Version in base suite: 17.0.12+7-2~deb12u1 Base version: openjdk-17_17.0.12+7-2~deb12u1 Target version: openjdk-17_17.0.13+11-2~deb12u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/o/openjdk-17/openjdk-17_17.0.12+7-2~deb12u1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/o/openjdk-17/openjdk-17_17.0.13+11-2~deb12u1.dsc /srv/release.debian.org/tmp/0ElK29bDIK/openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/resource/btn.png |binary /srv/release.debian.org/tmp/0ElK29bDIK/openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/resource/cmb.png |binary /srv/release.debian.org/tmp/0ElK29bDIK/openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/resource/dep.png |binary /srv/release.debian.org/tmp/0ElK29bDIK/openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/resource/dms.png |binary /srv/release.debian.org/tmp/0ElK29bDIK/openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/resource/hc.jpg |binary /srv/release.debian.org/tmp/0ElK29bDIK/openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/resource/if.png |binary /srv/release.debian.org/tmp/0ElK29bDIK/openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/resource/ifm.png |binary /srv/release.debian.org/tmp/0ElK29bDIK/openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/resource/list.png |binary /srv/release.debian.org/tmp/0ElK29bDIK/openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/resource/op.png |binary /srv/release.debian.org/tmp/0ElK29bDIK/openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/resource/rbtn.png |binary /srv/release.debian.org/tmp/0ElK29bDIK/openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/resource/tbl.png |binary /srv/release.debian.org/tmp/0ElK29bDIK/openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/resource/tbld.png |binary /srv/release.debian.org/tmp/0ElK29bDIK/openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/resource/tree.png |binary openjdk-17-17.0.13+11/.jcheck/conf | 3 openjdk-17-17.0.13+11/debian/JB-demo.overrides.in | 3 openjdk-17-17.0.13+11/debian/JB-doc.overrides.in | 5 openjdk-17-17.0.13+11/debian/JB-jdk-headless.overrides.in | 2 openjdk-17-17.0.13+11/debian/JB-jre-headless.overrides.in | 15 openjdk-17-17.0.13+11/debian/JB-jre-zero.overrides.in | 7 openjdk-17-17.0.13+11/debian/JB-jre.overrides.in | 3 openjdk-17-17.0.13+11/debian/JB-source.overrides.in | 2 openjdk-17-17.0.13+11/debian/apport-hook.py | 4 openjdk-17-17.0.13+11/debian/changelog | 42 openjdk-17-17.0.13+11/debian/control | 2 openjdk-17-17.0.13+11/debian/copyright-generator/strip-common-licenses.sh | 2 openjdk-17-17.0.13+11/debian/patches/build_gtest.patch | 31 openjdk-17-17.0.13+11/debian/patches/googletest-version.diff | 24 openjdk-17-17.0.13+11/debian/patches/jdk-8295111.patch | 92 openjdk-17-17.0.13+11/debian/patches/jdk-8325567.patch | 34 openjdk-17-17.0.13+11/debian/patches/jdk-8334895-proposed.patch | 2 openjdk-17-17.0.13+11/debian/patches/series | 4 openjdk-17-17.0.13+11/debian/rules | 23 openjdk-17-17.0.13+11/debian/source/lintian-overrides | 22 openjdk-17-17.0.13+11/debian/tests/jtreg-autopkgtest.in | 2 openjdk-17-17.0.13+11/debian/tests/jtreg-autopkgtest.sh | 2 openjdk-17-17.0.13+11/debian/tests/problems.csv | 25 openjdk-17-17.0.13+11/doc/building.html | 6 openjdk-17-17.0.13+11/doc/building.md | 13 openjdk-17-17.0.13+11/doc/testing.html | 2 openjdk-17-17.0.13+11/doc/testing.md | 10 openjdk-17-17.0.13+11/make/autoconf/configure.ac | 4 openjdk-17-17.0.13+11/make/autoconf/flags-cflags.m4 | 2 openjdk-17-17.0.13+11/make/autoconf/lib-tests.m4 | 24 openjdk-17-17.0.13+11/make/conf/github-actions.conf | 16 openjdk-17-17.0.13+11/make/conf/jib-profiles.js | 2 openjdk-17-17.0.13+11/make/conf/version-numbers.conf | 4 openjdk-17-17.0.13+11/make/data/cacerts/ssltlsrootecc2022 | 21 openjdk-17-17.0.13+11/make/data/cacerts/ssltlsrootrsa2022 | 39 openjdk-17-17.0.13+11/make/data/cldr/common/main/ff_Adlm.xml | 4 openjdk-17-17.0.13+11/make/data/currency/CurrencyData.properties | 10 openjdk-17-17.0.13+11/make/data/lsrdata/language-subtag-registry.txt | 12 openjdk-17-17.0.13+11/make/devkit/createJMHBundle.sh | 2 openjdk-17-17.0.13+11/make/hotspot/lib/CompileJvm.gmk | 4 openjdk-17-17.0.13+11/make/hotspot/lib/JvmFlags.gmk | 4 openjdk-17-17.0.13+11/make/modules/java.base/Launcher.gmk | 3 openjdk-17-17.0.13+11/make/modules/java.base/lib/CoreLibraries.gmk | 7 openjdk-17-17.0.13+11/make/modules/java.desktop/Java.gmk | 1 openjdk-17-17.0.13+11/make/modules/java.desktop/lib/Awt2dLibraries.gmk | 17 openjdk-17-17.0.13+11/src/hotspot/cpu/aarch64/assembler_aarch64.hpp | 2 openjdk-17-17.0.13+11/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp | 104 openjdk-17-17.0.13+11/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp | 9 openjdk-17-17.0.13+11/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp | 3 openjdk-17-17.0.13+11/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp | 11 openjdk-17-17.0.13+11/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp | 4 openjdk-17-17.0.13+11/src/hotspot/cpu/aarch64/vtableStubs_aarch64.cpp | 25 openjdk-17-17.0.13+11/src/hotspot/cpu/arm/arm.ad | 2 openjdk-17-17.0.13+11/src/hotspot/cpu/ppc/ppc.ad | 2 openjdk-17-17.0.13+11/src/hotspot/cpu/x86/assembler_x86.cpp | 19 openjdk-17-17.0.13+11/src/hotspot/cpu/x86/assembler_x86.hpp | 2 openjdk-17-17.0.13+11/src/hotspot/cpu/x86/macroAssembler_x86.cpp | 134 openjdk-17-17.0.13+11/src/hotspot/cpu/x86/macroAssembler_x86.hpp | 10 openjdk-17-17.0.13+11/src/hotspot/cpu/x86/macroAssembler_x86_aes.cpp | 18 openjdk-17-17.0.13+11/src/hotspot/cpu/x86/vtableStubs_x86_32.cpp | 43 openjdk-17-17.0.13+11/src/hotspot/cpu/x86/vtableStubs_x86_64.cpp | 35 openjdk-17-17.0.13+11/src/hotspot/os/aix/attachListener_aix.cpp | 8 openjdk-17-17.0.13+11/src/hotspot/os/aix/os_aix.cpp | 13 openjdk-17-17.0.13+11/src/hotspot/os/bsd/attachListener_bsd.cpp | 12 openjdk-17-17.0.13+11/src/hotspot/os/bsd/os_bsd.cpp | 54 openjdk-17-17.0.13+11/src/hotspot/os/bsd/os_perf_bsd.cpp | 62 openjdk-17-17.0.13+11/src/hotspot/os/linux/attachListener_linux.cpp | 28 openjdk-17-17.0.13+11/src/hotspot/os/linux/os_linux.cpp | 42 openjdk-17-17.0.13+11/src/hotspot/os/linux/os_perf_linux.cpp | 2 openjdk-17-17.0.13+11/src/hotspot/os/posix/os_posix.cpp | 13 openjdk-17-17.0.13+11/src/hotspot/os/posix/os_posix.hpp | 2 openjdk-17-17.0.13+11/src/hotspot/os/posix/perfMemory_posix.cpp | 58 openjdk-17-17.0.13+11/src/hotspot/os/windows/os_windows.cpp | 22 openjdk-17-17.0.13+11/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp | 4 openjdk-17-17.0.13+11/src/hotspot/share/adlc/adlc.hpp | 4 openjdk-17-17.0.13+11/src/hotspot/share/adlc/adlparse.cpp | 25 openjdk-17-17.0.13+11/src/hotspot/share/adlc/archDesc.cpp | 4 openjdk-17-17.0.13+11/src/hotspot/share/adlc/dfa.cpp | 6 openjdk-17-17.0.13+11/src/hotspot/share/adlc/formssel.cpp | 21 openjdk-17-17.0.13+11/src/hotspot/share/adlc/main.cpp | 2 openjdk-17-17.0.13+11/src/hotspot/share/adlc/output_c.cpp | 57 openjdk-17-17.0.13+11/src/hotspot/share/c1/c1_Runtime1.cpp | 4 openjdk-17-17.0.13+11/src/hotspot/share/cds/filemap.cpp | 5 openjdk-17-17.0.13+11/src/hotspot/share/classfile/classLoaderDataGraph.cpp | 2 openjdk-17-17.0.13+11/src/hotspot/share/classfile/classLoaderDataGraph.inline.hpp | 2 openjdk-17-17.0.13+11/src/hotspot/share/classfile/javaClasses.cpp | 17 openjdk-17-17.0.13+11/src/hotspot/share/classfile/symbolTable.cpp | 25 openjdk-17-17.0.13+11/src/hotspot/share/classfile/symbolTable.hpp | 21 openjdk-17-17.0.13+11/src/hotspot/share/classfile/verifier.cpp | 7 openjdk-17-17.0.13+11/src/hotspot/share/code/codeCache.cpp | 113 openjdk-17-17.0.13+11/src/hotspot/share/code/dependencies.cpp | 3 openjdk-17-17.0.13+11/src/hotspot/share/code/nmethod.cpp | 2 openjdk-17-17.0.13+11/src/hotspot/share/compiler/compilationPolicy.cpp | 2 openjdk-17-17.0.13+11/src/hotspot/share/compiler/compileBroker.cpp | 8 openjdk-17-17.0.13+11/src/hotspot/share/gc/g1/g1Allocator.cpp | 21 openjdk-17-17.0.13+11/src/hotspot/share/gc/g1/g1Allocator.hpp | 4 openjdk-17-17.0.13+11/src/hotspot/share/gc/g1/g1CollectedHeap.cpp | 3 openjdk-17-17.0.13+11/src/hotspot/share/gc/g1/g1EvacStats.cpp | 14 openjdk-17-17.0.13+11/src/hotspot/share/gc/g1/g1EvacStats.hpp | 8 openjdk-17-17.0.13+11/src/hotspot/share/gc/g1/g1EvacStats.inline.hpp | 8 openjdk-17-17.0.13+11/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp | 16 openjdk-17-17.0.13+11/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp | 4 openjdk-17-17.0.13+11/src/hotspot/share/gc/parallel/psScavenge.cpp | 5 openjdk-17-17.0.13+11/src/hotspot/share/gc/shared/gcHeapSummary.hpp | 25 openjdk-17-17.0.13+11/src/hotspot/share/gc/shared/memAllocator.cpp | 7 openjdk-17-17.0.13+11/src/hotspot/share/gc/shared/oopStorage.inline.hpp | 6 openjdk-17-17.0.13+11/src/hotspot/share/gc/shared/oopStorageParState.hpp | 6 openjdk-17-17.0.13+11/src/hotspot/share/gc/shared/oopStorageParState.inline.hpp | 5 openjdk-17-17.0.13+11/src/hotspot/share/gc/shared/threadLocalAllocBuffer.inline.hpp | 10 openjdk-17-17.0.13+11/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetNMethod.cpp | 10 openjdk-17-17.0.13+11/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp | 30 openjdk-17-17.0.13+11/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp | 28 openjdk-17-17.0.13+11/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp | 9 openjdk-17-17.0.13+11/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp | 7 openjdk-17-17.0.13+11/src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp | 51 openjdk-17-17.0.13+11/src/hotspot/share/gc/shenandoah/shenandoahNMethod.hpp | 4 openjdk-17-17.0.13+11/src/hotspot/share/gc/z/zSafeDelete.hpp | 5 openjdk-17-17.0.13+11/src/hotspot/share/gc/z/zSafeDelete.inline.hpp | 5 openjdk-17-17.0.13+11/src/hotspot/share/interpreter/bootstrapInfo.cpp | 8 openjdk-17-17.0.13+11/src/hotspot/share/interpreter/zero/bytecodeInterpreter.cpp | 8 openjdk-17-17.0.13+11/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp | 16 openjdk-17-17.0.13+11/src/hotspot/share/jfr/metadata/metadata.xml | 4 openjdk-17-17.0.13+11/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp | 3 openjdk-17-17.0.13+11/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp | 4 openjdk-17-17.0.13+11/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp | 2 openjdk-17-17.0.13+11/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdLoadBarrier.inline.hpp | 11 openjdk-17-17.0.13+11/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp | 10 openjdk-17-17.0.13+11/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp | 4 openjdk-17-17.0.13+11/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTraceRepository.cpp | 3 openjdk-17-17.0.13+11/src/hotspot/share/jfr/recorder/stringpool/jfrStringPool.cpp | 3 openjdk-17-17.0.13+11/src/hotspot/share/jfr/writers/jfrStreamWriterHost.inline.hpp | 14 openjdk-17-17.0.13+11/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp | 6 openjdk-17-17.0.13+11/src/hotspot/share/memory/iterator.inline.hpp | 20 openjdk-17-17.0.13+11/src/hotspot/share/memory/metaspace.cpp | 9 openjdk-17-17.0.13+11/src/hotspot/share/memory/metaspace/counters.hpp | 7 openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/conditional.hpp | 43 openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/decay.hpp | 41 openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/integralConstant.hpp | 59 openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/isArray.hpp | 35 openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/isConst.hpp | 33 openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/isFloatingPoint.hpp | 50 openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/isIntegral.hpp | 58 openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/isPointer.hpp | 40 openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/isSame.hpp | 38 openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/isSigned.hpp | 37 openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/isVolatile.hpp | 33 openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/removeCV.hpp | 50 openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/removeExtent.hpp | 35 openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/removePointer.hpp | 41 openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/removeReference.hpp | 38 openjdk-17-17.0.13+11/src/hotspot/share/oops/accessBackend.hpp | 77 openjdk-17-17.0.13+11/src/hotspot/share/oops/accessBackend.inline.hpp | 6 openjdk-17-17.0.13+11/src/hotspot/share/oops/accessDecorators.hpp | 5 openjdk-17-17.0.13+11/src/hotspot/share/oops/generateOopMap.cpp | 4 openjdk-17-17.0.13+11/src/hotspot/share/oops/instanceKlass.cpp | 35 openjdk-17-17.0.13+11/src/hotspot/share/oops/instanceKlass.hpp | 8 openjdk-17-17.0.13+11/src/hotspot/share/oops/markWord.hpp | 5 openjdk-17-17.0.13+11/src/hotspot/share/oops/oopHandle.hpp | 4 openjdk-17-17.0.13+11/src/hotspot/share/oops/oopsHierarchy.hpp | 55 openjdk-17-17.0.13+11/src/hotspot/share/opto/callGenerator.cpp | 28 openjdk-17-17.0.13+11/src/hotspot/share/opto/callnode.cpp | 2 openjdk-17-17.0.13+11/src/hotspot/share/opto/cfgnode.cpp | 2 openjdk-17-17.0.13+11/src/hotspot/share/opto/chaitin.cpp | 20 openjdk-17-17.0.13+11/src/hotspot/share/opto/chaitin.hpp | 2 openjdk-17-17.0.13+11/src/hotspot/share/opto/graphKit.cpp | 11 openjdk-17-17.0.13+11/src/hotspot/share/opto/graphKit.hpp | 2 openjdk-17-17.0.13+11/src/hotspot/share/opto/idealGraphPrinter.cpp | 38 openjdk-17-17.0.13+11/src/hotspot/share/opto/idealGraphPrinter.hpp | 3 openjdk-17-17.0.13+11/src/hotspot/share/opto/loopnode.cpp | 6 openjdk-17-17.0.13+11/src/hotspot/share/opto/output.cpp | 43 openjdk-17-17.0.13+11/src/hotspot/share/opto/regalloc.hpp | 2 openjdk-17-17.0.13+11/src/hotspot/share/opto/superword.cpp | 545 openjdk-17-17.0.13+11/src/hotspot/share/opto/superword.hpp | 91 openjdk-17-17.0.13+11/src/hotspot/share/opto/type.cpp | 64 openjdk-17-17.0.13+11/src/hotspot/share/opto/type.hpp | 1 openjdk-17-17.0.13+11/src/hotspot/share/prims/jvm.cpp | 4 openjdk-17-17.0.13+11/src/hotspot/share/prims/wbtestmethods/parserTests.cpp | 2 openjdk-17-17.0.13+11/src/hotspot/share/runtime/atomic.hpp | 47 openjdk-17-17.0.13+11/src/hotspot/share/runtime/deoptimization.cpp | 6 openjdk-17-17.0.13+11/src/hotspot/share/runtime/globals.hpp | 3 openjdk-17-17.0.13+11/src/hotspot/share/runtime/os.cpp | 28 openjdk-17-17.0.13+11/src/hotspot/share/runtime/os.hpp | 12 openjdk-17-17.0.13+11/src/hotspot/share/runtime/perfData.cpp | 7 openjdk-17-17.0.13+11/src/hotspot/share/runtime/thread.cpp | 13 openjdk-17-17.0.13+11/src/hotspot/share/runtime/thread.hpp | 6 openjdk-17-17.0.13+11/src/hotspot/share/services/classLoadingService.cpp | 19 openjdk-17-17.0.13+11/src/hotspot/share/services/classLoadingService.hpp | 4 openjdk-17-17.0.13+11/src/hotspot/share/services/heapDumperCompression.cpp | 11 openjdk-17-17.0.13+11/src/hotspot/share/services/mallocTracker.hpp | 5 openjdk-17-17.0.13+11/src/hotspot/share/services/memBaseline.cpp | 12 openjdk-17-17.0.13+11/src/hotspot/share/services/memBaseline.hpp | 10 openjdk-17-17.0.13+11/src/hotspot/share/services/memReporter.cpp | 1 openjdk-17-17.0.13+11/src/hotspot/share/services/memTracker.cpp | 23 openjdk-17-17.0.13+11/src/hotspot/share/services/memoryService.cpp | 18 openjdk-17-17.0.13+11/src/hotspot/share/services/memoryService.hpp | 4 openjdk-17-17.0.13+11/src/hotspot/share/services/nmtDCmd.cpp | 37 openjdk-17-17.0.13+11/src/hotspot/share/services/threadStackTracker.cpp | 10 openjdk-17-17.0.13+11/src/hotspot/share/utilities/concurrentHashTable.inline.hpp | 35 openjdk-17-17.0.13+11/src/hotspot/share/utilities/debug.cpp | 2 openjdk-17-17.0.13+11/src/hotspot/share/utilities/events.cpp | 6 openjdk-17-17.0.13+11/src/hotspot/share/utilities/events.hpp | 30 openjdk-17-17.0.13+11/src/hotspot/share/utilities/ostream.cpp | 4 openjdk-17-17.0.13+11/src/hotspot/share/utilities/population_count.hpp | 11 openjdk-17-17.0.13+11/src/hotspot/share/utilities/utf8.cpp | 5 openjdk-17-17.0.13+11/src/hotspot/share/utilities/vmassert_reinstall.hpp | 36 openjdk-17-17.0.13+11/src/hotspot/share/utilities/vmassert_uninstall.hpp | 45 openjdk-17-17.0.13+11/src/hotspot/share/utilities/waitBarrier_generic.cpp | 263 openjdk-17-17.0.13+11/src/hotspot/share/utilities/waitBarrier_generic.hpp | 74 openjdk-17-17.0.13+11/src/java.base/share/classes/java/lang/System.java | 15 openjdk-17-17.0.13+11/src/java.base/share/classes/java/lang/VersionProps.java.template | 3 openjdk-17-17.0.13+11/src/java.base/share/classes/java/net/doc-files/net-properties.html | 9 openjdk-17-17.0.13+11/src/java.base/share/classes/java/security/Provider.java | 547 openjdk-17-17.0.13+11/src/java.base/share/classes/java/text/MessageFormat.java | 60 openjdk-17-17.0.13+11/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java | 5 openjdk-17-17.0.13+11/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java | 5 openjdk-17-17.0.13+11/src/java.base/share/classes/java/util/regex/Grapheme.java | 8 openjdk-17-17.0.13+11/src/java.base/share/classes/javax/crypto/DecapsulateException.java | 66 openjdk-17-17.0.13+11/src/java.base/share/classes/javax/crypto/KEM.java | 751 openjdk-17-17.0.13+11/src/java.base/share/classes/javax/crypto/KEMSpi.java | 259 openjdk-17-17.0.13+11/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java | 4 openjdk-17-17.0.13+11/src/java.base/share/classes/jdk/internal/ref/CleanerImpl.java | 2 openjdk-17-17.0.13+11/src/java.base/share/classes/sun/launcher/LauncherHelper.java | 18 openjdk-17-17.0.13+11/src/java.base/share/classes/sun/net/www/MessageHeader.java | 55 openjdk-17-17.0.13+11/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java | 23 openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/provider/PolicyFile.java | 3 openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/CertificateMessage.java | 6 openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/ClientHello.java | 11 openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/DTLSInputRecord.java | 145 openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java | 5 openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/SSLSessionContextImpl.java | 64 openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java | 29 openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/ServerHandshakeContext.java | 3 openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/ServerNameExtension.java | 7 openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/SessionTicketExtension.java | 85 openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/TransportContext.java | 7 openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/util/Debug.java | 119 openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/validator/CADistrustPolicy.java | 18 openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/validator/EntrustTLSPolicy.java | 136 openjdk-17-17.0.13+11/src/java.base/share/classes/sun/util/resources/CurrencyNames.properties | 4 openjdk-17-17.0.13+11/src/java.base/share/conf/net.properties | 17 openjdk-17-17.0.13+11/src/java.base/share/conf/security/java.policy | 2 openjdk-17-17.0.13+11/src/java.base/share/conf/security/java.security | 8 openjdk-17-17.0.13+11/src/java.base/share/native/libjli/java.c | 22 openjdk-17-17.0.13+11/src/java.base/share/native/libzip/zip_util.c | 2 openjdk-17-17.0.13+11/src/java.base/unix/classes/sun/security/provider/NativePRNG.java | 20 openjdk-17-17.0.13+11/src/java.base/unix/native/jspawnhelper/jspawnhelper.c | 25 openjdk-17-17.0.13+11/src/java.base/unix/native/libjava/ProcessImpl_md.c | 14 openjdk-17-17.0.13+11/src/java.base/unix/native/libjava/TimeZone_md.c | 6 openjdk-17-17.0.13+11/src/java.base/unix/native/libjli/java_md.c | 4 openjdk-17-17.0.13+11/src/java.base/unix/native/libnet/NetworkInterface.c | 4 openjdk-17-17.0.13+11/src/java.base/unix/native/libnet/net_util_md.c | 4 openjdk-17-17.0.13+11/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c | 30 openjdk-17-17.0.13+11/src/java.base/windows/native/libjava/Console_md.c | 6 openjdk-17-17.0.13+11/src/java.base/windows/native/libjava/TimeZone_md.c | 18 openjdk-17-17.0.13+11/src/java.base/windows/native/libjava/java_props_md.c | 13 openjdk-17-17.0.13+11/src/java.base/windows/native/libnet/net_util_md.c | 4 openjdk-17-17.0.13+11/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.c | 14 openjdk-17-17.0.13+11/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.h | 4 openjdk-17-17.0.13+11/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.c | 8 openjdk-17-17.0.13+11/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.c | 8 openjdk-17-17.0.13+11/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_Ports.c | 8 openjdk-17-17.0.13+11/src/java.desktop/macosx/classes/sun/font/CStrike.java | 2 openjdk-17-17.0.13+11/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java | 77 openjdk-17-17.0.13+11/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java | 4 openjdk-17-17.0.13+11/src/java.desktop/macosx/native/libawt_lwawt/awt/CPrinterJob.m | 4 openjdk-17-17.0.13+11/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineAccessibility.h | 11 openjdk-17-17.0.13+11/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineAccessibility.m | 88 openjdk-17-17.0.13+11/src/java.desktop/macosx/native/libawt_lwawt/font/AWTStrike.m | 2 openjdk-17-17.0.13+11/src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m | 18 openjdk-17-17.0.13+11/src/java.desktop/macosx/native/libjsound/PLATFORM_API_MacOSX_Ports.cpp | 2 openjdk-17-17.0.13+11/src/java.desktop/share/classes/java/awt/Robot.java | 87 openjdk-17-17.0.13+11/src/java.desktop/share/classes/javax/swing/JEditorPane.java | 54 openjdk-17-17.0.13+11/src/java.desktop/share/classes/javax/swing/JPopupMenu.java | 27 openjdk-17-17.0.13+11/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java | 190 openjdk-17-17.0.13+11/src/java.desktop/share/classes/javax/swing/text/html/CSS.java | 18 openjdk-17-17.0.13+11/src/java.desktop/share/classes/javax/swing/text/html/HTMLDocument.java | 119 openjdk-17-17.0.13+11/src/java.desktop/share/classes/javax/swing/text/html/MuxingAttributeSet.java | 40 openjdk-17-17.0.13+11/src/java.desktop/share/classes/javax/swing/text/html/StyleSheet.java | 84 openjdk-17-17.0.13+11/src/java.desktop/share/classes/sun/awt/SunToolkit.java | 18 openjdk-17-17.0.13+11/src/java.desktop/share/classes/sun/font/FileFontStrike.java | 16 openjdk-17-17.0.13+11/src/java.desktop/share/legal/giflib.md | 26 openjdk-17-17.0.13+11/src/java.desktop/share/legal/libpng.md | 43 openjdk-17-17.0.13+11/src/java.desktop/share/native/common/awt/debug/debug_mem.c | 2 openjdk-17-17.0.13+11/src/java.desktop/share/native/common/awt/debug/debug_trace.c | 2 openjdk-17-17.0.13+11/src/java.desktop/share/native/common/java2d/opengl/OGLBufImgOps.c | 16 openjdk-17-17.0.13+11/src/java.desktop/share/native/common/java2d/opengl/OGLPaints.c | 8 openjdk-17-17.0.13+11/src/java.desktop/share/native/libfontmanager/freetypeScaler.c | 14 openjdk-17-17.0.13+11/src/java.desktop/share/native/libharfbuzz/hb-meta.hh | 2 openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/UNIXToolkit.java | 135 openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/X11/XBaseWindow.java | 14 openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/X11/XDragSourceContextPeer.java | 41 openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/X11/XMenuWindow.java | 35 openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/X11/XPopupMenuPeer.java | 24 openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java | 56 openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/X11/XWM.java | 4 openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/X11GraphicsEnvironment.java | 4 openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/screencast/ScreencastHelper.java | 233 openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/screencast/TokenItem.java | 154 openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/screencast/TokenStorage.java | 461 openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/java2d/opengl/GLXGraphicsConfig.java | 4 openjdk-17-17.0.13+11/src/java.desktop/unix/legal/pipewire.md | 41 openjdk-17-17.0.13+11/src/java.desktop/unix/native/common/awt/awt.h | 4 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libawt_xawt/awt/fp_pipewire.h | 91 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.h | 9 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c | 105 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.h | 204 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libawt_xawt/awt/gtk_interface.h | 290 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.c | 1038 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.h | 104 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libawt_xawt/awt/screencast_portal.c | 906 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libawt_xawt/awt/screencast_portal.h | 76 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/pipewire/context.h | 175 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/pipewire/core.h | 612 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/pipewire/keys.h | 343 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/pipewire/loop.h | 70 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/pipewire/port.h | 159 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/pipewire/properties.h | 179 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/pipewire/protocol.h | 142 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/pipewire/proxy.h | 201 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/pipewire/stream.h | 509 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/pipewire/utils.h | 99 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/buffer/buffer.h | 112 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/buffer/meta.h | 172 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/buffer/type-info.h | 74 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/control/control.h | 42 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/control/type-info.h | 41 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/debug/types.h | 107 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/monitor/event.h | 43 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/monitor/type-info.h | 47 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/node/command.h | 53 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/node/event.h | 44 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/node/io.h | 290 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/node/type-info.h | 87 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/aac-types.h | 38 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/aac.h | 51 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/amr-types.h | 32 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/amr.h | 36 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/iec958-types.h | 39 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/iec958.h | 49 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/mp3-types.h | 34 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/mp3.h | 37 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/raw-types.h | 258 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/raw.h | 309 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/type-info.h | 15 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/wma-types.h | 37 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/wma.h | 47 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/bluetooth/audio.h | 54 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/bluetooth/type-info.h | 58 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/buffers-types.h | 70 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/buffers.h | 52 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/format-types.h | 172 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/format-utils.h | 38 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/format.h | 157 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/latency-types.h | 55 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/latency.h | 69 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/param-types.h | 95 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/param.h | 87 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/port-config-types.h | 53 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/port-config.h | 46 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/profile-types.h | 45 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/profile.h | 52 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/profiler-types.h | 40 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/profiler.h | 77 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/props-types.h | 104 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/props.h | 120 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/route-types.h | 51 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/route.h | 49 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/type-info.h | 18 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/video/chroma.h | 44 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/video/color.h | 105 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/video/dsp-utils.h | 63 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/video/dsp.h | 35 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/video/encoded.h | 11 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/video/format-utils.h | 64 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/video/format.h | 41 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/video/h264-utils.h | 70 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/video/h264.h | 48 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/video/mjpg-utils.h | 62 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/video/mjpg.h | 33 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/video/multiview.h | 114 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/video/raw-types.h | 144 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/video/raw-utils.h | 115 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/video/raw.h | 201 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/param/video/type-info.h | 10 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/pod/builder.h | 681 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/pod/command.h | 49 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/pod/event.h | 48 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/pod/iter.h | 455 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/pod/parser.h | 574 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/pod/pod.h | 226 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/pod/vararg.h | 93 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/support/loop.h | 318 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/support/system.h | 145 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/utils/defs.h | 382 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/utils/dict.h | 100 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/utils/enum-types.h | 45 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/utils/hook.h | 452 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/utils/list.h | 146 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/utils/string.h | 394 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/utils/type-info.h | 98 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libpipewire/include/spa/utils/type.h | 133 openjdk-17-17.0.13+11/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c | 2 openjdk-17-17.0.13+11/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java | 38 openjdk-17-17.0.13+11/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java | 4 openjdk-17-17.0.13+11/src/java.desktop/windows/native/libawt/java2d/d3d/D3DShaderGen.c | 24 openjdk-17-17.0.13+11/src/java.desktop/windows/native/libawt/windows/ShellFolder2.cpp | 28 openjdk-17-17.0.13+11/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp | 2 openjdk-17-17.0.13+11/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp | 2 openjdk-17-17.0.13+11/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiOut.c | 2 openjdk-17-17.0.13+11/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c | 12 openjdk-17-17.0.13+11/src/java.management/share/native/libmanagement/VMManagementImpl.c | 2 openjdk-17-17.0.13+11/src/java.management/share/native/libmanagement/management.c | 2 openjdk-17-17.0.13+11/src/java.naming/share/classes/com/sun/jndi/ldap/Obj.java | 6 openjdk-17-17.0.13+11/src/java.naming/share/classes/com/sun/jndi/ldap/VersionHelper.java | 17 openjdk-17-17.0.13+11/src/java.naming/share/classes/module-info.java | 15 openjdk-17-17.0.13+11/src/java.net.http/share/classes/jdk/internal/net/http/Exchange.java | 106 openjdk-17-17.0.13+11/src/java.net.http/share/classes/jdk/internal/net/http/ExchangeImpl.java | 10 openjdk-17-17.0.13+11/src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java | 9 openjdk-17-17.0.13+11/src/java.net.http/share/classes/jdk/internal/net/http/Http1HeaderParser.java | 49 openjdk-17-17.0.13+11/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java | 79 openjdk-17-17.0.13+11/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java | 422 openjdk-17-17.0.13+11/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java | 5 openjdk-17-17.0.13+11/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java | 4 openjdk-17-17.0.13+11/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java | 12 openjdk-17-17.0.13+11/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java | 273 openjdk-17-17.0.13+11/src/java.net.http/share/classes/jdk/internal/net/http/common/HeaderDecoder.java | 52 openjdk-17-17.0.13+11/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.java | 54 openjdk-17-17.0.13+11/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java | 38 openjdk-17-17.0.13+11/src/java.net.http/share/classes/jdk/internal/net/http/common/ValidatingHeadersConsumer.java | 89 openjdk-17-17.0.13+11/src/java.net.http/share/classes/jdk/internal/net/http/hpack/Decoder.java | 80 openjdk-17-17.0.13+11/src/java.net.http/share/classes/jdk/internal/net/http/hpack/DecodingCallback.java | 14 openjdk-17-17.0.13+11/src/java.net.http/share/classes/jdk/internal/net/http/hpack/Encoder.java | 14 openjdk-17-17.0.13+11/src/java.security.jgss/share/classes/javax/security/auth/kerberos/EncryptionKey.java | 4 openjdk-17-17.0.13+11/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KerberosCredMessage.java | 6 openjdk-17-17.0.13+11/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KerberosKey.java | 8 openjdk-17-17.0.13+11/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KeyImpl.java | 16 openjdk-17-17.0.13+11/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Context.java | 22 openjdk-17-17.0.13+11/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Util.java | 15 openjdk-17-17.0.13+11/src/java.security.jgss/share/classes/sun/security/krb5/EncryptionKey.java | 8 openjdk-17-17.0.13+11/src/java.security.jgss/share/classes/sun/security/krb5/internal/Krb5.java | 3 openjdk-17-17.0.13+11/src/java.security.jgss/windows/classes/sun/security/krb5/internal/tools/Kinit.java | 4 openjdk-17-17.0.13+11/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dv/SchemaDVFactory.java | 6 openjdk-17-17.0.13+11/src/jdk.accessibility/windows/native/common/AccessBridgeDebug.cpp | 14 openjdk-17-17.0.13+11/src/jdk.accessibility/windows/native/jaccessinspector/jaccessinspector.cpp | 6 openjdk-17-17.0.13+11/src/jdk.accessibility/windows/native/jaccesswalker/jaccesswalker.cpp | 4 openjdk-17-17.0.13+11/src/jdk.accessibility/windows/native/libwindowsaccessbridge/AccessBridgeEventHandler.cpp | 18 openjdk-17-17.0.13+11/src/jdk.accessibility/windows/native/libwindowsaccessbridge/AccessBridgeJavaVMInstance.cpp | 28 openjdk-17-17.0.13+11/src/jdk.accessibility/windows/native/libwindowsaccessbridge/WinAccessBridge.cpp | 4 openjdk-17-17.0.13+11/src/jdk.accessibility/windows/native/toolscommon/AccessInfo.cpp | 10 openjdk-17-17.0.13+11/src/jdk.attach/windows/native/libattach/VirtualMachineImpl.c | 6 openjdk-17-17.0.13+11/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java | 11 openjdk-17-17.0.13+11/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11AEADCipher.java | 25 openjdk-17-17.0.13+11/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PBE_PARAMS.java | 5 openjdk-17-17.0.13+11/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11.java | 36 openjdk-17-17.0.13+11/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c | 23 openjdk-17-17.0.13+11/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_crypt.c | 129 openjdk-17-17.0.13+11/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c | 83 openjdk-17-17.0.13+11/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp | 10 openjdk-17-17.0.13+11/src/jdk.hotspot.agent/linux/native/libsaproc/ps_proc.c | 6 openjdk-17-17.0.13+11/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/CodeBlob.java | 1 openjdk-17-17.0.13+11/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/riscv/RISCV64ThreadContext.java | 172 openjdk-17-17.0.13+11/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/riscv64/RISCV64ThreadContext.java | 172 openjdk-17-17.0.13+11/src/jdk.hotspot.agent/test/libproc/Makefile | 4 openjdk-17-17.0.13+11/src/jdk.hotspot.agent/windows/native/libsaproc/sawindbg.cpp | 5 openjdk-17-17.0.13+11/src/jdk.httpserver/share/classes/sun/net/httpserver/ChunkedOutputStream.java | 8 openjdk-17-17.0.13+11/src/jdk.httpserver/share/classes/sun/net/httpserver/ExchangeImpl.java | 7 openjdk-17-17.0.13+11/src/jdk.httpserver/share/classes/sun/net/httpserver/FixedLengthOutputStream.java | 17 openjdk-17-17.0.13+11/src/jdk.httpserver/share/classes/sun/net/httpserver/Request.java | 35 openjdk-17-17.0.13+11/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerConfig.java | 18 openjdk-17-17.0.13+11/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java | 100 openjdk-17-17.0.13+11/src/jdk.httpserver/share/classes/sun/net/httpserver/UndefLengthOutputStream.java | 8 openjdk-17-17.0.13+11/src/jdk.jartool/share/man/jar.1 | 10 openjdk-17-17.0.13+11/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDoclet.java | 2 openjdk-17-17.0.13+11/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java | 55 openjdk-17-17.0.13+11/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/RawHtml.java | 10 openjdk-17-17.0.13+11/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/script-dir/jquery-3.6.1.js |10909 ---------- openjdk-17-17.0.13+11/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/script-dir/jquery-3.6.1.min.js | 2 openjdk-17-17.0.13+11/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/script-dir/jquery-3.7.1.js |10716 +++++++++ openjdk-17-17.0.13+11/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/script-dir/jquery-3.7.1.min.js | 2 openjdk-17-17.0.13+11/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DocPaths.java | 2 openjdk-17-17.0.13+11/src/jdk.javadoc/share/legal/jquery.md | 50 openjdk-17-17.0.13+11/src/jdk.jdi/share/native/libdt_shmem/SharedMemoryTransport.c | 6 openjdk-17-17.0.13+11/src/jdk.jdi/share/native/libdt_shmem/shmemBase.c | 24 openjdk-17-17.0.13+11/src/jdk.jdwp.agent/share/native/libdt_socket/socketTransport.c | 12 openjdk-17-17.0.13+11/src/jdk.jdwp.agent/unix/native/libjdwp/exec_md.c | 124 openjdk-17-17.0.13+11/src/jdk.jdwp.agent/windows/native/libdt_socket/socket_md.c | 2 openjdk-17-17.0.13+11/src/jdk.jdwp.agent/windows/native/libjdwp/linker_md.c | 4 openjdk-17-17.0.13+11/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxDebBundler.java | 64 openjdk-17-17.0.13+11/src/jdk.management/share/native/libmanagement_ext/GcInfoBuilder.c | 38 openjdk-17-17.0.13+11/src/jdk.management/share/native/libmanagement_ext/management_ext.c | 2 openjdk-17-17.0.13+11/src/jdk.security.auth/share/classes/com/sun/security/auth/module/Krb5LoginModule.java | 10 openjdk-17-17.0.13+11/src/utils/IdealGraphVisualizer/Bytecodes/pom.xml | 6 openjdk-17-17.0.13+11/src/utils/IdealGraphVisualizer/ControlFlow/pom.xml | 6 openjdk-17-17.0.13+11/src/utils/IdealGraphVisualizer/Coordinator/pom.xml | 6 openjdk-17-17.0.13+11/src/utils/IdealGraphVisualizer/Data/pom.xml | 6 openjdk-17-17.0.13+11/src/utils/IdealGraphVisualizer/Difference/pom.xml | 6 openjdk-17-17.0.13+11/src/utils/IdealGraphVisualizer/Filter/pom.xml | 8 openjdk-17-17.0.13+11/src/utils/IdealGraphVisualizer/FilterWindow/pom.xml | 6 openjdk-17-17.0.13+11/src/utils/IdealGraphVisualizer/Graal/pom.xml | 6 openjdk-17-17.0.13+11/src/utils/IdealGraphVisualizer/Graph/pom.xml | 6 openjdk-17-17.0.13+11/src/utils/IdealGraphVisualizer/HierarchicalLayout/pom.xml | 6 openjdk-17-17.0.13+11/src/utils/IdealGraphVisualizer/Layout/pom.xml | 6 openjdk-17-17.0.13+11/src/utils/IdealGraphVisualizer/NetworkConnection/pom.xml | 6 openjdk-17-17.0.13+11/src/utils/IdealGraphVisualizer/README.md | 2 openjdk-17-17.0.13+11/src/utils/IdealGraphVisualizer/SelectionCoordinator/pom.xml | 6 openjdk-17-17.0.13+11/src/utils/IdealGraphVisualizer/ServerCompiler/pom.xml | 4 openjdk-17-17.0.13+11/src/utils/IdealGraphVisualizer/Settings/pom.xml | 6 openjdk-17-17.0.13+11/src/utils/IdealGraphVisualizer/Util/pom.xml | 6 openjdk-17-17.0.13+11/src/utils/IdealGraphVisualizer/View/pom.xml | 6 openjdk-17-17.0.13+11/src/utils/IdealGraphVisualizer/application/pom.xml | 5 openjdk-17-17.0.13+11/src/utils/IdealGraphVisualizer/application/src/main/resources/idealgraphvisualizer.conf | 24 openjdk-17-17.0.13+11/src/utils/IdealGraphVisualizer/branding/pom.xml | 6 openjdk-17-17.0.13+11/src/utils/IdealGraphVisualizer/pom.xml | 24 openjdk-17-17.0.13+11/src/utils/LogCompilation/Makefile | 6 openjdk-17-17.0.13+11/test/failure_handler/src/share/classes/jdk/test/failurehandler/action/ActionHelper.java | 2 openjdk-17-17.0.13+11/test/hotspot/gtest/classfile/test_symbolTable.cpp | 67 openjdk-17-17.0.13+11/test/hotspot/gtest/gc/shared/test_memset_with_concurrent_readers.cpp | 7 openjdk-17-17.0.13+11/test/hotspot/gtest/gc/shared/test_oopStorage.cpp | 13 openjdk-17-17.0.13+11/test/hotspot/gtest/gc/shenandoah/test_shenandoahNumberSeq.cpp | 6 openjdk-17-17.0.13+11/test/hotspot/gtest/gtestMain.cpp | 4 openjdk-17-17.0.13+11/test/hotspot/gtest/jfr/test_networkUtilization.cpp | 8 openjdk-17-17.0.13+11/test/hotspot/gtest/logging/test_logDecorators.cpp | 3 openjdk-17-17.0.13+11/test/hotspot/gtest/logging/test_logMessageTest.cpp | 5 openjdk-17-17.0.13+11/test/hotspot/gtest/metaprogramming/test_conditional.cpp | 46 openjdk-17-17.0.13+11/test/hotspot/gtest/metaprogramming/test_decay.cpp | 47 openjdk-17-17.0.13+11/test/hotspot/gtest/metaprogramming/test_isArray.cpp | 71 openjdk-17-17.0.13+11/test/hotspot/gtest/metaprogramming/test_isConst.cpp | 47 openjdk-17-17.0.13+11/test/hotspot/gtest/metaprogramming/test_isFloatingPoint.cpp | 45 openjdk-17-17.0.13+11/test/hotspot/gtest/metaprogramming/test_isIntegral.cpp | 62 openjdk-17-17.0.13+11/test/hotspot/gtest/metaprogramming/test_isPointer.cpp | 53 openjdk-17-17.0.13+11/test/hotspot/gtest/metaprogramming/test_isSame.cpp | 51 openjdk-17-17.0.13+11/test/hotspot/gtest/metaprogramming/test_isSigned.cpp | 49 openjdk-17-17.0.13+11/test/hotspot/gtest/metaprogramming/test_isVolatile.cpp | 46 openjdk-17-17.0.13+11/test/hotspot/gtest/metaprogramming/test_primitiveConversions.cpp | 1 openjdk-17-17.0.13+11/test/hotspot/gtest/metaprogramming/test_removeCV.cpp | 75 openjdk-17-17.0.13+11/test/hotspot/gtest/metaprogramming/test_removeExtent.cpp | 65 openjdk-17-17.0.13+11/test/hotspot/gtest/metaprogramming/test_removePointer.cpp | 45 openjdk-17-17.0.13+11/test/hotspot/gtest/metaprogramming/test_removeReference.cpp | 45 openjdk-17-17.0.13+11/test/hotspot/gtest/unittest.hpp | 14 openjdk-17-17.0.13+11/test/hotspot/gtest/utilities/test_count_leading_zeros.cpp | 10 openjdk-17-17.0.13+11/test/hotspot/jtreg/ProblemList-zgc.txt | 2 openjdk-17-17.0.13+11/test/hotspot/jtreg/ProblemList.txt | 3 openjdk-17-17.0.13+11/test/hotspot/jtreg/TEST.ROOT | 4 openjdk-17-17.0.13+11/test/hotspot/jtreg/TEST.groups | 5 openjdk-17-17.0.13+11/test/hotspot/jtreg/compiler/c2/Test7190310.java | 9 openjdk-17-17.0.13+11/test/hotspot/jtreg/compiler/calls/NativeCalls.java | 87 openjdk-17-17.0.13+11/test/hotspot/jtreg/compiler/calls/libNativeCalls.c | 27 openjdk-17-17.0.13+11/test/hotspot/jtreg/compiler/codecache/CheckCodeCacheInfo.java | 77 openjdk-17-17.0.13+11/test/hotspot/jtreg/compiler/codecache/CheckLargePages.java | 2 openjdk-17-17.0.13+11/test/hotspot/jtreg/compiler/codecache/CodeCacheFullCountTest.java | 142 openjdk-17-17.0.13+11/test/hotspot/jtreg/compiler/codecache/cli/TestSegmentedCodeCacheOption.java | 1 openjdk-17-17.0.13+11/test/hotspot/jtreg/compiler/codecache/cli/codeheapsize/TestCodeHeapSizeOptions.java | 1 openjdk-17-17.0.13+11/test/hotspot/jtreg/compiler/codecache/cli/printcodecache/TestPrintCodeCacheOption.java | 1 openjdk-17-17.0.13+11/test/hotspot/jtreg/compiler/lib/ir_framework/README.md | 32 openjdk-17-17.0.13+11/test/hotspot/jtreg/compiler/runtime/Test8168712.java | 15 openjdk-17-17.0.13+11/test/hotspot/jtreg/compiler/runtime/unloaded/TestMHUnloaded.java | 57 openjdk-17-17.0.13+11/test/hotspot/jtreg/compiler/runtime/unloaded/TestMHUnloadedHelper.java | 103 openjdk-17-17.0.13+11/test/hotspot/jtreg/containers/docker/TestJcmd.java | 115 openjdk-17-17.0.13+11/test/hotspot/jtreg/gc/arguments/TestDisableDefaultGC.java | 16 openjdk-17-17.0.13+11/test/hotspot/jtreg/gc/arguments/TestG1HeapSizeFlags.java | 5 openjdk-17-17.0.13+11/test/hotspot/jtreg/gc/arguments/TestG1PercentageOptions.java | 10 openjdk-17-17.0.13+11/test/hotspot/jtreg/gc/arguments/TestHeapFreeRatio.java | 5 openjdk-17-17.0.13+11/test/hotspot/jtreg/gc/arguments/TestMaxHeapSizeTools.java | 72 openjdk-17-17.0.13+11/test/hotspot/jtreg/gc/arguments/TestMaxNewSize.java | 40 openjdk-17-17.0.13+11/test/hotspot/jtreg/gc/arguments/TestParallelHeapSizeFlags.java | 5 openjdk-17-17.0.13+11/test/hotspot/jtreg/gc/arguments/TestSerialHeapSizeFlags.java | 4 openjdk-17-17.0.13+11/test/hotspot/jtreg/gc/g1/plab/lib/LogParser.java | 19 openjdk-17-17.0.13+11/test/hotspot/jtreg/gc/stress/TestStressG1Humongous.java | 49 openjdk-17-17.0.13+11/test/hotspot/jtreg/gc/z/TestGarbageCollectorMXBean.java | 1 openjdk-17-17.0.13+11/test/hotspot/jtreg/runtime/NMT/JcmdBaselineDetail.java | 2 openjdk-17-17.0.13+11/test/hotspot/jtreg/runtime/NMT/JcmdDetailDiff.java | 2 openjdk-17-17.0.13+11/test/hotspot/jtreg/runtime/NMT/JcmdSummaryDiff.java | 2 openjdk-17-17.0.13+11/test/hotspot/jtreg/runtime/NMT/MallocSiteTypeChange.java | 2 openjdk-17-17.0.13+11/test/hotspot/jtreg/runtime/NMT/SummaryDiffThreadCount.java | 66 openjdk-17-17.0.13+11/test/hotspot/jtreg/runtime/Thread/ThreadCountLimit.java | 59 openjdk-17-17.0.13+11/test/hotspot/jtreg/runtime/cds/TestCDSVMCrash.java | 72 openjdk-17-17.0.13+11/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/RelativePath.java | 12 openjdk-17-17.0.13+11/test/hotspot/jtreg/runtime/cds/serviceability/ReplaceCriticalClassesForSubgraphs.java | 1 openjdk-17-17.0.13+11/test/hotspot/jtreg/runtime/logging/ClassLoadUnloadTest.java | 59 openjdk-17-17.0.13+11/test/hotspot/jtreg/serviceability/jvmti/AddModuleExportsAndOpens/libAddModuleExportsAndOpensTest.c | 8 openjdk-17-17.0.13+11/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/RedefinePreviousVersions.java | 10 openjdk-17-17.0.13+11/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/RedefineSharedClassJFR.java | 111 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_anonclassloader_inMemoryCompilation_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_anonclassloader_inMemoryCompilation_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_anonclassloader_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_anonclassloader_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_inMemoryCompilation_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_inMemoryCompilation_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_inMemoryCompilation_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level1_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_inMemoryCompilation_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_inMemoryCompilation_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_inMemoryCompilation_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level2_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_inMemoryCompilation_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_inMemoryCompilation_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_inMemoryCompilation_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level3_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_inMemoryCompilation_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_inMemoryCompilation_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_inMemoryCompilation_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_compilation_level4_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_inMemoryCompilation_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_inMemoryCompilation_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_inMemoryCompilation_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_humongous_class_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_inMemoryCompilation_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_inMemoryCompilation_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_inMemoryCompilation_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_jni_classloading_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_inMemoryCompilation_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_inMemoryCompilation_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_inMemoryCompilation_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_global_ref_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_inMemoryCompilation_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_inMemoryCompilation_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_inMemoryCompilation_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_jni_local_ref_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_inMemoryCompilation_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_inMemoryCompilation_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_inMemoryCompilation_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_rootClass_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_inMemoryCompilation_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_inMemoryCompilation_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_inMemoryCompilation_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_stackLocal_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_inMemoryCompilation_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_inMemoryCompilation_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_inMemoryCompilation_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_staticField_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_inMemoryCompilation_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_inMemoryCompilation_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_inMemoryCompilation_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_strongRef_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_inMemoryCompilation_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_inMemoryCompilation_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_inMemoryCompilation_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_keepRef_threadItself_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_inMemoryCompilation_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_inMemoryCompilation_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_inMemoryCompilation_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_phantom_ref_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_inMemoryCompilation_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_inMemoryCompilation_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_inMemoryCompilation_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_prot_domains_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_inMemoryCompilation_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_inMemoryCompilation_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_inMemoryCompilation_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_redefinition_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_inMemoryCompilation_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_inMemoryCompilation_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_inMemoryCompilation_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_reflection_classloading_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_inMemoryCompilation_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_inMemoryCompilation_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_inMemoryCompilation_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_keep_cl/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_keep_class/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/tests/unloading_weak_ref_keep_obj/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/gctests/LargeObjects/large001/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/gctests/LargeObjects/large002/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/gctests/LargeObjects/large003/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/gctests/LargeObjects/large004/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/gc/gctests/LargeObjects/large005/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/metaspace/gc/watermark_0_1/TestDescription.java | 1 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/metaspace/gc/watermark_10_20/TestDescription.java | 1 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/metaspace/gc/watermark_70_80/TestDescription.java | 1 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/metaspace/gc/watermark_99_100/TestDescription.java | 1 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/jvmti/CreateRawMonitor/crrawmon001/crrawmon001.cpp | 2 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/jvmti/DestroyRawMonitor/drrawmon001/drrawmon001.cpp | 2 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetClassFields/getclfld007.java | 82 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetClassFields/getclfld007/TestDescription.java | 9 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetClassFields/getclfld007/getclfld007.cpp | 145 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RawMonitorEnter/rawmonenter001/rawmonenter001.cpp | 4 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RawMonitorExit/rawmonexit001/rawmonexit001.cpp | 4 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RawMonitorNotify/rawmnntfy001/rawmnntfy001.cpp | 4 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RawMonitorNotifyAll/rawmnntfyall001/rawmnntfyall001.cpp | 4 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RawMonitorWait/rawmnwait001/rawmnwait001.cpp | 4 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ThreadEnd/threadend001/threadend001.cpp | 2 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ThreadStart/threadstart001/threadstart001.cpp | 2 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/bcinstr/BI04/bi04t002/bi04t002.cpp | 4 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/hotswap/HS201/hs201t001/hs201t001.cpp | 2 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/hotswap/HS201/hs201t002/hs201t002.cpp | 2 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/GetAllStackTraces/getallstktr001/getallstktr001.cpp | 2 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/MethodBind/JvmtiTest/JvmtiTest.cpp | 2 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/StackTrace/JvmtiTest/JvmtiTest.cpp | 2 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/functions/nosuspendStackTrace/JvmtiTest/JvmtiTest.cpp | 2 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/functions/rawmonitor/rawmonitor.cpp | 2 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load001/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load002/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load003/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load004/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load005/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load006/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load007/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load008/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load009/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load010/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load011/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load012/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload001/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload002/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload003/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload004/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload005/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload006/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload007/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload008/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload009/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload010/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload011/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/unload012/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/cmon001/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/cmon002/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/cmon003/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace001/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace002/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace003/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace004/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace005/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace006/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace007/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace008/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace009/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace010/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace011/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace012/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace013/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace014/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace015/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace016/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace017/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace018/TEST.properties | 23 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/share/JVMTIagent.cpp | 2 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/share/Log.java | 16 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/share/NativeUtils.java | 31 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/share/gc/gp/GarbageUtils.java | 16 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/aod/jvmti_aod.cpp | 2 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/jvmti_tools.cpp | 2 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/share/native/native_utils.cpp | 43 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/share/native/nsk_tools.cpp | 2 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/share/test/StressOptions.java | 4 openjdk-17-17.0.13+11/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/TEST.properties | 24 openjdk-17-17.0.13+11/test/jdk/ProblemList-Xcomp.txt | 1 openjdk-17-17.0.13+11/test/jdk/ProblemList.txt | 48 openjdk-17-17.0.13+11/test/jdk/TEST.ROOT | 41 openjdk-17-17.0.13+11/test/jdk/TEST.groups | 6 openjdk-17-17.0.13+11/test/jdk/com/sun/jndi/ldap/objects/RemoteLocationAttributeTest.java | 124 openjdk-17-17.0.13+11/test/jdk/com/sun/jndi/ldap/objects/RemoteLocationAttributeTest.ldap | 61 openjdk-17-17.0.13+11/test/jdk/com/sun/net/httpserver/bugs/ExceptionKeepAlive.java | 131 openjdk-17-17.0.13+11/test/jdk/com/sun/net/httpserver/bugs/HeadKeepAlive.java | 128 openjdk-17-17.0.13+11/test/jdk/com/sun/net/httpserver/bugs/ZeroLengthOutputStream.java | 114 openjdk-17-17.0.13+11/test/jdk/java/awt/Choice/ChoiceKeyEventReaction/ChoiceKeyEventReaction.java | 4 openjdk-17-17.0.13+11/test/jdk/java/awt/Choice/NonFocusablePopupMenuTest.java | 96 openjdk-17-17.0.13+11/test/jdk/java/awt/Choice/NonFocusablePopupMenuTest/NonFocusablePopupMenuTest.html | 43 openjdk-17-17.0.13+11/test/jdk/java/awt/Choice/NonFocusablePopupMenuTest/NonFocusablePopupMenuTest.java | 214 openjdk-17-17.0.13+11/test/jdk/java/awt/Dialog/NestedDialogs/Modal/NestedModalDialogTest.java | 25 openjdk-17-17.0.13+11/test/jdk/java/awt/FileDialog/FilenameFilterTest/FilenameFilterTest.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/Focus/6981400/Test1.java | 57 openjdk-17-17.0.13+11/test/jdk/java/awt/Focus/ActualFocusedWindowTest/ActualFocusedWindowBlockingTest.java | 48 openjdk-17-17.0.13+11/test/jdk/java/awt/Focus/AutoRequestFocusTest/AutoRequestFocusSetVisibleTest.java | 58 openjdk-17-17.0.13+11/test/jdk/java/awt/Focus/AutoRequestFocusTest/AutoRequestFocusToFrontTest.java | 23 openjdk-17-17.0.13+11/test/jdk/java/awt/Focus/ModalBlockedStealsFocusTest/ModalBlockedStealsFocusTest.java | 7 openjdk-17-17.0.13+11/test/jdk/java/awt/Focus/ModalDialogInFocusEventTest.java | 38 openjdk-17-17.0.13+11/test/jdk/java/awt/Focus/ModalExcludedWindowClickTest/ModalExcludedWindowClickTest.java | 8 openjdk-17-17.0.13+11/test/jdk/java/awt/Focus/NonFocusableBlockedOwnerTest/NonFocusableBlockedOwnerTest.java | 8 openjdk-17-17.0.13+11/test/jdk/java/awt/Focus/NonFocusableWindowTest/NonfocusableOwnerTest.java | 45 openjdk-17-17.0.13+11/test/jdk/java/awt/Focus/OwnedWindowFocusIMECrashTest/OwnedWindowFocusIMECrashTest.java | 3 openjdk-17-17.0.13+11/test/jdk/java/awt/Focus/SimpleWindowActivationTest/SimpleWindowActivationTest.java | 8 openjdk-17-17.0.13+11/test/jdk/java/awt/Focus/WindowUpdateFocusabilityTest/WindowUpdateFocusabilityTest.java | 7 openjdk-17-17.0.13+11/test/jdk/java/awt/FontMetrics/ExtremeFontSizeTest.java | 118 openjdk-17-17.0.13+11/test/jdk/java/awt/Frame/DefaultSizeTest.java | 68 openjdk-17-17.0.13+11/test/jdk/java/awt/Frame/FrameRepackTest.java | 175 openjdk-17-17.0.13+11/test/jdk/java/awt/Frame/FrameResizeTest/FrameResizeTest_1.java | 92 openjdk-17-17.0.13+11/test/jdk/java/awt/Frame/FrameResizeTest/FrameResizeTest_2.java | 144 openjdk-17-17.0.13+11/test/jdk/java/awt/Frame/GetBoundsResizeTest.java | 97 openjdk-17-17.0.13+11/test/jdk/java/awt/Frame/GetBoundsResizeTest/GetBoundsResizeTest.java | 168 openjdk-17-17.0.13+11/test/jdk/java/awt/Frame/WindowMoveTest.java | 166 openjdk-17-17.0.13+11/test/jdk/java/awt/LightweightComponent/LightweightCliprect.java | 120 openjdk-17-17.0.13+11/test/jdk/java/awt/List/ActionEventTest/ActionEventTest.java | 9 openjdk-17-17.0.13+11/test/jdk/java/awt/List/MouseDraggedOutCauseScrollingTest/MouseDraggedOutCauseScrollingTest.html | 43 openjdk-17-17.0.13+11/test/jdk/java/awt/List/MouseDraggedOutCauseScrollingTest/MouseDraggedOutCauseScrollingTest.java | 276 openjdk-17-17.0.13+11/test/jdk/java/awt/MenuBar/AddRemoveMenuBarTests/AddRemoveMenuBarTest_1.java | 104 openjdk-17-17.0.13+11/test/jdk/java/awt/MenuBar/AddRemoveMenuBarTests/AddRemoveMenuBarTest_2.java | 99 openjdk-17-17.0.13+11/test/jdk/java/awt/MenuBar/AddRemoveMenuBarTests/AddRemoveMenuBarTest_3.java | 195 openjdk-17-17.0.13+11/test/jdk/java/awt/MenuBar/AddRemoveMenuBarTests/AddRemoveMenuBarTest_4.java | 116 openjdk-17-17.0.13+11/test/jdk/java/awt/Mixing/AWT_Mixing/HierarchyBoundsListenerMixingTest.java | 192 openjdk-17-17.0.13+11/test/jdk/java/awt/Modal/ToFront/FrameToFrontModelessTest.java | 8 openjdk-17-17.0.13+11/test/jdk/java/awt/Modal/helpers/TestDialog.java | 11 openjdk-17-17.0.13+11/test/jdk/java/awt/Modal/helpers/TestFrame.java | 12 openjdk-17-17.0.13+11/test/jdk/java/awt/Mouse/MouseModifiersUnitTest/ExtraButtonDrag.java | 5 openjdk-17-17.0.13+11/test/jdk/java/awt/Paint/PaintSetEnabledDeadlock/PaintSetEnabledDeadlock.java | 193 openjdk-17-17.0.13+11/test/jdk/java/awt/PrintJob/ConstrainedPrintingTest/ConstrainedPrintingTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/PrintJob/EdgeTest/EdgeTest.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/PrintJob/HighResTest.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/PrintJob/JobAttrUpdateTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/PrintJob/MultipleEnd/MultipleEnd.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/PrintJob/PageSetupDlgBlockingTest/PageSetupDlgBlockingTest.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/PrintJob/PrintArcTest/PrintArcTest.java | 3 openjdk-17-17.0.13+11/test/jdk/java/awt/PrintJob/PrintCheckboxTest/PrintCheckboxManualTest.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/PrintJob/QuoteAndBackslashTest/QuoteAndBackslashTest.java | 3 openjdk-17-17.0.13+11/test/jdk/java/awt/PrintJob/RoundedRectTest/RoundedRectTest.java | 3 openjdk-17-17.0.13+11/test/jdk/java/awt/PrintJob/SaveDialogTitleTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/PrintJob/Security/SecurityDialogTest.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/PrintJob/TestPrintJobFrameAssociation.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/PrintJob/Text/stringwidth.sh | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/Robot/AcceptExtraMouseButtons/AcceptExtraMouseButtons.java | 4 openjdk-17-17.0.13+11/test/jdk/java/awt/Robot/ManualInstructions/ManualInstructions.java | 328 openjdk-17-17.0.13+11/test/jdk/java/awt/ScrollPane/ScrollPaneTest.java | 216 openjdk-17-17.0.13+11/test/jdk/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java | 4 openjdk-17-17.0.13+11/test/jdk/java/awt/TextArea/Length.java | 61 openjdk-17-17.0.13+11/test/jdk/java/awt/Toolkit/DesktopProperties/rfe4758438.java | 114 openjdk-17-17.0.13+11/test/jdk/java/awt/Toolkit/DesktopProperties/rfe4758438.sh | 41 openjdk-17-17.0.13+11/test/jdk/java/awt/Window/FindOwner/FindOwnerTest.html | 44 openjdk-17-17.0.13+11/test/jdk/java/awt/Window/FindOwner/FindOwnerTest.java | 110 openjdk-17-17.0.13+11/test/jdk/java/awt/Window/Grab/GrabTest.java | 128 openjdk-17-17.0.13+11/test/jdk/java/awt/Window/GrabSequence/GrabSequence.java | 7 openjdk-17-17.0.13+11/test/jdk/java/awt/Window/WindowOwner.java | 155 openjdk-17-17.0.13+11/test/jdk/java/awt/color/ICC_Profile/CustomCMMID.java | 69 openjdk-17-17.0.13+11/test/jdk/java/awt/dnd/MouseEventAfterStartDragTest/MouseEventAfterStartDragTest.java | 214 openjdk-17-17.0.13+11/test/jdk/java/awt/dnd/RecognizedActionTest/RecognizedActionTest.java | 5 openjdk-17-17.0.13+11/test/jdk/java/awt/event/KeyEvent/FunctionKeyTest.java | 136 openjdk-17-17.0.13+11/test/jdk/java/awt/event/MouseEvent/ClickDuringKeypress/ClickDuringKeypress.java | 142 openjdk-17-17.0.13+11/test/jdk/java/awt/font/JNICheck/JNICheck.sh | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/font/Rotate/RotateTest3.java | 114 openjdk-17-17.0.13+11/test/jdk/java/awt/font/TextLayout/ArabicBox.java | 103 openjdk-17-17.0.13+11/test/jdk/java/awt/font/TextLayout/TestJustification.html | 52 openjdk-17-17.0.13+11/test/jdk/java/awt/font/TextLayout/TestJustification.java | 438 openjdk-17-17.0.13+11/test/jdk/java/awt/print/Dialog/DestinationTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/Dialog/DialogCopies.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/Dialog/DialogOrient.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/Dialog/DialogOwnerTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/Dialog/DialogType.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/Dialog/MediaInPrintable.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/Dialog/PaperSizeError.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/Dialog/PrintApplet.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/Dialog/PrintDialog.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/Dialog/PrintDlgPageable.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/Dialog/RestoreActiveWindowTest/RestoreActiveWindowTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/Headless/HeadlessPrinterJob.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/MissedFontFamilyName/PrintFontWithMissedFontFamilyTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PageFormat/CustomPaper.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PageFormat/ImageableAreaTest.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PageFormat/NullPaper.java | 7 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PageFormat/Orient.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PageFormat/PageFormatFromAttributes.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PageFormat/PageSetupDialog.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PageFormat/PrintContentCutOffTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PageFormat/ReverseLandscapeTest.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PageFormat/SetOrient.html | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PageFormat/SmallPaperPrinting.java | 83 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PageFormat/ValidateCustom.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PageFormat/WrongPaperForBookPrintingTest.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PageFormat/WrongPaperPrintingTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PaintSetEnabledDeadlock/PaintSetEnabledDeadlock.java | 193 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PathPrecisionScaleFactor/PathPrecisionScaleFactorShapeTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PathPrecisionScaleFactor/PathPrecisionScaleFactorTextTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/BannerTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/Cancel/PrinterJobCancel.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/Collate2DPrintingTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/CompareImageable.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/CustomFont/CustomFont.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/CustomPrintService/PrintDialog.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/CustomPrintService/SetPrintServiceTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/DeviceScale.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/DlgAttrsBug.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/DrawImage.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/DrawStringMethods.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/EmptyFill.java | 6 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/GetMediasTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/ImagePrinting/ImageTypes.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/ImagePrinting/PrintARGBImage.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/InitToBlack.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/InvalidPage.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/JobName/PrinterJobName.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/LandscapeStackOverflow.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/Legal/PrintTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/LinearGradientPrintingTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/MultiMonPrintDlgTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/MultiThread/MultiThreadTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/NumCopies.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PageDialogMarginTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PageDialogMarginValidation.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PageDialogTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PageDlgApp.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PageDlgPrnButton.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PageDlgStackOverflowTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PageFormatChange.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PageRanges.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PolylinePrintingTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PrintAWTImage.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PrintAllFonts.java | 4 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PrintAttributeUpdateTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PrintBadImage.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PrintCompoundString.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PrintDialog.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PrintDialogCancel.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PrintDlgPageable.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PrintDlgSelectionAttribTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PrintFontStyle.java | 7 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PrintGlyphVectorTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PrintImage.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PrintLatinCJKTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PrintNullString.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PrintParenString.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PrintRotatedText.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PrintTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PrintTestLexmarkIQ.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PrintTextLayout.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PrintTextTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PrintTranslatedFont.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PrintVolatileImage.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PrinterDialogsModalityTest/PrinterDialogsModalityTest.html | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PrinterDialogsModalityTest/PrinterDialogsModalityTest.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/PrinterJobDialogBugDemo.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/RadialGradientPrintingTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/RemoveListener.java | 3 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/SameService.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/ScaledText/ScaledText.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/SecurityDialogTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/SetCopies/Test.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/SwingUIText.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/TestCheckSystemDefaultBannerOption.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/TestMediaTraySelection.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/TestPageDlgFrameAssociation.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/TestPrintDlgFrameAssociation.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/TexturePaintPrintingTest.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/ThinLines.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/ValidatePage/ValidatePage.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/XparColor.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/PrinterJob/raster/RasterTest.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/RemotePrinterStatusRefresh/RemotePrinterStatusRefresh.java | 1 openjdk-17-17.0.13+11/test/jdk/java/awt/print/bug8023392/bug8023392.html | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/print/bug8023392/bug8023392.java | 2 openjdk-17-17.0.13+11/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java | 252 openjdk-17-17.0.13+11/test/jdk/java/awt/regtesthelpers/Util.java | 8 openjdk-17-17.0.13+11/test/jdk/java/io/Serializable/concurrentClassDescLookup/ConcurrentClassDescLookup.java | 58 openjdk-17-17.0.13+11/test/jdk/java/lang/ClassLoader/forNameLeak/ClassForNameLeak.java | 72 openjdk-17-17.0.13+11/test/jdk/java/lang/Math/CubeRootTests.java | 25 openjdk-17-17.0.13+11/test/jdk/java/lang/Math/Expm1Tests.java | 24 openjdk-17-17.0.13+11/test/jdk/java/lang/Math/HyperbolicTests.java | 52 openjdk-17-17.0.13+11/test/jdk/java/lang/Math/InverseTrigTests.java | 187 openjdk-17-17.0.13+11/test/jdk/java/lang/Math/Log10Tests.java | 36 openjdk-17-17.0.13+11/test/jdk/java/lang/Math/Log1pTests.java | 21 openjdk-17-17.0.13+11/test/jdk/java/lang/Math/Tests.java | 35 openjdk-17-17.0.13+11/test/jdk/java/lang/ProcessBuilder/JspawnhelperWarnings.java | 76 openjdk-17-17.0.13+11/test/jdk/java/lang/ProcessBuilder/PipelineLeaksFD.java | 39 openjdk-17-17.0.13+11/test/jdk/java/lang/invoke/defineHiddenClass/UnloadingTest.java | 4 openjdk-17-17.0.13+11/test/jdk/java/lang/management/ClassLoadingMXBean/TestVerboseClassLoading.java | 84 openjdk-17-17.0.13+11/test/jdk/java/lang/management/MemoryMXBean/TestVerboseMemory.java | 79 openjdk-17-17.0.13+11/test/jdk/java/net/MulticastSocket/IPMulticastIF.java | 34 openjdk-17-17.0.13+11/test/jdk/java/net/ProxySelector/LoopbackAddresses.java | 63 openjdk-17-17.0.13+11/test/jdk/java/net/ProxySelector/ProxyTest.java | 62 openjdk-17-17.0.13+11/test/jdk/java/net/URL/PerConnectionProxy.java | 69 openjdk-17-17.0.13+11/test/jdk/java/net/URLConnection/B5052093.java | 68 openjdk-17-17.0.13+11/test/jdk/java/net/httpclient/ForbiddenHeadTest.java | 32 openjdk-17-17.0.13+11/test/jdk/java/net/httpclient/ProxySelectorTest.java | 23 openjdk-17-17.0.13+11/test/jdk/java/net/httpclient/Response1xxTest.java | 497 openjdk-17-17.0.13+11/test/jdk/java/net/httpclient/http2/BadHeadersTest.java | 35 openjdk-17-17.0.13+11/test/jdk/java/net/httpclient/http2/PushPromiseContinuation.java | 367 openjdk-17-17.0.13+11/test/jdk/java/net/httpclient/http2/TrailingHeadersTest.java | 325 openjdk-17-17.0.13+11/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/HttpServerAdapters.java | 12 openjdk-17-17.0.13+11/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/BodyOutputStream.java | 6 openjdk-17-17.0.13+11/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/HpackTestEncoder.java | 174 openjdk-17-17.0.13+11/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2TestExchange.java | 13 openjdk-17-17.0.13+11/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2TestExchangeImpl.java | 30 openjdk-17-17.0.13+11/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2TestServer.java | 2 openjdk-17-17.0.13+11/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2TestServerConnection.java | 239 openjdk-17-17.0.13+11/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/OutgoingPushPromise.java | 16 openjdk-17-17.0.13+11/test/jdk/java/net/httpclient/whitebox/SSLFlowDelegateTestDriver.java | 33 openjdk-17-17.0.13+11/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SSLFlowDelegateTest.java | 595 openjdk-17-17.0.13+11/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SSLTubeTest.java | 14 openjdk-17-17.0.13+11/test/jdk/java/nio/channels/AsyncCloseAndInterrupt.java | 1 openjdk-17-17.0.13+11/test/jdk/java/nio/channels/DatagramChannel/Disconnect.java | 45 openjdk-17-17.0.13+11/test/jdk/java/nio/channels/DatagramChannel/Loopback.java | 14 openjdk-17-17.0.13+11/test/jdk/java/nio/channels/DatagramChannel/SendReceiveMaxSize.java | 17 openjdk-17-17.0.13+11/test/jdk/java/nio/channels/DatagramChannel/StressNativeSignal.java | 136 openjdk-17-17.0.13+11/test/jdk/java/nio/channels/FileChannel/BlockDeviceSize.java | 49 openjdk-17-17.0.13+11/test/jdk/java/nio/channels/SocketChannel/OpenLeak.java | 106 openjdk-17-17.0.13+11/test/jdk/java/nio/charset/StandardCharsets/Standard.java | 195 openjdk-17-17.0.13+11/test/jdk/java/nio/file/attribute/BasicFileAttributeView/CreationTime.java | 42 openjdk-17-17.0.13+11/test/jdk/java/rmi/reliability/benchmark/bench/Makefile | 3 openjdk-17-17.0.13+11/test/jdk/java/rmi/reliability/benchmark/bench/rmi/Makefile | 3 openjdk-17-17.0.13+11/test/jdk/java/security/Provider/CaseSensitiveServices.java | 33 openjdk-17-17.0.13+11/test/jdk/java/text/Format/MessageFormat/MaxArgumentIndexTest.java | 97 openjdk-17-17.0.13+11/test/jdk/java/text/Format/MessageFormat/SerializationTest.java | 96 openjdk-17-17.0.13+11/test/jdk/java/text/Format/NumberFormat/BigDecimalCompatibilityTest.java | 202 openjdk-17-17.0.13+11/test/jdk/java/text/Format/NumberFormat/Bug4208135.java | 237 openjdk-17-17.0.13+11/test/jdk/java/text/Format/NumberFormat/Bug4838107.java | 413 openjdk-17-17.0.13+11/test/jdk/java/text/Format/NumberFormat/Bug4944439.java | 138 openjdk-17-17.0.13+11/test/jdk/java/text/Format/NumberFormat/Bug4990596.java | 22 openjdk-17-17.0.13+11/test/jdk/java/text/Format/NumberFormat/Bug6278616.java | 73 openjdk-17-17.0.13+11/test/jdk/java/text/Format/NumberFormat/Bug8132125.java | 23 openjdk-17-17.0.13+11/test/jdk/java/text/Format/NumberFormat/CurrencyFormat.java | 203 openjdk-17-17.0.13+11/test/jdk/java/text/Format/NumberFormat/TestPeruCurrencyFormat.java | 22 openjdk-17-17.0.13+11/test/jdk/java/util/Currency/CheckDataVersion.java | 4 openjdk-17-17.0.13+11/test/jdk/java/util/Currency/CurrencyTest.java | 6 openjdk-17-17.0.13+11/test/jdk/java/util/Currency/ISO4217-list-one.txt | 284 openjdk-17-17.0.13+11/test/jdk/java/util/Currency/ValidateISO4217.java | 13 openjdk-17-17.0.13+11/test/jdk/java/util/Currency/tablea1.txt | 284 openjdk-17-17.0.13+11/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java | 4 openjdk-17-17.0.13+11/test/jdk/java/util/ResourceBundle/Control/MissingResourceCauseTestRun.java | 12 openjdk-17-17.0.13+11/test/jdk/java/util/concurrent/ConcurrentHashMap/ToArray.java | 113 openjdk-17-17.0.13+11/test/jdk/java/util/jar/JarFile/mrjar/MultiReleaseJarAPI.java | 7 openjdk-17-17.0.13+11/test/jdk/java/util/logging/LogManager/Configuration/updateConfiguration/HandlersOnComplexResetUpdate.java | 15 openjdk-17-17.0.13+11/test/jdk/java/util/logging/LogManager/Configuration/updateConfiguration/HandlersOnComplexUpdate.java | 15 openjdk-17-17.0.13+11/test/jdk/java/util/regex/GraphemeTest.java | 388 openjdk-17-17.0.13+11/test/jdk/java/util/regex/whitebox/GraphemeTest.java | 106 openjdk-17-17.0.13+11/test/jdk/java/util/regex/whitebox/java.base/java/util/regex/GraphemeTestAccessor.java | 41 openjdk-17-17.0.13+11/test/jdk/java/util/zip/DataDescriptorSignatureMissing.java | 224 openjdk-17-17.0.13+11/test/jdk/java/util/zip/ZipFile/ReadLongZipFileName.java | 158 openjdk-17-17.0.13+11/test/jdk/java/util/zip/ZipFile/Zip64SizeTest.java | 213 openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/ButtonDemo.html | 80 openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/ButtonDemo.java | 28 openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/ComboBoxDemo.html | 75 openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/ComboBoxDemo.java | 28 openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/DemoSelection.html | 66 openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/DemoSelection.java | 28 openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/OptionPaneDemo.html | 78 openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/OptionPaneDemo.java | 29 openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/README.md | 79 openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/SwingSetTest.java | 56 openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/TableDemo.html | 81 openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/TableDemo.java | 28 openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/TabsDemo.html | 67 openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/TabsDemo.java | 29 openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/TestJProgressBarAccessibility.java | 117 openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/TreeDemo.html | 65 openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/TreeDemo.java | 28 openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/lib/DescriptionPane.java | 54 openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/lib/FailureReasonPane.java | 73 openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/lib/ManualTestFrame.java | 204 openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/lib/PassFailPane.java | 74 openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/lib/ScreenImagePane.java | 124 openjdk-17-17.0.13+11/test/jdk/javax/accessibility/manual/lib/TestResult.java | 79 openjdk-17-17.0.13+11/test/jdk/javax/crypto/KEM/RSA_KEM.java | 533 openjdk-17-17.0.13+11/test/jdk/javax/crypto/SecretKeyFactory/evilprov/Makefile | 4 openjdk-17-17.0.13+11/test/jdk/javax/management/remote/mandatory/connection/DefaultAgentFilterTest.java | 4 openjdk-17-17.0.13+11/test/jdk/javax/naming/module/RunBasic.java | 30 openjdk-17-17.0.13+11/test/jdk/javax/naming/module/src/test/test/ConnectWithAuthzId.java | 6 openjdk-17-17.0.13+11/test/jdk/javax/naming/module/src/test/test/ConnectWithFoo.java | 5 openjdk-17-17.0.13+11/test/jdk/javax/naming/module/src/test/test/ReadByUrl.java | 5 openjdk-17-17.0.13+11/test/jdk/javax/naming/module/src/test/test/StoreFruit.java | 12 openjdk-17-17.0.13+11/test/jdk/javax/naming/module/src/test/test/StoreObject.java | 12 openjdk-17-17.0.13+11/test/jdk/javax/naming/module/src/test/test/StorePerson.java | 12 openjdk-17-17.0.13+11/test/jdk/javax/naming/module/src/test/test/StoreRemote.java | 9 openjdk-17-17.0.13+11/test/jdk/javax/net/ssl/DTLS/CipherSuite.java | 4 openjdk-17-17.0.13+11/test/jdk/javax/net/ssl/DTLS/DTLSWontNegotiateV10.java | 58 openjdk-17-17.0.13+11/test/jdk/javax/net/ssl/DTLS/InvalidRecords.java | 32 openjdk-17-17.0.13+11/test/jdk/javax/net/ssl/SSLSession/ServerNameRejectedTLSSessionResumption.java | 247 openjdk-17-17.0.13+11/test/jdk/javax/net/ssl/TLSCommon/MFLNTest.java | 12 openjdk-17-17.0.13+11/test/jdk/javax/net/ssl/ciphersuites/DisabledAlgorithms.java | 37 openjdk-17-17.0.13+11/test/jdk/javax/net/ssl/sanity/ciphersuites/CheckCipherSuites.java | 96 openjdk-17-17.0.13+11/test/jdk/javax/print/DialogMargins.java | 2 openjdk-17-17.0.13+11/test/jdk/javax/print/LookupServices.java | 1 openjdk-17-17.0.13+11/test/jdk/javax/print/PrintServiceLookup/GetPrintServices.java | 1 openjdk-17-17.0.13+11/test/jdk/javax/print/PrintSubInputStream/Example.java | 2 openjdk-17-17.0.13+11/test/jdk/javax/print/ServiceUIPropBtnTest.java | 1 openjdk-17-17.0.13+11/test/jdk/javax/print/TextFlavorTest.java | 1 openjdk-17-17.0.13+11/test/jdk/javax/print/attribute/Chroma.java | 2 openjdk-17-17.0.13+11/test/jdk/javax/print/attribute/CollateAttr.java | 1 openjdk-17-17.0.13+11/test/jdk/javax/print/attribute/PSCopiesFlavorTest.java | 1 openjdk-17-17.0.13+11/test/jdk/javax/print/attribute/PrintResAttr.java | 1 openjdk-17-17.0.13+11/test/jdk/javax/print/attribute/ServiceDialogTest.java | 1 openjdk-17-17.0.13+11/test/jdk/javax/print/attribute/ServiceDialogValidateTest.java | 1 openjdk-17-17.0.13+11/test/jdk/javax/print/attribute/ServiceDlgPageRangeTest.java | 1 openjdk-17-17.0.13+11/test/jdk/javax/print/attribute/ServiceDlgSheetCollateTest.java | 1 openjdk-17-17.0.13+11/test/jdk/javax/print/attribute/Services_getDocFl.java | 1 openjdk-17-17.0.13+11/test/jdk/javax/print/attribute/SidesAttributeTest.java | 1 openjdk-17-17.0.13+11/test/jdk/javax/print/attribute/TestUnsupportedResolution.java | 1 openjdk-17-17.0.13+11/test/jdk/javax/print/attribute/autosense/PrintAutoSenseData.java | 1 openjdk-17-17.0.13+11/test/jdk/javax/swing/JButton/bug4234034.java | 72 openjdk-17-17.0.13+11/test/jdk/javax/swing/JButton/bug4323121.java | 125 openjdk-17-17.0.13+11/test/jdk/javax/swing/JButton/bug4490179.java | 95 openjdk-17-17.0.13+11/test/jdk/javax/swing/JComponent/6683775/bug6683775.java | 66 openjdk-17-17.0.13+11/test/jdk/javax/swing/JEditorPane/EditorPaneCharset.java | 74 openjdk-17-17.0.13+11/test/jdk/javax/swing/JFileChooser/8041694/bug8041694.java | 4 openjdk-17-17.0.13+11/test/jdk/javax/swing/JFileChooser/8046391/bug8046391.java | 2 openjdk-17-17.0.13+11/test/jdk/javax/swing/JFileChooser/FileSystemView/NoIconExeNPE.java | 274 openjdk-17-17.0.13+11/test/jdk/javax/swing/JFileChooser/FileSystemView/Win32FolderSort.java | 158 openjdk-17-17.0.13+11/test/jdk/javax/swing/JFileChooser/FileSystemView/WindowsDefaultIconSizeTest.java | 73 openjdk-17-17.0.13+11/test/jdk/javax/swing/JFrame/DefaultCloseOperation.java | 221 openjdk-17-17.0.13+11/test/jdk/javax/swing/JFrame/bug4419914.java | 82 openjdk-17-17.0.13+11/test/jdk/javax/swing/JMenuBar/RightLeftOrientation.java | 154 openjdk-17-17.0.13+11/test/jdk/javax/swing/JPopupMenu/6580930/bug6580930.java | 17 openjdk-17-17.0.13+11/test/jdk/javax/swing/JPopupMenu/FocusablePopupDismissTest.java | 94 openjdk-17-17.0.13+11/test/jdk/javax/swing/JRadioButton/8033699/bug8033699.java | 2 openjdk-17-17.0.13+11/test/jdk/javax/swing/JRadioButton/bug4823809.java | 93 openjdk-17-17.0.13+11/test/jdk/javax/swing/JRootPane/DefaultButtonTest.java | 5 openjdk-17-17.0.13+11/test/jdk/javax/swing/JSpinner/8008657/bug8008657.java | 4 openjdk-17-17.0.13+11/test/jdk/javax/swing/JSplitPane/bug4147653.java | 58 openjdk-17-17.0.13+11/test/jdk/javax/swing/JSplitPane/bug4870674.java | 181 openjdk-17-17.0.13+11/test/jdk/javax/swing/JTabbedPane/GetComponentAtTest.java | 96 openjdk-17-17.0.13+11/test/jdk/javax/swing/JTabbedPane/ReplaceCompTab.java | 97 openjdk-17-17.0.13+11/test/jdk/javax/swing/JTabbedPane/bug4703690.java | 148 openjdk-17-17.0.13+11/test/jdk/javax/swing/JTable/4275046/bug4275046.java | 3 openjdk-17-17.0.13+11/test/jdk/javax/swing/JTextArea/bug4849868.java | 103 openjdk-17-17.0.13+11/test/jdk/javax/swing/JTextField/bug4244613.java | 52 openjdk-17-17.0.13+11/test/jdk/javax/swing/JToolBar/RightLeftOrientation.java | 172 openjdk-17-17.0.13+11/test/jdk/javax/swing/JToolBar/bug4203039.java | 82 openjdk-17-17.0.13+11/test/jdk/javax/swing/JTree/8003400/Test8003400.java | 6 openjdk-17-17.0.13+11/test/jdk/javax/swing/border/Test4129681.html | 33 openjdk-17-17.0.13+11/test/jdk/javax/swing/border/Test4129681.java | 83 openjdk-17-17.0.13+11/test/jdk/javax/swing/plaf/basic/BasicDirectoryModel/ConcurrentModification.java | 273 openjdk-17-17.0.13+11/test/jdk/javax/swing/text/PaintTest.java | 108 openjdk-17-17.0.13+11/test/jdk/javax/swing/text/bug4148489.java | 109 openjdk-17-17.0.13+11/test/jdk/javax/swing/text/html/HTMLDocument/HTMLStrikeOnly.java | 135 openjdk-17-17.0.13+11/test/jdk/javax/swing/text/html/HTMLDocument/HTMLTextDecoration.java | 157 openjdk-17-17.0.13+11/test/jdk/javax/swing/text/html/HTMLDocument/HTMLTextDecorationNone.java | 128 openjdk-17-17.0.13+11/test/jdk/javax/swing/text/html/HTMLDocument/HTMLUnderlineOnly.java | 129 openjdk-17-17.0.13+11/test/jdk/javax/swing/text/html/HTMLDocument/HTMLUnderlineStrike.java | 89 openjdk-17-17.0.13+11/test/jdk/javax/swing/text/html/StyleSheet/TestExternalCSSFontSize.css | 14 openjdk-17-17.0.13+11/test/jdk/javax/swing/text/html/StyleSheet/TestExternalCSSFontSize.html | 21 openjdk-17-17.0.13+11/test/jdk/javax/swing/text/html/StyleSheet/TestExternalCSSFontSize.java | 171 openjdk-17-17.0.13+11/test/jdk/javax/swing/text/html/StyleSheet/bug4803145.java | 97 openjdk-17-17.0.13+11/test/jdk/jdk/incubator/vector/Double128VectorTests.java | 47 openjdk-17-17.0.13+11/test/jdk/jdk/incubator/vector/Double256VectorTests.java | 47 openjdk-17-17.0.13+11/test/jdk/jdk/incubator/vector/Double512VectorTests.java | 47 openjdk-17-17.0.13+11/test/jdk/jdk/incubator/vector/Double64VectorTests.java | 47 openjdk-17-17.0.13+11/test/jdk/jdk/incubator/vector/DoubleMaxVectorTests.java | 48 openjdk-17-17.0.13+11/test/jdk/jdk/incubator/vector/Float128VectorTests.java | 47 openjdk-17-17.0.13+11/test/jdk/jdk/incubator/vector/Float256VectorTests.java | 47 openjdk-17-17.0.13+11/test/jdk/jdk/incubator/vector/Float512VectorTests.java | 47 openjdk-17-17.0.13+11/test/jdk/jdk/incubator/vector/Float64VectorTests.java | 47 openjdk-17-17.0.13+11/test/jdk/jdk/incubator/vector/FloatMaxVectorTests.java | 48 openjdk-17-17.0.13+11/test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Masked-op.template | 4 openjdk-17-17.0.13+11/test/jdk/jdk/incubator/vector/templates/Unit-Reduction-op.template | 4 openjdk-17-17.0.13+11/test/jdk/jdk/incubator/vector/templates/Unit-header.template | 57 openjdk-17-17.0.13+11/test/jdk/jdk/internal/loader/URLClassPath/LargeClasspathWithPkgPrefix.java | 140 openjdk-17-17.0.13+11/test/jdk/jdk/jfr/api/consumer/TestRecordedClass.java | 115 openjdk-17-17.0.13+11/test/jdk/jdk/jfr/api/consumer/filestream/TestOrdered.java | 6 openjdk-17-17.0.13+11/test/jdk/jdk/jfr/event/oldobject/TestListenerLeak.java | 22 openjdk-17-17.0.13+11/test/jdk/jdk/jfr/event/oldobject/TestSanityDefault.java | 4 openjdk-17-17.0.13+11/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java | 29 openjdk-17-17.0.13+11/test/jdk/sun/java2d/marlin/ScaleTest.java | 6 openjdk-17-17.0.13+11/test/jdk/sun/java2d/marlin/StrokeShapeTest.java | 6 openjdk-17-17.0.13+11/test/jdk/sun/java2d/marlin/ThinLineTest.java | 6 openjdk-17-17.0.13+11/test/jdk/sun/management/jmxremote/bootstrap/RmiRegistrySslTest.java | 4 openjdk-17-17.0.13+11/test/jdk/sun/management/jmxremote/bootstrap/exelauncher.c | 5 openjdk-17-17.0.13+11/test/jdk/sun/management/windows/exerevokeall.c | 9 openjdk-17-17.0.13+11/test/jdk/sun/net/www/AuthHeaderTest.java | 133 openjdk-17-17.0.13+11/test/jdk/sun/net/www/http/KeepAliveCache/B5045306.java | 80 openjdk-17-17.0.13+11/test/jdk/sun/net/www/http/KeepAliveCache/B8293562.java | 14 openjdk-17-17.0.13+11/test/jdk/sun/net/www/httptest/AbstractCallback.java | 82 openjdk-17-17.0.13+11/test/jdk/sun/net/www/httptest/ClosedChannelList.java | 77 openjdk-17-17.0.13+11/test/jdk/sun/net/www/httptest/HttpCallback.java | 39 openjdk-17-17.0.13+11/test/jdk/sun/net/www/httptest/HttpTransaction.java | 330 openjdk-17-17.0.13+11/test/jdk/sun/net/www/httptest/TestHttpServer.java | 797 openjdk-17-17.0.13+11/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java | 13 openjdk-17-17.0.13+11/test/jdk/sun/security/ssl/InputRecord/ClientHelloRead.java | 20 openjdk-17-17.0.13+11/test/jdk/sun/security/ssl/SSLSessionImpl/ResumptionUpdateBoundValues.java | 5 openjdk-17-17.0.13+11/test/jdk/sun/security/ssl/SSLSocketImpl/ReuseAddr.java | 22 openjdk-17-17.0.13+11/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketBruceForceClose.java | 102 openjdk-17-17.0.13+11/test/jdk/sun/security/ssl/X509TrustManagerImpl/Entrust/Distrust.java | 249 openjdk-17-17.0.13+11/test/jdk/sun/security/ssl/X509TrustManagerImpl/Entrust/affirmtrustcommercialca-chain.pem | 77 openjdk-17-17.0.13+11/test/jdk/sun/security/ssl/X509TrustManagerImpl/Entrust/affirmtrustnetworkingca-chain.pem | 76 openjdk-17-17.0.13+11/test/jdk/sun/security/ssl/X509TrustManagerImpl/Entrust/affirmtrustpremiumca-chain.pem | 88 openjdk-17-17.0.13+11/test/jdk/sun/security/ssl/X509TrustManagerImpl/Entrust/affirmtrustpremiumeccca-chain.pem | 63 openjdk-17-17.0.13+11/test/jdk/sun/security/ssl/X509TrustManagerImpl/Entrust/entrust2048ca-chain.pem | 76 openjdk-17-17.0.13+11/test/jdk/sun/security/ssl/X509TrustManagerImpl/Entrust/entrustevca-chain.pem | 79 openjdk-17-17.0.13+11/test/jdk/sun/security/ssl/X509TrustManagerImpl/Entrust/entrustrootcaec1-chain.pem | 66 openjdk-17-17.0.13+11/test/jdk/sun/security/ssl/X509TrustManagerImpl/Entrust/entrustrootcag2-chain.pem | 80 openjdk-17-17.0.13+11/test/jdk/sun/security/ssl/X509TrustManagerImpl/Entrust/entrustrootcag4-chain.pem | 92 openjdk-17-17.0.13+11/test/jdk/sun/security/tools/keytool/i18n.java | 341 openjdk-17-17.0.13+11/test/jdk/sun/security/util/Debug/DebugOptions.java | 138 openjdk-17-17.0.13+11/test/jdk/sun/security/util/math/TestIntegerModuloP.java | 64 openjdk-17-17.0.13+11/test/jdk/sun/tools/jstatd/JstatdTest.java | 26 openjdk-17-17.0.13+11/test/jdk/tools/jpackage/share/jdk/jpackage/tests/MainClassTest.java | 4 openjdk-17-17.0.13+11/test/jdk/tools/launcher/Settings.java | 11 openjdk-17-17.0.13+11/test/jtreg-ext/requires/VMProps.java | 55 openjdk-17-17.0.13+11/test/langtools/jdk/internal/shellsupport/doc/JavadocHelperTest.java | 2 openjdk-17-17.0.13+11/test/langtools/jdk/javadoc/doclet/testBreakIterator/TestBreakIterator.java | 7 openjdk-17-17.0.13+11/test/langtools/jdk/javadoc/doclet/testBreakIterator/pkg/BreakIteratorTest.java | 5 openjdk-17-17.0.13+11/test/langtools/jdk/javadoc/doclet/testIOException/TestIOException.java | 60 openjdk-17-17.0.13+11/test/langtools/jdk/javadoc/doclet/testSearch/TestSearch.java | 4 openjdk-17-17.0.13+11/test/langtools/jdk/javadoc/doclet/testSearchScript/javadoc-search.js | 10 openjdk-17-17.0.13+11/test/langtools/jdk/javadoc/doclet/testSeeTag/TestSeeTag.java | 48 openjdk-17-17.0.13+11/test/langtools/jdk/javadoc/tool/api/basic/APITest.java | 2 openjdk-17-17.0.13+11/test/langtools/jdk/jshell/AnalyzeSnippetTest.java | 1 openjdk-17-17.0.13+11/test/langtools/jdk/jshell/CustomInputToolBuilder.java | 3 openjdk-17-17.0.13+11/test/langtools/jdk/jshell/ExecutionControlTestBase.java | 20 openjdk-17-17.0.13+11/test/langtools/jdk/jshell/FailOverDirectExecutionControlTest.java | 10 openjdk-17-17.0.13+11/test/langtools/jdk/jshell/FailOverExecutionControlDyingLaunchTest.java | 4 openjdk-17-17.0.13+11/test/langtools/jdk/jshell/FailOverExecutionControlHangingLaunchTest.java | 4 openjdk-17-17.0.13+11/test/langtools/jdk/jshell/FailOverExecutionControlHangingListenTest.java | 4 openjdk-17-17.0.13+11/test/langtools/jdk/jshell/FailOverExecutionControlTest.java | 4 openjdk-17-17.0.13+11/test/langtools/jdk/jshell/IdGeneratorTest.java | 3 openjdk-17-17.0.13+11/test/langtools/jdk/jshell/KullaTesting.java | 7 openjdk-17-17.0.13+11/test/langtools/jdk/jshell/Presets.java | 59 openjdk-17-17.0.13+11/test/langtools/jdk/jshell/ReplToolTesting.java | 2 openjdk-17-17.0.13+11/test/langtools/jdk/jshell/StartOptionTest.java | 2 openjdk-17-17.0.13+11/test/langtools/jdk/jshell/ToolReloadTest.java | 2 openjdk-17-17.0.13+11/test/langtools/jdk/jshell/UITesting.java | 3 openjdk-17-17.0.13+11/test/langtools/tools/javac/patterns/T8312229.java | 44 openjdk-17-17.0.13+11/test/lib-test/jdk/test/lib/TestMutuallyExclusivePlatformPredicates.java | 4 openjdk-17-17.0.13+11/test/lib-test/jdk/test/lib/process/ProcessToolsStartProcessTest.java | 113 openjdk-17-17.0.13+11/test/lib-test/jdk/test/lib/process/proc/A.java | 27 openjdk-17-17.0.13+11/test/lib-test/jdk/test/lib/process/proc/B.java | 28 openjdk-17-17.0.13+11/test/lib-test/jdk/test/lib/process/proc/Launcher.java | 39 openjdk-17-17.0.13+11/test/lib/jdk/test/lib/NetworkConfiguration.java | 13 openjdk-17-17.0.13+11/test/lib/jdk/test/lib/Platform.java | 11 openjdk-17-17.0.13+11/test/lib/jdk/test/lib/SA/SATestUtils.java | 1 openjdk-17-17.0.13+11/test/lib/jdk/test/lib/UIBuilder.java | 160 openjdk-17-17.0.13+11/test/lib/jdk/test/lib/cds/CDSTestUtils.java | 5 openjdk-17-17.0.13+11/test/lib/jdk/test/lib/net/IPSupport.java | 26 openjdk-17-17.0.13+11/test/lib/jdk/test/lib/net/SimpleSSLContext.java | 3 openjdk-17-17.0.13+11/test/lib/jdk/test/lib/process/Proc.java | 87 openjdk-17-17.0.13+11/test/lib/jdk/test/lib/process/ProcessTools.java | 116 openjdk-17-17.0.13+11/test/lib/jdk/test/lib/util/ForceGC.java | 39 openjdk-17-17.0.13+11/test/micro/org/openjdk/bench/java/security/AlgorithmConstraintsPermits.java | 6 openjdk-17-17.0.13+11/test/micro/org/openjdk/bench/java/security/CacheBench.java | 6 openjdk-17-17.0.13+11/test/micro/org/openjdk/bench/java/security/CipherSuiteBench.java | 6 openjdk-17-17.0.13+11/test/micro/org/openjdk/bench/java/security/DoPrivileged.java | 8 openjdk-17-17.0.13+11/test/micro/org/openjdk/bench/java/security/GetContext.java | 8 openjdk-17-17.0.13+11/test/micro/org/openjdk/bench/java/security/GetMessageDigest.java | 4 openjdk-17-17.0.13+11/test/micro/org/openjdk/bench/java/security/MessageDigests.java | 14 openjdk-17-17.0.13+11/test/micro/org/openjdk/bench/java/security/PKCS12KeyStores.java | 8 openjdk-17-17.0.13+11/test/micro/org/openjdk/bench/java/security/PermissionsImplies.java | 4 openjdk-17-17.0.13+11/test/micro/org/openjdk/bench/java/security/SSLHandshake.java | 6 openjdk-17-17.0.13+11/test/micro/org/openjdk/bench/java/security/SecureRandomBench.java | 43 openjdk-17-17.0.13+11/test/micro/org/openjdk/bench/vm/compiler/InterfaceCalls.java | 295 1269 files changed, 55730 insertions(+), 26237 deletions(-) diff -Nru openjdk-17-17.0.12+7/.jcheck/conf openjdk-17-17.0.13+11/.jcheck/conf --- openjdk-17-17.0.12+7/.jcheck/conf 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/.jcheck/conf 2024-10-10 14:01:59.000000000 +0000 @@ -1,10 +1,11 @@ [general] project=jdk-updates jbs=JDK -version=17.0.12 +version=17.0.13 [checks] error=author,committer,reviewers,merge,issues,executable,symlink,message,hg-tag,whitespace,problemlists +warning=issuestitle,binary [repository] tags=(?:jdk-(?:[1-9]([0-9]*)(?:\.(?:0|[1-9][0-9]*)){0,4})(?:\+(?:(?:[0-9]+))|(?:-ga)))|(?:jdk[4-9](?:u\d{1,3})?-(?:(?:b\d{2,3})|(?:ga)))|(?:hs\d\d(?:\.\d{1,2})?-b\d\d) diff -Nru openjdk-17-17.0.12+7/debian/JB-demo.overrides.in openjdk-17-17.0.13+11/debian/JB-demo.overrides.in --- openjdk-17-17.0.12+7/debian/JB-demo.overrides.in 2024-03-20 22:00:03.000000000 +0000 +++ openjdk-17-17.0.13+11/debian/JB-demo.overrides.in 2024-08-08 06:27:17.000000000 +0000 @@ -9,3 +9,6 @@ # example jar file with sources @basename@-demo binary: jar-contains-source + +# allow repeated path segments, e.g. nbproject +@basename@-demo binary: repeated-path-segment diff -Nru openjdk-17-17.0.12+7/debian/JB-doc.overrides.in openjdk-17-17.0.13+11/debian/JB-doc.overrides.in --- openjdk-17-17.0.12+7/debian/JB-doc.overrides.in 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.13+11/debian/JB-doc.overrides.in 2024-08-08 06:27:17.000000000 +0000 @@ -0,0 +1,5 @@ +# Override due to upstream copyright +@basename@-doc binary: spelling-error-in-copyright "GNU Public License" "GNU General Public License" +# chromium and firefox snaps are unable to load scripts from /usr/share/javascript +# LP: 2032992 +@basename@-doc binary: embedded-javascript-library diff -Nru openjdk-17-17.0.12+7/debian/JB-jdk-headless.overrides.in openjdk-17-17.0.13+11/debian/JB-jdk-headless.overrides.in --- openjdk-17-17.0.12+7/debian/JB-jdk-headless.overrides.in 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.13+11/debian/JB-jdk-headless.overrides.in 2024-08-08 06:27:17.000000000 +0000 @@ -0,0 +1,2 @@ +# repeated lib due to upstream implementation directory layout +@basename@-jdk-headless binary: repeated-path-segment diff -Nru openjdk-17-17.0.12+7/debian/JB-jre-headless.overrides.in openjdk-17-17.0.13+11/debian/JB-jre-headless.overrides.in --- openjdk-17-17.0.12+7/debian/JB-jre-headless.overrides.in 2024-03-20 22:00:03.000000000 +0000 +++ openjdk-17-17.0.13+11/debian/JB-jre-headless.overrides.in 2024-08-08 06:27:17.000000000 +0000 @@ -1,6 +1,3 @@ -# empty directory by intent -@basename@-jre-headless binary: package-contains-empty-directory usr/share/binfmts/ - # Strip libjvm.so with --strip-debug instead of --strip-unneeded. LP: #574997. @basename@-jre-headless binary: unstripped-binary-or-object @@ -8,4 +5,14 @@ @basename@-jre-headless binary: image-file-in-usr-lib # Just an empty directory -@basename@-jre-headless binary: debug-package-should-be-named-dbg +@basename@-jre-headless binary: debug-suffix-not-dbg + +# Upstream implementation +@basename@-jre-headless binary: exit-in-shared-library +@basename@-jre-headless binary: spelling-error-in-binary + +# Override due to upstream copyright +@basename@-jre-headless binary: spelling-error-in-copyright "GNU Public License" "GNU General Public License" + +# repeated lib due to upstream implementation directory layout +@basename@-jre-headless binary: repeated-path-segment diff -Nru openjdk-17-17.0.12+7/debian/JB-jre-zero.overrides.in openjdk-17-17.0.13+11/debian/JB-jre-zero.overrides.in --- openjdk-17-17.0.12+7/debian/JB-jre-zero.overrides.in 2024-03-20 22:00:03.000000000 +0000 +++ openjdk-17-17.0.13+11/debian/JB-jre-zero.overrides.in 2024-08-08 06:27:17.000000000 +0000 @@ -1,2 +1,9 @@ # Strip libjvm.so with --strip-debug instead of --strip-unneeded. LP: #574997. @basename@-jre-zero binary: unstripped-binary-or-object + +# Upstream implementation +@basename@-jre-zero binary: exit-in-shared-library +@basename@-jre-zero binary: spelling-error-in-binary + +# repeated lib due to upstream implementation directory layout +@basename@-jre-zero binary: repeated-path-segment diff -Nru openjdk-17-17.0.12+7/debian/JB-jre.overrides.in openjdk-17-17.0.13+11/debian/JB-jre.overrides.in --- openjdk-17-17.0.12+7/debian/JB-jre.overrides.in 2024-03-20 22:00:09.000000000 +0000 +++ openjdk-17-17.0.13+11/debian/JB-jre.overrides.in 2024-08-08 06:27:17.000000000 +0000 @@ -4,3 +4,6 @@ # LP: #2012326 - in order to print allocation locations, # the libraries need to retain symbols @basename@-jre binary: unstripped-binary-or-object + +# repeated lib due to upstream implementation directory layout +@basename@-jre binary: repeated-path-segment diff -Nru openjdk-17-17.0.12+7/debian/JB-source.overrides.in openjdk-17-17.0.13+11/debian/JB-source.overrides.in --- openjdk-17-17.0.12+7/debian/JB-source.overrides.in 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.13+11/debian/JB-source.overrides.in 2024-08-08 06:27:17.000000000 +0000 @@ -0,0 +1,2 @@ +# repeated lib due to upstream implementation directory layout +@basename@-source binary: repeated-path-segment diff -Nru openjdk-17-17.0.12+7/debian/apport-hook.py openjdk-17-17.0.13+11/debian/apport-hook.py --- openjdk-17-17.0.12+7/debian/apport-hook.py 2023-03-17 00:31:13.000000000 +0000 +++ openjdk-17-17.0.13+11/debian/apport-hook.py 2024-08-23 09:21:28.000000000 +0000 @@ -1,4 +1,4 @@ -'''Apport package hook for openjdk-11 packages. +'''Apport package hook for openjdk packages. Copyright (C) 2017 Canonical Ltd. Author: Tiago Stürmer Daitx ''' @@ -16,7 +16,7 @@ return '{0:.1f} {1}'.format(size, unit) def add_info(report, ui=None): - attach_conffiles(report,'openjdk-11-jre-headless', ui=ui) + attach_conffiles(report,'openjdk-17-jre-headless', ui=ui) if report['ProblemType'] == 'Crash' and 'ProcCwd' in report: # attach hs_err_.pid file diff -Nru openjdk-17-17.0.12+7/debian/changelog openjdk-17-17.0.13+11/debian/changelog --- openjdk-17-17.0.12+7/debian/changelog 2024-07-31 15:55:14.000000000 +0000 +++ openjdk-17-17.0.13+11/debian/changelog 2024-10-17 20:50:46.000000000 +0000 @@ -1,8 +1,46 @@ -openjdk-17 (17.0.12+7-2~deb12u1) bookworm-security; urgency=medium +openjdk-17 (17.0.13+11-2~deb12u1) bookworm-security; urgency=medium * Rebuild for bookworm - -- Moritz Muehlenhoff Wed, 31 Jul 2024 17:55:14 +0200 + -- Moritz Mühlenhoff Thu, 17 Oct 2024 22:50:46 +0200 + +openjdk-17 (17.0.13+11-2) unstable; urgency=high + + * Don't enable dtrace on POWER* architectures. + + -- Matthias Klose Thu, 17 Oct 2024 10:59:51 +0200 + +openjdk-17 (17.0.13+11-1) unstable; urgency=high + + * OpenJDK 17.0.13 release, build 11. + - CVE-2024-21208 + - CVE-2024-21210 + - CVE-2024-21217 + - CVE-2024-21235 + + [ Vladimir Petko ] + * d/rules: do not include dtrace support for S390x (JDK-8305174). + * d/t/problems.csv: Disable jdk/sun/security/util/Debug/DebugOptions.java + due to JDK-8339713. + + -- Matthias Klose Wed, 16 Oct 2024 12:01:58 +0200 + +openjdk-17 (17.0.13~6ea-1) unstable; urgency=medium + + * OpenJDK 17.0.13 early access, build 6. + + [ Vladimir Petko ] + * d/copyright-generator/strip-common-licenses.sh: Add GPLv3 to the + list of common licenses. + * d/JB-*.override.in: Update lintian overrides. + * d/s/lintian-override: Add source-contains-prebuilt-javascript-object + due to LP: 2032992. + * d/p/jdk-8334895-proposed.patch: Fix typo in the patch description. + * d/t/problemlist.csv: Update problemlist.csv for July release + * d/t/jtreg-autopkgtest.{in,sh}: Increase jtreg test timeouts. + * Enable dtrace support. + + -- Matthias Klose Mon, 09 Sep 2024 15:48:20 +0200 openjdk-17 (17.0.12+7-2) unstable; urgency=medium diff -Nru openjdk-17-17.0.12+7/debian/control openjdk-17-17.0.13+11/debian/control --- openjdk-17-17.0.12+7/debian/control 2024-07-31 15:54:35.000000000 +0000 +++ openjdk-17-17.0.13+11/debian/control 2024-10-17 20:50:08.000000000 +0000 @@ -13,7 +13,7 @@ openjdk-17-jdk-headless:native | openjdk-16-jdk-headless:native, libxtst-dev, libxi-dev, libxt-dev, libxaw7-dev, libxrender-dev, libcups2-dev, libasound2-dev, liblcms2-dev, libxinerama-dev, libkrb5-dev, xsltproc, libpcsclite-dev, libxrandr-dev, libelf-dev, libfontconfig-dev, libfreetype-dev, libharfbuzz-dev, libffi-dev, libffi-dev:native, - zlib1g-dev:native, zlib1g-dev, libattr1-dev, libpng-dev, libjpeg-dev, libgif-dev, + zlib1g-dev:native, zlib1g-dev, libattr1-dev, libpng-dev, libjpeg-dev, libgif-dev, systemtap-sdt-dev [!powerpc !ppc64 !ppc64el !sh4 !s390x], libnss3-dev (>= 2:3.17.1), openjdk-17-jdk-headless , Build-Depends-Indep: graphviz, pandoc, diff -Nru openjdk-17-17.0.12+7/debian/copyright-generator/strip-common-licenses.sh openjdk-17-17.0.13+11/debian/copyright-generator/strip-common-licenses.sh --- openjdk-17-17.0.12+7/debian/copyright-generator/strip-common-licenses.sh 2024-03-20 22:00:09.000000000 +0000 +++ openjdk-17-17.0.13+11/debian/copyright-generator/strip-common-licenses.sh 2024-08-08 06:27:17.000000000 +0000 @@ -1,7 +1,7 @@ SOURCE_DIR=$1 VERSION=$2 for LEGAL_DIR in `find $SOURCE_DIR/src -name legal`; do - for COMMON_LICENSE in "### Apache 2.0 License" "### GPL v2" ; do + for COMMON_LICENSE in "### Apache 2.0 License" "### GPL v2" "### GPL version 3"; do for FILE in `grep -Rl "${COMMON_LICENSE}" $LEGAL_DIR`; do sed -i "/^${COMMON_LICENSE}/,/^###/{/^###/!{d}}" $FILE sed -i "s/${COMMON_LICENSE}/${COMMON_LICENSE}: Refer to the copy under \/usr\/share\/common-licenses\n/g" $FILE diff -Nru openjdk-17-17.0.12+7/debian/patches/build_gtest.patch openjdk-17-17.0.13+11/debian/patches/build_gtest.patch --- openjdk-17-17.0.12+7/debian/patches/build_gtest.patch 2024-03-20 22:00:09.000000000 +0000 +++ openjdk-17-17.0.13+11/debian/patches/build_gtest.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -Description: Add support for building with the system google test - A major portion of hotspot tests require google test. - In order to get tier1 tests passing the package should build - with the system google test. -Author: Vladimir Petko -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/openjdk-20/+bug/2012316 -Last-Update: 2023-07-20 ---- a/make/autoconf/lib-tests.m4 -+++ b/make/autoconf/lib-tests.m4 -@@ -43,6 +43,8 @@ AC_DEFUN_ONCE([LIB_TESTS_SETUP_GTEST], - AC_MSG_CHECKING([for gtest]) - if test "x${with_gtest}" = xno; then - AC_MSG_RESULT([no, disabled]) -+ elif test "x${with_gtest}" = xsystem; then -+ GTEST_FRAMEWORK_SRC=/usr/src/googletest - elif test "x${with_gtest}" = xyes; then - AC_MSG_RESULT([no, error]) - AC_MSG_ERROR([--with-gtest must have a value]) ---- a/test/hotspot/gtest/gtestMain.cpp -+++ b/test/hotspot/gtest/gtestMain.cpp -@@ -230,7 +230,9 @@ static void runUnitTestsInner(int argc, - bool is_vmassert_test = false; - bool is_othervm_test = false; - // death tests facility is used for both regular death tests, other vm and vmassert tests -- if (::testing::internal::GTEST_FLAG(internal_run_death_test).length() > 0) { -+using namespace ::testing; -+using namespace ::testing::internal; -+ if (GTEST_FLAG(internal_run_death_test).length() > 0) { - // when we execute death test, filter value equals to test name - const char* test_name = ::testing::GTEST_FLAG(filter).c_str(); - const char* const othervm_suffix = "_other_vm"; // TEST_OTHER_VM diff -Nru openjdk-17-17.0.12+7/debian/patches/googletest-version.diff openjdk-17-17.0.13+11/debian/patches/googletest-version.diff --- openjdk-17-17.0.12+7/debian/patches/googletest-version.diff 2024-03-20 22:00:09.000000000 +0000 +++ openjdk-17-17.0.13+11/debian/patches/googletest-version.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ ---- a/make/autoconf/lib-tests.m4 -+++ b/make/autoconf/lib-tests.m4 -@@ -64,16 +64,17 @@ AC_DEFUN_ONCE([LIB_TESTS_SETUP_GTEST], - # determined. :-( Instead, there are different, incorrect version - # numbers we can look for. - GTEST_VERSION_1="`$GREP GOOGLETEST_VERSION $GTEST_FRAMEWORK_SRC/CMakeLists.txt | $SED -E -e 's/set\(GOOGLETEST_VERSION (.*)\)/\1/'`" -- if test "x$GTEST_VERSION_1" != "x1.9.0"; then -- AC_MSG_ERROR([gtest at $GTEST_FRAMEWORK_SRC does not seem to be version 1.8.1]) -+ if test "x$GTEST_VERSION_1" != "x1.14.0"; then -+ AC_MSG_ERROR([gtest at $GTEST_FRAMEWORK_SRC does not seem to be version 1.14.0]) - fi - -+ # $GTEST_FRAMEWORK_SRC/configure.ac does not exist - # We cannot grep for "AC_IN*T" as a literal since then m4 will treat it as a macro - # and expand it. - # Additional [] needed to keep m4 from mangling shell constructs. - [ GTEST_VERSION_2="`$GREP -A1 ^.C_INIT $GTEST_FRAMEWORK_SRC/configure.ac | $TAIL -n 1 | $SED -E -e 's/ +\[(.*)],/\1/'`" ] -- if test "x$GTEST_VERSION_2" != "x1.8.0"; then -- AC_MSG_ERROR([gtest at $GTEST_FRAMEWORK_SRC does not seem to be version 1.8.1 B]) -+ if false && test "x$GTEST_VERSION_2" != "x1.14.0"; then -+ AC_MSG_ERROR([gtest at $GTEST_FRAMEWORK_SRC does not seem to be version 1.14.0 B]) - fi - fi - fi diff -Nru openjdk-17-17.0.12+7/debian/patches/jdk-8295111.patch openjdk-17-17.0.13+11/debian/patches/jdk-8295111.patch --- openjdk-17-17.0.12+7/debian/patches/jdk-8295111.patch 2024-06-29 06:57:46.000000000 +0000 +++ openjdk-17-17.0.13+11/debian/patches/jdk-8295111.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,92 +0,0 @@ -Applied-Upstream: 32946e1882e9b22c983cbba3c6bda3cc7295946a -From: Alexey Semenyuk -Subject: [PATCH] 8295111: dpkg appears to have problems resolving symbolically - linked native libraries -Bug: https://bugs.openjdk.org/browse/JDK-8295111 -Reviewed-by: almatvee - ---- - .../jpackage/internal/LinuxDebBundler.java | 66 ++++++++++++------- - 1 file changed, 41 insertions(+), 25 deletions(-) - ---- a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxDebBundler.java -+++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxDebBundler.java -@@ -195,6 +195,24 @@ - Map params, - LibProvidersLookup libProvidersLookup) { - -+ libProvidersLookup.setPackageLookup(file -> { -+ Path realPath = file.toRealPath(); -+ -+ try { -+ // Try the real path first as it works better on newer Ubuntu versions -+ return findProvidingPackages(realPath); -+ } catch (IOException ex) { -+ // Try the default path if differ -+ if (!realPath.toString().equals(file.toString())) { -+ return findProvidingPackages(file); -+ } else { -+ throw ex; -+ } -+ } -+ }); -+ } -+ -+ private static Stream findProvidingPackages(Path file) throws IOException { - // - // `dpkg -S` command does glob pattern lookup. If not the absolute path - // to the file is specified it might return mltiple package names. -@@ -237,32 +255,30 @@ - // 4. Arch suffix should be stripped from accepted package names. - // - -- libProvidersLookup.setPackageLookup(file -> { -- Set archPackages = new HashSet<>(); -- Set otherPackages = new HashSet<>(); -+ Set archPackages = new HashSet<>(); -+ Set otherPackages = new HashSet<>(); - -- Executor.of(TOOL_DPKG, "-S", file.toString()) -- .saveOutput(true).executeExpectSuccess() -- .getOutput().forEach(line -> { -- Matcher matcher = PACKAGE_NAME_REGEX.matcher(line); -- if (matcher.find()) { -- String name = matcher.group(1); -- if (name.endsWith(":" + DEB_ARCH)) { -- // Strip arch suffix -- name = name.substring(0, -- name.length() - (DEB_ARCH.length() + 1)); -- archPackages.add(name); -- } else { -- otherPackages.add(name); -- } -+ Executor.of(TOOL_DPKG, "-S", file.toString()) -+ .saveOutput(true).executeExpectSuccess() -+ .getOutput().forEach(line -> { -+ Matcher matcher = PACKAGE_NAME_REGEX.matcher(line); -+ if (matcher.find()) { -+ String name = matcher.group(1); -+ if (name.endsWith(":" + DEB_ARCH)) { -+ // Strip arch suffix -+ name = name.substring(0, -+ name.length() - (DEB_ARCH.length() + 1)); -+ archPackages.add(name); -+ } else { -+ otherPackages.add(name); - } -- }); -+ } -+ }); - -- if (!archPackages.isEmpty()) { -- return archPackages.stream(); -- } -- return otherPackages.stream(); -- }); -+ if (!archPackages.isEmpty()) { -+ return archPackages.stream(); -+ } -+ return otherPackages.stream(); - } - - @Override diff -Nru openjdk-17-17.0.12+7/debian/patches/jdk-8325567.patch openjdk-17-17.0.13+11/debian/patches/jdk-8325567.patch --- openjdk-17-17.0.12+7/debian/patches/jdk-8325567.patch 2024-06-29 06:57:46.000000000 +0000 +++ openjdk-17-17.0.13+11/debian/patches/jdk-8325567.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -Origin: commit,262747094670b00ac63463a059074afa9b81d8a4 -From: Elif Aslan -Date: Fri, 8 Mar 2024 22:09:18 +0000 -Subject: [PATCH] 8325567: jspawnhelper without args fails with segfault -Bug: https://bugs.openjdk.org/browse/JDK-8325567 -Co-authored-by: Vladimir Petko -Reviewed-by: eastigeevich, rriggs, shade, vpetko ---- - .../unix/native/jspawnhelper/jspawnhelper.c | 5 ++ - .../ProcessBuilder/JspawnhelperWarnings.java | 57 +++++++++++++++++++ - 2 files changed, 62 insertions(+) - create mode 100644 test/jdk/java/lang/ProcessBuilder/JspawnhelperWarnings.java - ---- a/src/java.base/unix/native/jspawnhelper/jspawnhelper.c -+++ b/src/java.base/unix/native/jspawnhelper/jspawnhelper.c -@@ -62,6 +62,7 @@ - fprintf(stdout, "only be run as the result of a call to\n"); - fprintf(stdout, "ProcessBuilder.start() or Runtime.exec() in a java "); - fprintf(stdout, "application\n"); -+ fflush(stdout); - _exit(1); - } - -@@ -142,6 +143,10 @@ - /* argv[1] contains the fd number to read all the child info */ - int r, fdinr, fdinw, fdout; - -+ if (argc != 2) { -+ shutItDown(); -+ } -+ - #ifdef DEBUG - jtregSimulateCrash(0, 4); - #endif diff -Nru openjdk-17-17.0.12+7/debian/patches/jdk-8334895-proposed.patch openjdk-17-17.0.13+11/debian/patches/jdk-8334895-proposed.patch --- openjdk-17-17.0.12+7/debian/patches/jdk-8334895-proposed.patch 2024-07-20 08:43:54.000000000 +0000 +++ openjdk-17-17.0.13+11/debian/patches/jdk-8334895-proposed.patch 2024-08-08 06:27:17.000000000 +0000 @@ -1,7 +1,7 @@ Description: set default compatible cds alignment to auto for arm64 ARM64 requires cds alignment option to be enabled if CDS is enabled. Setting it to true will enable the option even if CDS is disabled - causing a configuration error. Setting option to auto allows to + causing a configuration error. Setting option to auto allows one to enable it only when CDS is enabled. Author: Vladimir Petko Bug: https://bugs.openjdk.org/browse/JDK-8334895 diff -Nru openjdk-17-17.0.12+7/debian/patches/series openjdk-17-17.0.13+11/debian/patches/series --- openjdk-17-17.0.12+7/debian/patches/series 2024-07-20 08:43:54.000000000 +0000 +++ openjdk-17-17.0.13+11/debian/patches/series 2024-09-09 13:48:15.000000000 +0000 @@ -29,7 +29,6 @@ mips.diff #nspr+nss-headers.diff 8314491-jexec.patch -build_gtest.patch update-assertion-for-armhf.patch misalign-pointer-for-armhf.patch log-generated-classes-test.patch @@ -37,11 +36,8 @@ ldap-timeout-test-use-ip.patch test-use-ip-address.patch loong64-autoconf-config.diff -googletest-version.diff jdk-8307977-proposed.patch -jdk-8295111.patch jdk-8334502-proposed.patch jdk-8334895-proposed.patch -jdk-8325567.patch jdk-8336529-proposed.patch jdk-8312488.patch diff -Nru openjdk-17-17.0.12+7/debian/rules openjdk-17-17.0.13+11/debian/rules --- openjdk-17-17.0.12+7/debian/rules 2024-07-30 06:41:57.000000000 +0000 +++ openjdk-17-17.0.13+11/debian/rules 2024-10-17 08:58:43.000000000 +0000 @@ -384,14 +384,16 @@ CONFIGURE_ARGS += --disable-nss endif -ifeq ($(with_systemtap),yes) - CONFIGURE_ARGS += --enable-systemtap --with-abs-install-dir=/$(basedir) -endif - COMMON_CONFIGURE_ARGS = DEFAULT_CONFIGURE_ARGS = ZERO_CONFIGURE_ARGS = +# S390x does not support dtrace probes +# https://github.com/openjdk/jdk/pull/13228 +ifeq (,$(filter $(DEB_HOST_ARCH), powerpc ppc64 ppc64el s390x)) + COMMON_CONFIGURE_ARGS += --enable-dtrace +endif + COMMON_CONFIGURE_ARGS += --with-jni-libpath=/usr/lib/$(DEB_HOST_MULTIARCH)/jni:/lib/$(DEB_HOST_MULTIARCH):/usr/lib/$(DEB_HOST_MULTIARCH):/usr/lib/jni:/lib:/usr/lib # FIXME: --with-jvm-variants=server,zero not supported upstream @@ -715,9 +717,7 @@ bd_nss = libnss3-dev (>= 2:3.17.1), endif endif -ifeq ($(with_systemtap),yes) - bd_systemtap = systemtap-sdt-dev [!sh4], -endif +bd_systemtap = systemtap-sdt-dev [!powerpc !ppc64 !ppc64el !sh4 !s390x], ifeq (,$(filter $(distrel),jessie stretch buster precise trusty xenial bionic focal groovy)) with_debugedit = yes @@ -1837,11 +1837,6 @@ mkdir -p $(d_jrehl)/usr/lib/debug/usr/lib/jvm/$(jdirname) ln -sf $(jdirname) $(d_jrehl)/usr/lib/debug/usr/lib/jvm/$(jdiralias) -ifeq ($(with_systemtap),yes FIXME) - : # systemtap support - mkdir -p $(d_jrehl)/usr/share/systemtap/tapset - cp -p build/tapset/hotspot.stp $(d_jrehl)/usr/share/systemtap/tapset/ -endif : # install lintian overrides for FILE in debian/*.overrides; do \ @@ -1866,7 +1861,7 @@ cp -a $$i $(d_doc)/usr/share/doc/$(p_jrehl)/; \ ln -sf ../$(p_jrehl)/$$b $(d_doc)/usr/share/doc/$(p_doc)/$$b; \ done - rm -v $(d_doc)/usr/share/doc/$(p_jrehl)/api/script-dir/{jquery-3.6.1.min.js,jquery-ui.min.css,jquery-ui.min.js} + rm -v $(d_doc)/usr/share/doc/$(p_jrehl)/api/script-dir/{jquery-3.7.1.min.js,jquery-ui.min.css,jquery-ui.min.js} dh_link -p$(p_doc) \ /usr/share/javascript/jquery/jquery.min.js \ /usr/share/doc/$(p_jrehl)/api/script-dir/jquery-3.6.1.min.js \ @@ -1973,7 +1968,7 @@ dh_builddeb -a $(nodemo) $(nojrez) #$(bd_options) git_project = jdk17u -git_tag = jdk-17.0.12+7 +git_tag = jdk-17.0.13+11 package_version = $(subst jdk-,,$(git_tag)) package_version = $(shell echo $(PKGVERSION) | sed 's/-[^-][^-]*$$//') ifneq ($(is_upstream_release),yes) diff -Nru openjdk-17-17.0.12+7/debian/source/lintian-overrides openjdk-17-17.0.13+11/debian/source/lintian-overrides --- openjdk-17-17.0.12+7/debian/source/lintian-overrides 2024-03-20 22:00:09.000000000 +0000 +++ openjdk-17-17.0.13+11/debian/source/lintian-overrides 2024-08-08 06:27:17.000000000 +0000 @@ -1,2 +1,24 @@ # parts of the test suite, not installed openjdk-17 source: source-is-missing + +# openjdk packages use old standards version as they need to support +# backports +openjdk-17 source: newer-standards-version +openjdk-17 source: uses-debhelper-compat-file +openjdk-17 source: package-uses-old-debhelper-compat-version + +# suppress warnings about experimental patches +openjdk-17 source: patch-file-present-but-not-mentioned-in-series + +# jtreg test suite contains pre-built jars +openjdk-17 source: source-contains-prebuilt-java-object + +# upstream code formatting +openjdk-17 source: very-long-line-length-in-source-file + +# false positive, jtreg tests contain example/ directories +openjdk-17 source: package-does-not-install-examples + +# chromium and firefox snaps are unable to load scripts from /usr/share/javascript +# LP: 2032992 +openjdk-17 source: source-contains-prebuilt-javascript-object diff -Nru openjdk-17-17.0.12+7/debian/tests/jtreg-autopkgtest.in openjdk-17-17.0.13+11/debian/tests/jtreg-autopkgtest.in --- openjdk-17-17.0.12+7/debian/tests/jtreg-autopkgtest.in 2024-07-20 08:43:54.000000000 +0000 +++ openjdk-17-17.0.13+11/debian/tests/jtreg-autopkgtest.in 2024-08-08 06:36:30.000000000 +0000 @@ -103,7 +103,7 @@ -retain:none \ -ignore:quiet \ -agentvm \ - -timeout:5 \ + -timeout:10 \ -workDir:"${jtwork_dir}" \ -reportDir:"${report_dir}" \ -jdk:${JDK_TO_TEST} \ diff -Nru openjdk-17-17.0.12+7/debian/tests/jtreg-autopkgtest.sh openjdk-17-17.0.13+11/debian/tests/jtreg-autopkgtest.sh --- openjdk-17-17.0.12+7/debian/tests/jtreg-autopkgtest.sh 2024-07-20 08:43:54.000000000 +0000 +++ openjdk-17-17.0.13+11/debian/tests/jtreg-autopkgtest.sh 2024-08-08 06:36:30.000000000 +0000 @@ -103,7 +103,7 @@ -retain:none \ -ignore:quiet \ -agentvm \ - -timeout:5 \ + -timeout:10 \ -workDir:"${jtwork_dir}" \ -reportDir:"${report_dir}" \ -jdk:${JDK_TO_TEST} \ diff -Nru openjdk-17-17.0.12+7/debian/tests/problems.csv openjdk-17-17.0.13+11/debian/tests/problems.csv --- openjdk-17-17.0.12+7/debian/tests/problems.csv 2024-07-20 08:43:54.000000000 +0000 +++ openjdk-17-17.0.13+11/debian/tests/problems.csv 2024-10-10 12:16:00.000000000 +0000 @@ -13,7 +13,7 @@ FAILED: java/foreign/TestUpcallHighArity.java,,Ignore test failure in the preview api,:openjdk-21,:i386,:release-all FAILED: java/foreign/TestUpcallStructScope.java,,Ignore test failure in the preview api,:openjdk-21,:i386,:release-all FAILED: java/io/File/createTempFile/TargetDirectory.java,JDK-8166162,Container issue,:openjdk-21:openjdk-22,:arch-all,:release-all -FAILED: java/io/File/GetXSpace.java,,"Container issue, disk space size exceeds 32 bit integer",:openjdk-17:openjdk-21:openjdk-22,i386,:release-all +FAILED: java/io/File/GetXSpace.java,,"Container issue, disk space size exceeds 32 bit integer",:openjdk-17:openjdk-21:openjdk-22,:i386:armhf,:release-all FAILED: java/nio/channels/FileChannel/directio/DirectIOTest.java,JDK-8166162,Container issue,:openjdk-lts:openjdk-11::openjdk-17:openjdk-21:openjdk-22,:arch-all,:release-all FAILED: java/nio/channels/FileChannel/directio/PreadDirect.java,JDK-8166162,Container issue,:openjdk-lts:openjdk-11::openjdk-17:openjdk-21:openjdk-22,:arch-all,:release-all FAILED: java/nio/channels/FileChannel/directio/PwriteDirect.java,JDK-8166162,Container issue,:openjdk-lts:openjdk-11::openjdk-17:openjdk-21:openjdk-22,:arch-all,:release-all @@ -33,9 +33,9 @@ FAILED: java/nio/file/Files/Misc.java,JDK-8166162,Container issue,:openjdk-lts:openjdk-11::openjdk-17:openjdk-21:openjdk-22,:arch-all,:release-all FAILED: java/nio/file/Files/TemporaryFiles.java,JDK-8166162,Container issue,:openjdk-lts:openjdk-11::openjdk-17:openjdk-21:openjdk-22,:arch-all,:release-all FAILED: java/nio/file/FileStore/Basic.java,JDK-8166162,Container issue,:openjdk-lts:openjdk-11::openjdk-17:openjdk-21:openjdk-22,:arch-all,:release-all -FAILED: runtime/cds/appcds/jcmd/JCmdTestDynamicDump.java,,flaky test (?) existing comment,:openjdk-17,i386:arm64:amd64,:release-all +FAILED: runtime/cds/appcds/jcmd/JCmdTestDynamicDump.java,,flaky test (?) existing comment,:openjdk-17,:arch-all,:release-all FAILED: runtime/cds/appcds/jcmd/JCmdTestFileSafety.java,,flaky test (?) existing comment,:openjdk-17,i386:arm64:amd64:ppc64el,:release-all -FAILED: runtime/cds/appcds/jcmd/JCmdTestStaticDump.java,,flaky test (?) existing comment,:openjdk-17,ppc64el,:release-all +FAILED: runtime/cds/appcds/jcmd/JCmdTestStaticDump.java,,flaky test (?) existing comment,:openjdk-17,:arch-all,:release-all FAILED: runtime/ErrorHandling/MachCodeFramesInErrorFile.java,,java.lang.InternalError: a fault occurred in a recent unsafe memory access operation in compiled Java code at java.base/java.lang.Long.toHexString(Long.java:309) at,:openjdk-17:openjdk-21,armhf,:release-all FAILED: runtime/jni/nativeStack/TestNativeStack.java,JDK-8312016,"Backport fix (do not add patch, the fix just disables the test)",:openjdk-lts:openjdk-11:openjdk-17,armhf,:release-all FAILED: runtime/LoadClass/LongBCP.java,JDK-8166162,Container issue,:openjdk-lts:openjdk-11:openjdk-17:openjdk-21:openjdk-22,:arch-all,:release-all @@ -61,8 +61,25 @@ FAILED: jdk/javadoc/doclet/testWarnings/TestWarnings.java,,tests failing due to disable-doclint-by-default.diff (reproducible build maintainer patch),:openjdk-lts:openjdk-11,:arch-all,:release-all FAILED: jdk/javadoc/tool/doclint/DocLintTest.java,,tests failing due to disable-doclint-by-default.diff (reproducible build maintainer patch),:openjdk-lts:openjdk-11,:arch-all,:release-all FAILED: jdk/javadoc/tool/modules/Modules.java,,tests failing due to disable-doclint-by-default.diff (reproducible build maintainer patch),:openjdk-lts:openjdk-11,:arch-all,:release-all -FAILED: sun/security/ec/TestEC.java,,"New failure in CI, passes locally",:openjdk-lts:openjdk-11,:amd64,:release-all +FAILED: sun/security/ec/TestEC.java,,"New failure in CI, passes locally",:openjdk-lts:openjdk-11,:amd64:arm64,:release-all FAILED: runtime/NMT/SafepointPollingPages.java,,ThreadLocalHandshakes not yet supported on this platform. Disable test,:openjdk-lts:openjdk-11,:armhf,:release-all FAILED: serviceability/attach/ConcAttachTest.java,,java.lang.RuntimeException: Process is still alive. Can't get its output.,:openjdk-lts:openjdk-11,:armhf,:release-all FAILED: serviceability/attach/RemovingUnixDomainSocketTest.java,,java.lang.RuntimeException: Process is still alive. Can't get its output.,:openjdk-lts:openjdk-11,:armhf,:release-all FAILED: runtime/cds/appcds/jcmd/JCmdTestStaticDump.java,,Lingered App not found (CI),:openjdk-17,:amd64,:release-all +FAILED: runtime/appcds/sharedStrings/LargePages.java,, passes locally. class not found JarBuilder. I have seen it several times - the class file that is being produced in compilation step can not be read from disk in CI. ,:openjdk-lts:openjdk-11,:arm64,:focal +FAILED: runtime/appcds/sharedStrings/IncompatibleOptions.java,, passes locally. NoClassDefFound: TestCommon. Same as above.,:openjdk-lts:openjdk-11,:arm64,:focal +FAILED: java/foreign/StdLibTest.java,, asserts due to the invalid structure size. Ignore as this is a preview API and the issue does not occur in openjdk-22. I will add it to the problemlist.,:openjdk-21,:armhf,:release-all +FAILED: java/foreign/TestIllegalLink.java,, asserts due to the invalid structure size. Ignore as this is a preview API and the issue does not occur in openjdk-22. I will add it to the problemlist.,:openjdk-21,:armhf,:release-all +FAILED: java/foreign/TestDowncallStack.java,, asserts due to the invalid structure size. Ignore as this is a preview API and the issue does not occur in openjdk-22. I will add it to the problemlist.,:openjdk-21,:armhf,:release-all +FAILED: java/foreign/TestDowncallScope.java,, asserts due to the invalid structure size. Ignore as this is a preview API and the issue does not occur in openjdk-22. I will add it to the problemlist.,:openjdk-21,:armhf,:release-all +FAILED: java/foreign/TestSegments.java,, asserts due to the invalid structure size. Ignore as this is a preview API and the issue does not occur in openjdk-22. I will add it to the problemlist.,:openjdk-21,:armhf,:release-all +FAILED: java/foreign/TestLinker.java,, asserts due to the invalid structure size. Ignore as this is a preview API and the issue does not occur in openjdk-22. I will add it to the problemlist.,:openjdk-21,:armhf,:release-all +FAILED: java/foreign/TestAddressDereference.java,, asserts due to the invalid structure size. Ignore as this is a preview API and the issue does not occur in openjdk-22. I will add it to the problemlist.,:openjdk-21,:armhf,:release-all +FAILED: java/foreign/TestUpcallHighArity.java,, asserts due to the invalid structure size. Ignore as this is a preview API and the issue does not occur in openjdk-22. I will add it to the problemlist.,:openjdk-21,:armhf,:release-all +FAILED: java/foreign/TestUpcallStructScope.java,, asserts due to the invalid structure size. Ignore as this is a preview API and the issue does not occur in openjdk-22. I will add it to the problemlist.,:openjdk-21,:armhf,:release-all +FAILED: java/foreign/TestUpcallScope.java,, asserts due to the invalid structure size. Ignore as this is a preview API and the issue does not occur in openjdk-22. I will add it to the problemlist.,:openjdk-21,:armhf,:release-all +FAILED: java/foreign/TestUpcallAsync.java,, asserts due to the invalid structure size. Ignore as this is a preview API and the issue does not occur in openjdk-22. I will add it to the problemlist.,:openjdk-21,:armhf,:release-all +FAILED: java/foreign/TestUpcallStack.java,, asserts due to the invalid structure size. Ignore as this is a preview API and the issue does not occur in openjdk-22. I will add it to the problemlist.,:openjdk-21,:armhf,:release-all +FAILED: java/foreign/TestVarArgs.java,, asserts due to the invalid structure size. Ignore as this is a preview API and the issue does not occur in openjdk-22. I will add it to the problemlist.,:openjdk-21,:armhf,:release-all +FAILED: runtime/os/TestTrimNative.java#trimNative,, java.lang.RuntimeException: We found fewer (periodic) trim lines in UL log than expected (expected at least 13 found 11). This looks like a flaky test - it asserts number of lines from the periodic trimmer e.g. src/hotspot/share/runtime/trimNativeHeap.hpp:56 which causes the test to fail due to the slow VM. Test passes locally.,:openjdk-21,:armhf,:release-all +FAILED: jdk/sun/security/util/Debug/DebugOptions.java,JDK-8339713,Stack overflow error on 32-bit platforms,:openjdk-21:openjdk-23,:armhf:i386,:release-all diff -Nru openjdk-17-17.0.12+7/doc/building.html openjdk-17-17.0.13+11/doc/building.html --- openjdk-17-17.0.12+7/doc/building.html 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/doc/building.html 2024-10-10 14:01:59.000000000 +0000 @@ -514,10 +514,10 @@

Running Tests

Most of the JDK tests are using the JTReg test framework. Make sure that your configuration knows where to find your installation of JTReg. If this is not picked up automatically, use the --with-jtreg=<path to jtreg home> option to point to the JTReg framework. Note that this option should point to the JTReg home, i.e. the top directory, containing lib/jtreg.jar etc.

The Adoption Group provides recent builds of jtreg here. Download the latest .tar.gz file, unpack it, and point --with-jtreg to the jtreg directory that you just unpacked.

-

Building of Hotspot Gtest suite requires the source code of Google Test framework. The top directory, which contains both googletest and googlemock directories, should be specified via --with-gtest. The supported version of Google Test is 1.8.1, whose source code can be obtained:

+

Building of Hotspot Gtest suite requires the source code of Google Test framework. The top directory, which contains both googletest and googlemock directories, should be specified via --with-gtest. The supported version of Google Test is 1.13.0, whose source code can be obtained:

    -
  • by downloading and unpacking the source bundle from here
  • -
  • or by checking out release-1.8.1 tag of googletest project: git clone -b release-1.8.1 https://github.com/google/googletest
  • +
  • by downloading and unpacking the source bundle from here
  • +
  • or by checking out v1.13.0 tag of googletest project: git clone -b v1.13.0 https://github.com/google/googletest

To execute the most basic tests (tier 1), use:

make run-test-tier1
diff -Nru openjdk-17-17.0.12+7/doc/building.md openjdk-17-17.0.13+11/doc/building.md --- openjdk-17-17.0.12+7/doc/building.md 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/doc/building.md 2024-10-10 14:01:59.000000000 +0000 @@ -852,13 +852,14 @@ Download the latest `.tar.gz` file, unpack it, and point `--with-jtreg` to the `jtreg` directory that you just unpacked. -Building of Hotspot Gtest suite requires the source code of Google Test framework. -The top directory, which contains both `googletest` and `googlemock` -directories, should be specified via `--with-gtest`. -The supported version of Google Test is 1.8.1, whose source code can be obtained: +Building of Hotspot Gtest suite requires the source code of Google +Test framework. The top directory, which contains both `googletest` +and `googlemock` directories, should be specified via `--with-gtest`. +The minimum supported version of Google Test is 1.13.0, whose source +code can be obtained: - * by downloading and unpacking the source bundle from [here](https://github.com/google/googletest/releases/tag/release-1.8.1) - * or by checking out `release-1.8.1` tag of `googletest` project: `git clone -b release-1.8.1 https://github.com/google/googletest` + * by downloading and unpacking the source bundle from [here](https://github.com/google/googletest/releases/tag/v1.13.0) + * or by checking out `v1.13.0` tag of `googletest` project: `git clone -b v1.13.0 https://github.com/google/googletest` To execute the most basic tests (tier 1), use: ``` diff -Nru openjdk-17-17.0.12+7/doc/testing.html openjdk-17-17.0.13+11/doc/testing.html --- openjdk-17-17.0.12+7/doc/testing.html 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/doc/testing.html 2024-10-10 14:01:59.000000000 +0000 @@ -67,7 +67,7 @@

Test selection

All functionality is available using the test make target. In this use case, the test or tests to be executed is controlled using the TEST variable. To speed up subsequent test runs with no source code changes, test-only can be used instead, which do not depend on the source and test image build.

For some common top-level tests, direct make targets have been generated. This includes all JTReg test groups, the hotspot gtest, and custom tests (if present). This means that make test-tier1 is equivalent to make test TEST="tier1", but the latter is more tab-completion friendly. For more complex test runs, the test TEST="x" solution needs to be used.

-

The test specifications given in TEST is parsed into fully qualified test descriptors, which clearly and unambigously show which tests will be run. As an example, :tier1 will expand to jtreg:$(TOPDIR)/test/hotspot/jtreg:tier1 jtreg:$(TOPDIR)/test/jdk:tier1 jtreg:$(TOPDIR)/test/langtools:tier1 jtreg:$(TOPDIR)/test/nashorn:tier1 jtreg:$(TOPDIR)/test/jaxp:tier1. You can always submit a list of fully qualified test descriptors in the TEST variable if you want to shortcut the parser.

+

The test specifications given in TEST is parsed into fully qualified test descriptors, which clearly and unambigously show which tests will be run. As an example, :tier1 will expand to include all subcomponent test directories that define `tier1`, for example: jtreg:$(TOPDIR)/test/hotspot/jtreg:tier1 jtreg:$(TOPDIR)/test/jdk:tier1 jtreg:$(TOPDIR)/test/langtools:tier1 .... You can always submit a list of fully qualified test descriptors in the TEST variable if you want to shortcut the parser.

Common Test Groups

Ideally, all tests are run for every change but this may not be practical due to the limited testing resources, the scope of the change, etc.

The source tree currently defines a few common test groups in the relevant TEST.groups files. There are test groups that cover a specific component, for example hotspot_gc. It is a good idea to look into TEST.groups files to get a sense what tests are relevant to a particular JDK component.

diff -Nru openjdk-17-17.0.12+7/doc/testing.md openjdk-17-17.0.13+11/doc/testing.md --- openjdk-17-17.0.12+7/doc/testing.md 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/doc/testing.md 2024-10-10 14:01:59.000000000 +0000 @@ -58,11 +58,11 @@ The test specifications given in `TEST` is parsed into fully qualified test descriptors, which clearly and unambigously show which tests will be run. As an -example, `:tier1` will expand to `jtreg:$(TOPDIR)/test/hotspot/jtreg:tier1 -jtreg:$(TOPDIR)/test/jdk:tier1 jtreg:$(TOPDIR)/test/langtools:tier1 -jtreg:$(TOPDIR)/test/nashorn:tier1 jtreg:$(TOPDIR)/test/jaxp:tier1`. You can -always submit a list of fully qualified test descriptors in the `TEST` variable -if you want to shortcut the parser. +example, `:tier1` will expand to include all subcomponent test directories +that define `tier1`, for example: `jtreg:$(TOPDIR)/test/hotspot/jtreg:tier1 +jtreg:$(TOPDIR)/test/jdk:tier1 jtreg:$(TOPDIR)/test/langtools:tier1 ...`. You +can always submit a list of fully qualified test descriptors in the `TEST` +variable if you want to shortcut the parser. ### Common Test Groups diff -Nru openjdk-17-17.0.12+7/make/autoconf/configure.ac openjdk-17-17.0.13+11/make/autoconf/configure.ac --- openjdk-17-17.0.12+7/make/autoconf/configure.ac 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/make/autoconf/configure.ac 2024-10-10 14:01:59.000000000 +0000 @@ -300,9 +300,11 @@ # After AC_OUTPUT, we need to do final work CUSTOM_CONFIG_OUTPUT_GENERATED_HOOK -BASIC_POST_CONFIG_OUTPUT # Finally output some useful information to the user HELP_PRINT_SUMMARY_AND_WARNINGS CUSTOM_SUMMARY_AND_WARNINGS_HOOK HELP_REPEAT_WARNINGS + +# All output is done. Do the post-config output management. +BASIC_POST_CONFIG_OUTPUT diff -Nru openjdk-17-17.0.12+7/make/autoconf/flags-cflags.m4 openjdk-17-17.0.13+11/make/autoconf/flags-cflags.m4 --- openjdk-17-17.0.12+7/make/autoconf/flags-cflags.m4 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/make/autoconf/flags-cflags.m4 2024-10-10 14:01:59.000000000 +0000 @@ -419,7 +419,7 @@ [ #### OS DEFINES, these should be independent on toolchain if test "x$OPENJDK_TARGET_OS" = xlinux; then - CFLAGS_OS_DEF_JVM="-DLINUX" + CFLAGS_OS_DEF_JVM="-DLINUX -D_FILE_OFFSET_BITS=64" CFLAGS_OS_DEF_JDK="-D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE" elif test "x$OPENJDK_TARGET_OS" = xmacosx; then CFLAGS_OS_DEF_JVM="-D_ALLBSD_SOURCE -D_DARWIN_C_SOURCE -D_XOPEN_SOURCE" diff -Nru openjdk-17-17.0.12+7/make/autoconf/lib-tests.m4 openjdk-17-17.0.13+11/make/autoconf/lib-tests.m4 --- openjdk-17-17.0.12+7/make/autoconf/lib-tests.m4 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/make/autoconf/lib-tests.m4 2024-10-10 14:01:59.000000000 +0000 @@ -27,8 +27,9 @@ # Setup libraries and functionalities needed to test the JDK. ################################################################################ -# Minimum supported version +# Minimum supported versions JTREG_MINIMUM_VERSION=7.3.1 +GTEST_MINIMUM_VERSION=1.13.0 ############################################################################### # @@ -58,20 +59,13 @@ AC_MSG_RESULT([$GTEST_FRAMEWORK_SRC]) UTIL_FIXUP_PATH([GTEST_FRAMEWORK_SRC]) - # Try to verify version. We require 1.8.1, but this can not be directly - # determined. :-( Instead, there are different, incorrect version - # numbers we can look for. - GTEST_VERSION_1="`$GREP GOOGLETEST_VERSION $GTEST_FRAMEWORK_SRC/CMakeLists.txt | $SED -E -e 's/set\(GOOGLETEST_VERSION (.*)\)/\1/'`" - if test "x$GTEST_VERSION_1" != "x1.9.0"; then - AC_MSG_ERROR([gtest at $GTEST_FRAMEWORK_SRC does not seem to be version 1.8.1]) - fi - - # We cannot grep for "AC_IN*T" as a literal since then m4 will treat it as a macro - # and expand it. - # Additional [] needed to keep m4 from mangling shell constructs. - [ GTEST_VERSION_2="`$GREP -A1 ^.C_INIT $GTEST_FRAMEWORK_SRC/configure.ac | $TAIL -n 1 | $SED -E -e 's/ +\[(.*)],/\1/'`" ] - if test "x$GTEST_VERSION_2" != "x1.8.0"; then - AC_MSG_ERROR([gtest at $GTEST_FRAMEWORK_SRC does not seem to be version 1.8.1 B]) + # Verify that the version is the required one. + # This is a simplified version of TOOLCHAIN_CHECK_COMPILER_VERSION + gtest_version="`$GREP GOOGLETEST_VERSION $GTEST_FRAMEWORK_SRC/CMakeLists.txt | $SED -E -e 's/set\(GOOGLETEST_VERSION (.*)\)/\1/'`" + comparable_actual_version=`$AWK -F. '{ printf("%05d%05d%05d%05d\n", [$]1, [$]2, [$]3, [$]4) }' <<< "$gtest_version"` + comparable_minimum_version=`$AWK -F. '{ printf("%05d%05d%05d%05d\n", [$]1, [$]2, [$]3, [$]4) }' <<< "$GTEST_MINIMUM_VERSION"` + if test $comparable_actual_version -lt $comparable_minimum_version ; then + AC_MSG_ERROR([gtest version is too old, at least version $GTEST_MINIMUM_VERSION is required]) fi fi fi diff -Nru openjdk-17-17.0.12+7/make/conf/github-actions.conf openjdk-17-17.0.13+11/make/conf/github-actions.conf --- openjdk-17-17.0.12+7/make/conf/github-actions.conf 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/make/conf/github-actions.conf 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2022, 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 @@ -25,17 +25,21 @@ # Versions and download locations for dependencies used by GitHub Actions (GHA) -GTEST_VERSION=1.8.1 +GTEST_VERSION=1.13.0 JTREG_VERSION=7.3.1+1 LINUX_X64_BOOT_JDK_EXT=tar.gz LINUX_X64_BOOT_JDK_URL=https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.11%2B9/OpenJDK17U-jdk_x64_linux_hotspot_17.0.11_9.tar.gz LINUX_X64_BOOT_JDK_SHA256=aa7fb6bb342319d227a838af5c363bfa1b4a670c209372f9e6585bd79da6220c -WINDOWS_X64_BOOT_JDK_EXT=zip -WINDOWS_X64_BOOT_JDK_URL=https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.11%2B9/OpenJDK17U-jdk_x64_windows_hotspot_17.0.11_9.zip -WINDOWS_X64_BOOT_JDK_SHA256=fdd6664d4131370398fbc8bfbb7b46dbfec4a22a090a511fe5c379dae188c390 - MACOS_X64_BOOT_JDK_EXT=tar.gz MACOS_X64_BOOT_JDK_URL=https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.11%2B9/OpenJDK17U-jdk_x64_mac_hotspot_17.0.11_9.tar.gz MACOS_X64_BOOT_JDK_SHA256=f8b96724618f4df557c47f11048d1084e98ed3eb87f0dbd5b84f768a80c3348e + +MACOS_AARCH64_BOOT_JDK_EXT=tar.gz +MACOS_AARCH64_BOOT_JDK_URL=https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.11%2B9/OpenJDK17U-jdk_aarch64_mac_hotspot_17.0.11_9.tar.gz +MACOS_AARCH64_BOOT_JDK_SHA256=09a162c58dd801f7cfacd87e99703ed11fb439adc71cfa14ceb2d3194eaca01c + +WINDOWS_X64_BOOT_JDK_EXT=zip +WINDOWS_X64_BOOT_JDK_URL=https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.11%2B9/OpenJDK17U-jdk_x64_windows_hotspot_17.0.11_9.zip +WINDOWS_X64_BOOT_JDK_SHA256=fdd6664d4131370398fbc8bfbb7b46dbfec4a22a090a511fe5c379dae188c390 diff -Nru openjdk-17-17.0.12+7/make/conf/jib-profiles.js openjdk-17-17.0.13+11/make/conf/jib-profiles.js --- openjdk-17-17.0.12+7/make/conf/jib-profiles.js 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/make/conf/jib-profiles.js 2024-10-10 14:01:59.000000000 +0000 @@ -1242,7 +1242,7 @@ gtest: { organization: common.organization, ext: "tar.gz", - revision: "1.8.1" + revision: "1.13.0+1.0" }, }; diff -Nru openjdk-17-17.0.12+7/make/conf/version-numbers.conf openjdk-17-17.0.13+11/make/conf/version-numbers.conf --- openjdk-17-17.0.12+7/make/conf/version-numbers.conf 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/make/conf/version-numbers.conf 2024-10-10 14:01:59.000000000 +0000 @@ -28,12 +28,12 @@ DEFAULT_VERSION_FEATURE=17 DEFAULT_VERSION_INTERIM=0 -DEFAULT_VERSION_UPDATE=12 +DEFAULT_VERSION_UPDATE=13 DEFAULT_VERSION_PATCH=0 DEFAULT_VERSION_EXTRA1=0 DEFAULT_VERSION_EXTRA2=0 DEFAULT_VERSION_EXTRA3=0 -DEFAULT_VERSION_DATE=2024-07-16 +DEFAULT_VERSION_DATE=2024-10-15 DEFAULT_VERSION_CLASSFILE_MAJOR=61 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`" DEFAULT_VERSION_CLASSFILE_MINOR=0 DEFAULT_VERSION_DOCS_API_SINCE=11 diff -Nru openjdk-17-17.0.12+7/make/data/cacerts/ssltlsrootecc2022 openjdk-17-17.0.13+11/make/data/cacerts/ssltlsrootecc2022 --- openjdk-17-17.0.12+7/make/data/cacerts/ssltlsrootecc2022 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.13+11/make/data/cacerts/ssltlsrootecc2022 2024-10-10 14:01:59.000000000 +0000 @@ -0,0 +1,21 @@ +Owner: CN=SSL.com TLS ECC Root CA 2022, O=SSL Corporation, C=US +Issuer: CN=SSL.com TLS ECC Root CA 2022, O=SSL Corporation, C=US +Serial number: 1403f5abfb378b17405be243b2a5d1c4 +Valid from: Thu Aug 25 16:33:48 GMT 2022 until: Sun Aug 19 16:33:47 GMT 2046 +Signature algorithm name: SHA384withECDSA +Subject Public Key Algorithm: 384-bit EC (secp384r1) key +Version: 3 +-----BEGIN CERTIFICATE----- +MIICOjCCAcCgAwIBAgIQFAP1q/s3ixdAW+JDsqXRxDAKBggqhkjOPQQDAzBOMQsw +CQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxT +U0wuY29tIFRMUyBFQ0MgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzM0OFoXDTQ2 +MDgxOTE2MzM0N1owTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jwb3Jh +dGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgRUNDIFJvb3QgQ0EgMjAyMjB2MBAG +ByqGSM49AgEGBSuBBAAiA2IABEUpNXP6wrgjzhR9qLFNoFs27iosU8NgCTWyJGYm +acCzldZdkkAZDsalE3D07xJRKF3nzL35PIXBz5SQySvOkkJYWWf9lCcQZIxPBLFN +SeR7T5v15wj4A4j3p8OSSxlUgaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSME +GDAWgBSJjy+j6CugFFR781a4Jl9nOAuc0DAdBgNVHQ4EFgQUiY8vo+groBRUe/NW +uCZfZzgLnNAwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2gAMGUCMFXjIlbp +15IkWE8elDIPDAI2wv2sdDJO4fscgIijzPvX6yv/N33w7deedWo1dlJF4AIxAMeN +b0Igj762TVntd00pxCAgRWSGOlDGxK0tk/UYfXLtqc/ErFc2KAhl3zx5Zn6g6g== +-----END CERTIFICATE----- diff -Nru openjdk-17-17.0.12+7/make/data/cacerts/ssltlsrootrsa2022 openjdk-17-17.0.13+11/make/data/cacerts/ssltlsrootrsa2022 --- openjdk-17-17.0.12+7/make/data/cacerts/ssltlsrootrsa2022 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.13+11/make/data/cacerts/ssltlsrootrsa2022 2024-10-10 14:01:59.000000000 +0000 @@ -0,0 +1,39 @@ +Owner: CN=SSL.com TLS RSA Root CA 2022, O=SSL Corporation, C=US +Issuer: CN=SSL.com TLS RSA Root CA 2022, O=SSL Corporation, C=US +Serial number: 6fbedaad73bd0840e28b4dbed4f75b91 +Valid from: Thu Aug 25 16:34:22 GMT 2022 until: Sun Aug 19 16:34:21 GMT 2046 +Signature algorithm name: SHA256withRSA +Subject Public Key Algorithm: 4096-bit RSA key +Version: 3 +-----BEGIN CERTIFICATE----- +MIIFiTCCA3GgAwIBAgIQb77arXO9CEDii02+1PdbkTANBgkqhkiG9w0BAQsFADBO +MQswCQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQD +DBxTU0wuY29tIFRMUyBSU0EgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzQyMloX +DTQ2MDgxOTE2MzQyMVowTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jw +b3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgUlNBIFJvb3QgQ0EgMjAyMjCC +AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANCkCXJPQIgSYT41I57u9nTP +L3tYPc48DRAokC+X94xI2KDYJbFMsBFMF3NQ0CJKY7uB0ylu1bUJPiYYf7ISf5OY +t6/wNr/y7hienDtSxUcZXXTzZGbVXcdotL8bHAajvI9AI7YexoS9UcQbOcGV0ins +S657Lb85/bRi3pZ7QcacoOAGcvvwB5cJOYF0r/c0WRFXCsJbwST0MXMwgsadugL3 +PnxEX4MN8/HdIGkWCVDi1FW24IBydm5MR7d1VVm0U3TZlMZBrViKMWYPHqIbKUBO +L9975hYsLfy/7PO0+r4Y9ptJ1O4Fbtk085zx7AGL0SDGD6C1vBdOSHtRwvzpXGk3 +R2azaPgVKPC506QVzFpPulJwoxJF3ca6TvvC0PeoUidtbnm1jPx7jMEWTO6Af77w +dr5BUxIzrlo4QqvXDz5BjXYHMtWrifZOZ9mxQnUjbvPNQrL8VfVThxc7wDNY8VLS ++YCk8OjwO4s4zKTGkH8PnP2L0aPP2oOnaclQNtVcBdIKQXTbYxE3waWglksejBYS +d66UNHsef8JmAOSqg+qKkK3ONkRN0VHpvB/zagX9wHQfJRlAUW7qglFA35u5CCoG +AtUjHBPW6dvbxrB6y3snm/vg1UYk7RBLY0ulBY+6uB0rpvqR4pJSvezrZ5dtmi2f +gTIFZzL7SAg/2SW4BCUvAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j +BBgwFoAU+y437uOEeicuzRk1sTN8/9REQrkwHQYDVR0OBBYEFPsuN+7jhHonLs0Z +NbEzfP/UREK5MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAjYlt +hEUY8U+zoO9opMAdrDC8Z2awms22qyIZZtM7QbUQnRC6cm4pJCAcAZli05bg4vsM +QtfhWsSWTVTNj8pDU/0quOr4ZcoBwq1gaAafORpR2eCNJvkLTqVTJXojpBzOCBvf +R4iyrT7gJ4eLSYwfqUdYe5byiB0YrrPRpgqU+tvT5TgKa3kSM/tKWTcWQA673vWJ +DPFs0/dRa1419dvAJuoSc06pkZCmF8NsLzjUo3KUQyxi4U5cMj29TH0ZR6LDSeeW +P4+a0zvkEdiLA9z2tmBVGKaBUfPhqBVq6+AL8BQx1rmMRTqoENjwuSfr98t67wVy +lrXEj5ZzxOhWc5y8aVFjvO9nHEMaX3cZHxj4HCUp+UmZKbaSPaKDN7EgkaibMOlq +bLQjk2UEqxHzDh1TJElTHaE/nUiSEeJ9DU/1172iWD54nR4fK/4huxoTtrEoZP2w +AgDHbICivRZQIA9ygV/MlP+7mea6kMvq+cYMwq7FGc4zoWtcu358NFcXrfA/rs3q +r5nsLFR+jM4uElZI7xc7P0peYNLcdDa8pUNjyw9bowJWCZ4kLOGGgYz+qxcs+sji +Mho6/4UIyYOf8kpIEFR3N+2ivEC+5BB09+Rbu7nzifmPQdjH5FCQNYA+HLhNkNPU +98OwoX6EyneSMSy4kLGCenROmxMmtNVQZlR4rmA= +-----END CERTIFICATE----- diff -Nru openjdk-17-17.0.12+7/make/data/cldr/common/main/ff_Adlm.xml openjdk-17-17.0.13+11/make/data/cldr/common/main/ff_Adlm.xml --- openjdk-17-17.0.12+7/make/data/cldr/common/main/ff_Adlm.xml 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/make/data/cldr/common/main/ff_Adlm.xml 2024-10-10 14:01:59.000000000 +0000 @@ -272,7 +272,7 @@ 𞤄𞤢𞤸𞤢𞤥𞤢𞥄𞤧 𞤄𞤵𞥅𞤼𞤢𞥄𞤲 𞤅𞤵𞤪𞤭𞥅𞤪𞤫 𞤄𞤵𞥅𞤾𞤫𞥅 - ‮𞤄𞤮𞤼𞤧𞤵𞤱𞤢𞥄𞤲𞤢 + 𞤄𞤮𞤼𞤧𞤵𞤱𞤢𞥄𞤲𞤢 𞤄𞤫𞤤𞤢𞤪𞤵𞥅𞤧 𞤄𞤫𞤤𞤭𞥅𞥁 𞤑𞤢𞤲𞤢𞤣𞤢𞥄 @@ -2245,7 +2245,7 @@ 𞤐𞤵𞥅𞤳 - ‮𞤋𞤼𞥆𞤮𞤳𞤮𞤪𞤼𞤮𞥅𞤪𞤥𞤭𞥅𞤼 + 𞤋𞤼𞥆𞤮𞤳𞤮𞤪𞤼𞤮𞥅𞤪𞤥𞤭𞥅𞤼 𞤁𞤢𞥄𞤲𞤥𞤢𞤪𞤳𞥃𞤢𞥄𞤾𞤲 diff -Nru openjdk-17-17.0.12+7/make/data/currency/CurrencyData.properties openjdk-17-17.0.13+11/make/data/currency/CurrencyData.properties --- openjdk-17-17.0.12+7/make/data/currency/CurrencyData.properties 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/make/data/currency/CurrencyData.properties 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2000, 2023, 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 @@ -32,7 +32,7 @@ # Version of the currency code information in this class. # It is a serial number that accompanies with each amendment. -dataVersion=176 +dataVersion=177 # List of all valid ISO 4217 currency codes. # To ensure compatibility, do not remove codes. @@ -56,8 +56,8 @@ TPE626-TRL792-TRY949-TTD780-TWD901-TZS834-UAH980-UGX800-USD840-USN997-USS998-UYI940-\ UYU858-UZS860-VEB862-VED926-VEF937-VES928-VND704-VUV548-WST882-XAF950-XAG961-XAU959-XBA955-\ XBB956-XBC957-XBD958-XCD951-XCG532-XDR960-XFO000-XFU000-XOF952-XPD964-XPF953-\ - XPT962-XSU994-XTS963-XUA965-XXX999-YER886-YUM891-ZAR710-ZMK894-ZMW967-ZWD716-ZWL932-\ - ZWN942-ZWR935 + XPT962-XSU994-XTS963-XUA965-XXX999-YER886-YUM891-ZAR710-ZMK894-ZMW967-ZWD716-ZWG924-\ + ZWL932-ZWN942-ZWR935 # Mappings from ISO 3166 country codes to ISO 4217 currency codes. @@ -582,7 +582,7 @@ # ZAMBIA ZM=ZMW # ZIMBABWE -ZW=ZWL +ZW=ZWG # List of currencies with non-2digit decimals for minor units, diff -Nru openjdk-17-17.0.12+7/make/data/lsrdata/language-subtag-registry.txt openjdk-17-17.0.13+11/make/data/lsrdata/language-subtag-registry.txt --- openjdk-17-17.0.12+7/make/data/lsrdata/language-subtag-registry.txt 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/make/data/lsrdata/language-subtag-registry.txt 2024-10-10 14:01:59.000000000 +0000 @@ -1,4 +1,4 @@ -File-Date: 2024-03-07 +File-Date: 2024-06-14 %% Type: language Subtag: aa @@ -9402,6 +9402,7 @@ %% Type: language Subtag: dgr +Description: Tlicho Description: Dogrib Description: Tłı̨chǫ Added: 2005-10-16 @@ -15255,6 +15256,11 @@ Added: 2009-07-29 %% Type: language +Subtag: isv +Description: Interslavic +Added: 2024-05-15 +%% +Type: language Subtag: itb Description: Binongan Itneg Added: 2009-07-29 @@ -48003,7 +48009,9 @@ Subtag: laukika Description: Classical Sanskrit Added: 2010-07-28 +Deprecated: 2024-06-08 Prefix: sa +Comments: Preferred tag is cls %% Type: variant Subtag: lemosin @@ -48379,9 +48387,11 @@ Subtag: vaidika Description: Vedic Sanskrit Added: 2010-07-28 +Deprecated: 2024-06-08 Prefix: sa Comments: The most ancient dialect of Sanskrit used in verse and prose composed until about the 4th century B.C.E. +Comments: Preferred tag is vsn %% Type: variant Subtag: valbadia diff -Nru openjdk-17-17.0.12+7/make/devkit/createJMHBundle.sh openjdk-17-17.0.13+11/make/devkit/createJMHBundle.sh --- openjdk-17-17.0.12+7/make/devkit/createJMHBundle.sh 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/make/devkit/createJMHBundle.sh 2024-10-10 14:01:59.000000000 +0000 @@ -44,7 +44,7 @@ fetchJar() { url="${MAVEN_MIRROR}/$1/$2/$3/$2-$3.jar" if command -v curl > /dev/null; then - curl -O --fail $url + curl -OL --fail $url elif command -v wget > /dev/null; then wget $url else diff -Nru openjdk-17-17.0.12+7/make/hotspot/lib/CompileJvm.gmk openjdk-17-17.0.13+11/make/hotspot/lib/CompileJvm.gmk --- openjdk-17-17.0.12+7/make/hotspot/lib/CompileJvm.gmk 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/make/hotspot/lib/CompileJvm.gmk 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2013, 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 @@ -151,6 +151,8 @@ arguments.cpp_CXXFLAGS := $(CFLAGS_VM_VERSION), \ DISABLED_WARNINGS_gcc := $(DISABLED_WARNINGS_gcc), \ DISABLED_WARNINGS_clang := $(DISABLED_WARNINGS_clang), \ + DISABLED_WARNINGS_clang_notificationThread.cpp := bitwise-instead-of-logical, \ + DISABLED_WARNINGS_clang_serviceThread.cpp := bitwise-instead-of-logical, \ DISABLED_WARNINGS_xlc := $(DISABLED_WARNINGS_xlc), \ DISABLED_WARNINGS_microsoft := $(DISABLED_WARNINGS_microsoft), \ ASFLAGS := $(JVM_ASFLAGS), \ diff -Nru openjdk-17-17.0.12+7/make/hotspot/lib/JvmFlags.gmk openjdk-17-17.0.13+11/make/hotspot/lib/JvmFlags.gmk --- openjdk-17-17.0.12+7/make/hotspot/lib/JvmFlags.gmk 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/make/hotspot/lib/JvmFlags.gmk 2024-10-10 14:01:59.000000000 +0000 @@ -67,10 +67,12 @@ # ifeq ($(DEBUG_LEVEL), release) + # release builds disable uses of assert macro from . + JVM_CFLAGS_DEBUGLEVEL := -DNDEBUG # For hotspot, release builds differ internally between "optimized" and "product" # in that "optimize" does not define PRODUCT. ifneq ($(HOTSPOT_DEBUG_LEVEL), optimized) - JVM_CFLAGS_DEBUGLEVEL := -DPRODUCT + JVM_CFLAGS_DEBUGLEVEL += -DPRODUCT endif else ifeq ($(DEBUG_LEVEL), fastdebug) JVM_CFLAGS_DEBUGLEVEL := -DASSERT diff -Nru openjdk-17-17.0.12+7/make/modules/java.base/Launcher.gmk openjdk-17-17.0.13+11/make/modules/java.base/Launcher.gmk --- openjdk-17-17.0.12+7/make/modules/java.base/Launcher.gmk 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/make/modules/java.base/Launcher.gmk 2024-10-10 14:01:59.000000000 +0000 @@ -78,7 +78,8 @@ NAME := jspawnhelper, \ SRC := $(TOPDIR)/src/$(MODULE)/unix/native/jspawnhelper, \ OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKEXE) -I$(TOPDIR)/src/$(MODULE)/unix/native/libjava, \ + CFLAGS := $(CFLAGS_JDKEXE) $(VERSION_CFLAGS) \ + -I$(TOPDIR)/src/$(MODULE)/unix/native/libjava, \ EXTRA_OBJECT_FILES := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjava/childproc.o, \ LDFLAGS := $(LDFLAGS_JDKEXE), \ OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_libs/$(MODULE), \ diff -Nru openjdk-17-17.0.12+7/make/modules/java.base/lib/CoreLibraries.gmk openjdk-17-17.0.13+11/make/modules/java.base/lib/CoreLibraries.gmk --- openjdk-17-17.0.12+7/make/modules/java.base/lib/CoreLibraries.gmk 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/make/modules/java.base/lib/CoreLibraries.gmk 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -92,6 +92,7 @@ CFLAGS := $(CFLAGS_JDKLIB) \ $(LIBJAVA_CFLAGS), \ jdk_util.c_CFLAGS := $(VERSION_CFLAGS), \ + ProcessImpl_md.c_CFLAGS := $(VERSION_CFLAGS), \ EXTRA_HEADER_DIRS := libfdlibm, \ WARNINGS_AS_ERRORS_xlc := false, \ DISABLED_WARNINGS_gcc := unused-result unused-function, \ @@ -136,7 +137,7 @@ $(LIBZ_CFLAGS), \ CFLAGS_unix := $(BUILD_LIBZIP_MMAP) -UDEBUG, \ DISABLED_WARNINGS_gcc := unused-function implicit-fallthrough, \ - DISABLED_WARNINGS_clang := format-nonliteral, \ + DISABLED_WARNINGS_clang := format-nonliteral deprecated-non-prototype, \ LDFLAGS := $(LDFLAGS_JDKLIB) \ $(call SET_SHARED_LIBRARY_ORIGIN), \ LIBS_unix := -ljvm -ljava $(LIBZ_LIBS), \ @@ -205,7 +206,7 @@ OPTIMIZATION := HIGH, \ CFLAGS := $(CFLAGS_JDKLIB) $(LIBJLI_CFLAGS), \ DISABLED_WARNINGS_gcc := unused-function implicit-fallthrough, \ - DISABLED_WARNINGS_clang := sometimes-uninitialized format-nonliteral, \ + DISABLED_WARNINGS_clang := sometimes-uninitialized format-nonliteral deprecated-non-prototype, \ LDFLAGS := $(LDFLAGS_JDKLIB) \ $(call SET_SHARED_LIBRARY_ORIGIN), \ LIBS_unix := $(LIBZ_LIBS), \ diff -Nru openjdk-17-17.0.12+7/make/modules/java.desktop/Java.gmk openjdk-17-17.0.13+11/make/modules/java.desktop/Java.gmk --- openjdk-17-17.0.12+7/make/modules/java.desktop/Java.gmk 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/make/modules/java.desktop/Java.gmk 2024-10-10 14:01:59.000000000 +0000 @@ -67,6 +67,7 @@ ifeq ($(call isTargetOs, macosx), true) # exclude all X11 on Mac. EXCLUDES += \ + sun/awt/screencast \ sun/awt/X11 \ sun/java2d/x11 \ sun/java2d/jules \ diff -Nru openjdk-17-17.0.12+7/make/modules/java.desktop/lib/Awt2dLibraries.gmk openjdk-17-17.0.13+11/make/modules/java.desktop/lib/Awt2dLibraries.gmk --- openjdk-17-17.0.12+7/make/modules/java.desktop/lib/Awt2dLibraries.gmk 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/make/modules/java.desktop/lib/Awt2dLibraries.gmk 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -146,7 +146,7 @@ DISABLED_WARNINGS_gcc := sign-compare unused-result maybe-uninitialized \ format-nonliteral parentheses unused-value unused-function, \ DISABLED_WARNINGS_clang := logical-op-parentheses extern-initializer \ - sign-compare format-nonliteral, \ + sign-compare format-nonliteral deprecated-non-prototype, \ DISABLED_WARNINGS_microsoft := 4244 4267 4996, \ LDFLAGS := $(LDFLAGS_JDKLIB) $(call SET_SHARED_LIBRARY_ORIGIN), \ LDFLAGS_macosx := -L$(INSTALL_LIBRARIES_HERE), \ @@ -194,6 +194,9 @@ LIBAWT_XAWT_EXCLUDES := medialib debug + LIBPIPEWIRE_HEADER_DIRS := \ + $(TOPDIR)/src/$(MODULE)/unix/native/libpipewire/include + LIBAWT_XAWT_EXTRA_HEADER_DIRS := \ $(LIBAWT_DEFAULT_HEADER_DIRS) \ libawt_xawt/awt \ @@ -203,7 +206,7 @@ common/font \ common/java2d/opengl \ common/java2d/x11 \ - # + $(LIBPIPEWIRE_HEADER_DIRS) LIBAWT_XAWT_CFLAGS += -DXAWT -DXAWT_HACK \ $(FONTCONFIG_CFLAGS) \ @@ -456,7 +459,10 @@ endif # hb-ft.cc is not presently needed, and requires freetype 2.4.2 or later. - LIBFONTMANAGER_EXCLUDE_FILES += libharfbuzz/hb-ft.cc + # hb-subset and hb-style APIs are not needed, excluded to cut on compilation time. + LIBFONTMANAGER_EXCLUDE_FILES += hb-ft.cc hb-subset-cff-common.cc \ + hb-subset-cff1.cc hb-subset-cff2.cc hb-subset-input.cc hb-subset-plan.cc \ + hb-subset.cc hb-subset-instancer-solver.cc gsubgpos-context.cc hb-style.cc # list of disabled warnings and the compilers for which it was specifically added. # array-bounds -> GCC 12 on Alpine Linux @@ -767,7 +773,7 @@ maybe-uninitialized shift-negative-value implicit-fallthrough \ unused-function, \ DISABLED_WARNINGS_clang := incompatible-pointer-types sign-compare \ - deprecated-declarations null-pointer-subtraction $(LIBZ_DISABLED_WARNINGS_CLANG), \ + deprecated-declarations null-pointer-subtraction deprecated-non-prototype $(LIBZ_DISABLED_WARNINGS_CLANG), \ DISABLED_WARNINGS_microsoft := 4018 4244 4267, \ LDFLAGS := $(LDFLAGS_JDKLIB) \ $(call SET_SHARED_LIBRARY_ORIGIN), \ @@ -828,6 +834,7 @@ incompatible-pointer-types parentheses-equality extra-tokens \ sign-compare semicolon-before-method-body format-nonliteral undef \ pointer-arith, \ + DISABLED_WARNINGS_clang_MTLRenderer.m := gnu-folding-constant, \ LDFLAGS := $(LDFLAGS_JDKLIB) \ $(call SET_SHARED_LIBRARY_ORIGIN) \ -L$(INSTALL_LIBRARIES_HERE), \ diff -Nru openjdk-17-17.0.12+7/src/hotspot/cpu/aarch64/assembler_aarch64.hpp openjdk-17-17.0.13+11/src/hotspot/cpu/aarch64/assembler_aarch64.hpp --- openjdk-17-17.0.12+7/src/hotspot/cpu/aarch64/assembler_aarch64.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/cpu/aarch64/assembler_aarch64.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -505,7 +505,7 @@ if (size == 0) // It's a byte i->f(_ext.shift() >= 0, 12); else { - assert(_ext.shift() <= 0 || _ext.shift() == (int)size, "bad shift"); + guarantee(_ext.shift() <= 0 || _ext.shift() == (int)size, "bad shift"); i->f(_ext.shift() > 0, 12); } i->f(0b10, 11, 10); diff -Nru openjdk-17-17.0.12+7/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp openjdk-17-17.0.13+11/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp --- openjdk-17-17.0.12+7/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -1050,6 +1050,110 @@ } } +// Look up the method for a megamorphic invokeinterface call in a single pass over itable: +// - check recv_klass (actual object class) is a subtype of resolved_klass from CompiledICHolder +// - find a holder_klass (class that implements the method) vtable offset and get the method from vtable by index +// The target method is determined by . +// The receiver klass is in recv_klass. +// On success, the result will be in method_result, and execution falls through. +// On failure, execution transfers to the given label. +void MacroAssembler::lookup_interface_method_stub(Register recv_klass, + Register holder_klass, + Register resolved_klass, + Register method_result, + Register temp_itbl_klass, + Register scan_temp, + int itable_index, + Label& L_no_such_interface) { + // 'method_result' is only used as output register at the very end of this method. + // Until then we can reuse it as 'holder_offset'. + Register holder_offset = method_result; + assert_different_registers(resolved_klass, recv_klass, holder_klass, temp_itbl_klass, scan_temp, holder_offset); + + int vtable_start_offset = in_bytes(Klass::vtable_start_offset()); + int itable_offset_entry_size = itableOffsetEntry::size() * wordSize; + int ioffset = itableOffsetEntry::interface_offset_in_bytes(); + int ooffset = itableOffsetEntry::offset_offset_in_bytes(); + + Label L_loop_search_resolved_entry, L_resolved_found, L_holder_found; + + ldrw(scan_temp, Address(recv_klass, Klass::vtable_length_offset())); + add(recv_klass, recv_klass, vtable_start_offset + ioffset); + // itableOffsetEntry[] itable = recv_klass + Klass::vtable_start_offset() + sizeof(vtableEntry) * recv_klass->_vtable_len; + // temp_itbl_klass = itable[0]._interface; + int vtblEntrySize = vtableEntry::size_in_bytes(); + assert(vtblEntrySize == wordSize, "ldr lsl shift amount must be 3"); + ldr(temp_itbl_klass, Address(recv_klass, scan_temp, Address::lsl(exact_log2(vtblEntrySize)))); + mov(holder_offset, zr); + // scan_temp = &(itable[0]._interface) + lea(scan_temp, Address(recv_klass, scan_temp, Address::lsl(exact_log2(vtblEntrySize)))); + + // Initial checks: + // - if (holder_klass != resolved_klass), go to "scan for resolved" + // - if (itable[0] == holder_klass), shortcut to "holder found" + // - if (itable[0] == 0), no such interface + cmp(resolved_klass, holder_klass); + br(Assembler::NE, L_loop_search_resolved_entry); + cmp(holder_klass, temp_itbl_klass); + br(Assembler::EQ, L_holder_found); + cbz(temp_itbl_klass, L_no_such_interface); + + // Loop: Look for holder_klass record in itable + // do { + // temp_itbl_klass = *(scan_temp += itable_offset_entry_size); + // if (temp_itbl_klass == holder_klass) { + // goto L_holder_found; // Found! + // } + // } while (temp_itbl_klass != 0); + // goto L_no_such_interface // Not found. + Label L_search_holder; + bind(L_search_holder); + ldr(temp_itbl_klass, Address(pre(scan_temp, itable_offset_entry_size))); + cmp(holder_klass, temp_itbl_klass); + br(Assembler::EQ, L_holder_found); + cbnz(temp_itbl_klass, L_search_holder); + + b(L_no_such_interface); + + // Loop: Look for resolved_class record in itable + // while (true) { + // temp_itbl_klass = *(scan_temp += itable_offset_entry_size); + // if (temp_itbl_klass == 0) { + // goto L_no_such_interface; + // } + // if (temp_itbl_klass == resolved_klass) { + // goto L_resolved_found; // Found! + // } + // if (temp_itbl_klass == holder_klass) { + // holder_offset = scan_temp; + // } + // } + // + Label L_loop_search_resolved; + bind(L_loop_search_resolved); + ldr(temp_itbl_klass, Address(pre(scan_temp, itable_offset_entry_size))); + bind(L_loop_search_resolved_entry); + cbz(temp_itbl_klass, L_no_such_interface); + cmp(resolved_klass, temp_itbl_klass); + br(Assembler::EQ, L_resolved_found); + cmp(holder_klass, temp_itbl_klass); + br(Assembler::NE, L_loop_search_resolved); + mov(holder_offset, scan_temp); + b(L_loop_search_resolved); + + // See if we already have a holder klass. If not, go and scan for it. + bind(L_resolved_found); + cbz(holder_offset, L_search_holder); + mov(scan_temp, holder_offset); + + // Finally, scan_temp contains holder_klass vtable offset + bind(L_holder_found); + ldrw(method_result, Address(scan_temp, ooffset - ioffset)); + add(recv_klass, recv_klass, itable_index * wordSize + itableMethodEntry::method_offset_in_bytes() + - vtable_start_offset - ioffset); // substract offsets to restore the original value of recv_klass + ldr(method_result, Address(recv_klass, method_result, Address::uxtw(0))); +} + // virtual method calling void MacroAssembler::lookup_virtual_method(Register recv_klass, RegisterOrConstant vtable_index, diff -Nru openjdk-17-17.0.12+7/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp openjdk-17-17.0.13+11/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp --- openjdk-17-17.0.12+7/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -918,6 +918,15 @@ Label& no_such_interface, bool return_method = true); + void lookup_interface_method_stub(Register recv_klass, + Register holder_klass, + Register resolved_klass, + Register method_result, + Register temp_reg, + Register temp_reg2, + int itable_index, + Label& L_no_such_interface); + // virtual method calling // n.b. x86 allows RegisterOrConstant for vtable_index void lookup_virtual_method(Register recv_klass, diff -Nru openjdk-17-17.0.12+7/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp openjdk-17-17.0.13+11/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp --- openjdk-17-17.0.12+7/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -28,7 +28,6 @@ #include "code/codeCache.hpp" #include "code/compiledIC.hpp" #include "gc/shared/collectedHeap.hpp" -#include "memory/resourceArea.hpp" #include "nativeInst_aarch64.hpp" #include "oops/oop.inline.hpp" #include "runtime/handles.hpp" @@ -189,8 +188,6 @@ CompiledICLocker::is_safe(addr_at(0)), "concurrent code patching"); - ResourceMark rm; - int code_size = NativeInstruction::instruction_size; address addr_call = addr_at(0); bool reachable = Assembler::reachable_from_branch_at(addr_call, dest); assert(NativeCall::is_call_at(addr_call), "unexpected code at call site"); diff -Nru openjdk-17-17.0.12+7/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp openjdk-17-17.0.13+11/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp --- openjdk-17-17.0.12+7/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -212,10 +212,9 @@ } } - // Neoverse N1, N2 and V1 - if (_cpu == CPU_ARM && ((_model == 0xd0c || _model2 == 0xd0c) - || (_model == 0xd49 || _model2 == 0xd49) - || (_model == 0xd40 || _model2 == 0xd40))) { + // Neoverse N1, N2, V1, V2 + if (_cpu == CPU_ARM && (model_is(0xd0c) || model_is(0xd49) || + model_is(0xd40) || model_is(0xd4f))) { if (FLAG_IS_DEFAULT(UseSIMDForMemoryOps)) { FLAG_SET_DEFAULT(UseSIMDForMemoryOps, true); } @@ -238,8 +237,8 @@ if (_cpu == CPU_ARM && (_model == 0xd07 || _model2 == 0xd07)) _features |= CPU_STXR_PREFETCH; char buf[512]; - sprintf(buf, "0x%02x:0x%x:0x%03x:%d", _cpu, _variant, _model, _revision); - if (_model2) sprintf(buf+strlen(buf), "(0x%03x)", _model2); + int buf_used_len = os::snprintf_checked(buf, sizeof(buf), "0x%02x:0x%x:0x%03x:%d", _cpu, _variant, _model, _revision); + if (_model2) os::snprintf_checked(buf + buf_used_len, sizeof(buf) - buf_used_len, "(0x%03x)", _model2); #define ADD_FEATURE_IF_SUPPORTED(id, name, bit) if (_features & CPU_##id) strcat(buf, ", " name); CPU_FEATURE_FLAGS(ADD_FEATURE_IF_SUPPORTED) #undef ADD_FEATURE_IF_SUPPORTED diff -Nru openjdk-17-17.0.12+7/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp openjdk-17-17.0.13+11/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp --- openjdk-17-17.0.12+7/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -142,6 +142,10 @@ static int cpu_variant() { return _variant; } static int cpu_revision() { return _revision; } + static bool model_is(int cpu_model) { + return _model == cpu_model || _model2 == cpu_model; + } + static bool is_zva_enabled() { return 0 <= _zva_length; } static int zva_length() { assert(is_zva_enabled(), "ZVA not available"); diff -Nru openjdk-17-17.0.12+7/src/hotspot/cpu/aarch64/vtableStubs_aarch64.cpp openjdk-17-17.0.13+11/src/hotspot/cpu/aarch64/vtableStubs_aarch64.cpp --- openjdk-17-17.0.12+7/src/hotspot/cpu/aarch64/vtableStubs_aarch64.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/cpu/aarch64/vtableStubs_aarch64.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -175,7 +175,7 @@ // so all registers except arguments are free at this point. const Register recv_klass_reg = r10; const Register holder_klass_reg = r16; // declaring interface klass (DECC) - const Register resolved_klass_reg = rmethod; // resolved interface klass (REFC) + const Register resolved_klass_reg = r17; // resolved interface klass (REFC) const Register temp_reg = r11; const Register temp_reg2 = r15; const Register icholder_reg = rscratch2; @@ -192,28 +192,13 @@ __ load_klass(recv_klass_reg, j_rarg0); // Receiver subtype check against REFC. - __ lookup_interface_method(// inputs: rec. class, interface - recv_klass_reg, resolved_klass_reg, noreg, - // outputs: scan temp. reg1, scan temp. reg2 - temp_reg2, temp_reg, - L_no_such_interface, - /*return_method=*/false); - - const ptrdiff_t typecheckSize = __ pc() - start_pc; - start_pc = __ pc(); - // Get selected method from declaring class and itable index - __ lookup_interface_method(// inputs: rec. class, interface, itable index - recv_klass_reg, holder_klass_reg, itable_index, - // outputs: method, scan temp. reg - rmethod, temp_reg, - L_no_such_interface); - - const ptrdiff_t lookupSize = __ pc() - start_pc; + __ lookup_interface_method_stub(recv_klass_reg, holder_klass_reg, resolved_klass_reg, rmethod, + temp_reg, temp_reg2, itable_index, L_no_such_interface); // Reduce "estimate" such that "padding" does not drop below 8. - const ptrdiff_t estimate = 124; - const ptrdiff_t codesize = typecheckSize + lookupSize; + const ptrdiff_t estimate = 144; + const ptrdiff_t codesize = __ pc() - start_pc; slop_delta = (int)(estimate - codesize); slop_bytes += slop_delta; assert(slop_delta >= 0, "itable #%d: Code size estimate (%d) for lookup_interface_method too small, required: %d", itable_index, (int)estimate, (int)codesize); diff -Nru openjdk-17-17.0.12+7/src/hotspot/cpu/arm/arm.ad openjdk-17-17.0.13+11/src/hotspot/cpu/arm/arm.ad --- openjdk-17-17.0.12+7/src/hotspot/cpu/arm/arm.ad 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/cpu/arm/arm.ad 2024-10-10 14:01:59.000000000 +0000 @@ -243,7 +243,7 @@ #ifndef PRODUCT void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { char reg[128]; - ra_->dump_register(this, reg); + ra_->dump_register(this, reg, sizeof(reg)); st->print("MOV_SLOW &constanttable,%s\t! constant table base", reg); } #endif diff -Nru openjdk-17-17.0.12+7/src/hotspot/cpu/ppc/ppc.ad openjdk-17-17.0.13+11/src/hotspot/cpu/ppc/ppc.ad --- openjdk-17-17.0.12+7/src/hotspot/cpu/ppc/ppc.ad 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/cpu/ppc/ppc.ad 2024-10-10 14:01:59.000000000 +0000 @@ -1946,7 +1946,7 @@ void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); char reg_str[128]; - ra_->dump_register(this, reg_str); + ra_->dump_register(this, reg_str, sizeof(reg_str)); st->print("ADDI %s, SP, %d \t// box node", reg_str, offset); } #endif diff -Nru openjdk-17-17.0.12+7/src/hotspot/cpu/x86/assembler_x86.cpp openjdk-17-17.0.13+11/src/hotspot/cpu/x86/assembler_x86.cpp --- openjdk-17-17.0.12+7/src/hotspot/cpu/x86/assembler_x86.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/cpu/x86/assembler_x86.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -5811,6 +5811,14 @@ emit_arith(0x33, 0xC0, dst, src); } +void Assembler::xorw(Register dst, Address src) { + InstructionMark im(this); + emit_int8(0x66); + prefix(src, dst); + emit_int8(0x33); + emit_operand(dst, src, 0); +} + // AVX 3-operands scalar float-point arithmetic instructions void Assembler::vaddsd(XMMRegister dst, XMMRegister nds, Address src) { @@ -10513,17 +10521,6 @@ emit_int24(0x0F, (unsigned char)0xBE, (0xC0 | encode)); } -void Assembler::movslq(Register dst, int32_t imm32) { - // dbx shows movslq(rcx, 3) as movq $0x0000000049000000,(%rbx) - // and movslq(r8, 3); as movl $0x0000000048000000,(%rbx) - // as a result we shouldn't use until tested at runtime... - ShouldNotReachHere(); - InstructionMark im(this); - int encode = prefixq_and_encode(dst->encoding()); - emit_int8(0xC7 | encode); - emit_int32(imm32); -} - void Assembler::movslq(Address dst, int32_t imm32) { assert(is_simm32(imm32), "lost bits"); InstructionMark im(this); diff -Nru openjdk-17-17.0.12+7/src/hotspot/cpu/x86/assembler_x86.hpp openjdk-17-17.0.13+11/src/hotspot/cpu/x86/assembler_x86.hpp --- openjdk-17-17.0.12+7/src/hotspot/cpu/x86/assembler_x86.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/cpu/x86/assembler_x86.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -1584,7 +1584,6 @@ // Move signed 32bit immediate to 64bit extending sign void movslq(Address dst, int32_t imm64); - void movslq(Register dst, int32_t imm64); void movslq(Register dst, Address src); void movslq(Register dst, Register src); @@ -2116,6 +2115,7 @@ void xorb(Address dst, Register src); void xorb(Register dst, Address src); void xorw(Register dst, Register src); + void xorw(Register dst, Address src); void xorq(Register dst, Address src); void xorq(Address dst, int32_t imm32); diff -Nru openjdk-17-17.0.12+7/src/hotspot/cpu/x86/macroAssembler_x86.cpp openjdk-17-17.0.13+11/src/hotspot/cpu/x86/macroAssembler_x86.cpp --- openjdk-17-17.0.12+7/src/hotspot/cpu/x86/macroAssembler_x86.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/cpu/x86/macroAssembler_x86.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -1516,7 +1516,12 @@ void MacroAssembler::ic_call(address entry, jint method_index) { RelocationHolder rh = virtual_call_Relocation::spec(pc(), method_index); +#ifdef _LP64 + // Needs full 64-bit immediate for later patching. + mov64(rax, (intptr_t)Universe::non_oop_word()); +#else movptr(rax, (intptr_t)Universe::non_oop_word()); +#endif call(AddressLiteral(entry, rh)); } @@ -2685,7 +2690,15 @@ // src should NEVER be a real pointer. Use AddressLiteral for true pointers void MacroAssembler::movptr(Register dst, intptr_t src) { - LP64_ONLY(mov64(dst, src)) NOT_LP64(movl(dst, src)); +#ifdef _LP64 + if (is_simm32(src)) { + movq(dst, checked_cast(src)); + } else { + mov64(dst, src); + } +#else + movl(dst, src); +#endif } void MacroAssembler::movptr(Address dst, Register src) { @@ -3902,6 +3915,125 @@ } } +// Look up the method for a megamorphic invokeinterface call in a single pass over itable: +// - check recv_klass (actual object class) is a subtype of resolved_klass from CompiledICHolder +// - find a holder_klass (class that implements the method) vtable offset and get the method from vtable by index +// The target method is determined by . +// The receiver klass is in recv_klass. +// On success, the result will be in method_result, and execution falls through. +// On failure, execution transfers to the given label. +void MacroAssembler::lookup_interface_method_stub(Register recv_klass, + Register holder_klass, + Register resolved_klass, + Register method_result, + Register scan_temp, + Register temp_reg2, + Register receiver, + int itable_index, + Label& L_no_such_interface) { + assert_different_registers(recv_klass, method_result, holder_klass, resolved_klass, scan_temp, temp_reg2, receiver); + Register temp_itbl_klass = method_result; + Register temp_reg = (temp_reg2 == noreg ? recv_klass : temp_reg2); // reuse recv_klass register on 32-bit x86 impl + + int vtable_base = in_bytes(Klass::vtable_start_offset()); + int itentry_off = itableMethodEntry::method_offset_in_bytes(); + int scan_step = itableOffsetEntry::size() * wordSize; + int vte_size = vtableEntry::size_in_bytes(); + int ioffset = itableOffsetEntry::interface_offset_in_bytes(); + int ooffset = itableOffsetEntry::offset_offset_in_bytes(); + Address::ScaleFactor times_vte_scale = Address::times_ptr; + assert(vte_size == wordSize, "adjust times_vte_scale"); + + Label L_loop_scan_resolved_entry, L_resolved_found, L_holder_found; + + // temp_itbl_klass = recv_klass.itable[0] + // scan_temp = &recv_klass.itable[0] + step + movl(scan_temp, Address(recv_klass, Klass::vtable_length_offset())); + movptr(temp_itbl_klass, Address(recv_klass, scan_temp, times_vte_scale, vtable_base + ioffset)); + lea(scan_temp, Address(recv_klass, scan_temp, times_vte_scale, vtable_base + ioffset + scan_step)); + xorptr(temp_reg, temp_reg); + + // Initial checks: + // - if (holder_klass != resolved_klass), go to "scan for resolved" + // - if (itable[0] == 0), no such interface + // - if (itable[0] == holder_klass), shortcut to "holder found" + cmpptr(holder_klass, resolved_klass); + jccb(Assembler::notEqual, L_loop_scan_resolved_entry); + testptr(temp_itbl_klass, temp_itbl_klass); + jccb(Assembler::zero, L_no_such_interface); + cmpptr(holder_klass, temp_itbl_klass); + jccb(Assembler::equal, L_holder_found); + + // Loop: Look for holder_klass record in itable + // do { + // tmp = itable[index]; + // index += step; + // if (tmp == holder_klass) { + // goto L_holder_found; // Found! + // } + // } while (tmp != 0); + // goto L_no_such_interface // Not found. + Label L_scan_holder; + bind(L_scan_holder); + movptr(temp_itbl_klass, Address(scan_temp, 0)); + addptr(scan_temp, scan_step); + cmpptr(holder_klass, temp_itbl_klass); + jccb(Assembler::equal, L_holder_found); + testptr(temp_itbl_klass, temp_itbl_klass); + jccb(Assembler::notZero, L_scan_holder); + + jmpb(L_no_such_interface); + + // Loop: Look for resolved_class record in itable + // do { + // tmp = itable[index]; + // index += step; + // if (tmp == holder_klass) { + // // Also check if we have met a holder klass + // holder_tmp = itable[index-step-ioffset]; + // } + // if (tmp == resolved_klass) { + // goto L_resolved_found; // Found! + // } + // } while (tmp != 0); + // goto L_no_such_interface // Not found. + // + Label L_loop_scan_resolved; + bind(L_loop_scan_resolved); + movptr(temp_itbl_klass, Address(scan_temp, 0)); + addptr(scan_temp, scan_step); + bind(L_loop_scan_resolved_entry); + cmpptr(holder_klass, temp_itbl_klass); + cmovl(Assembler::equal, temp_reg, Address(scan_temp, ooffset - ioffset - scan_step)); + cmpptr(resolved_klass, temp_itbl_klass); + jccb(Assembler::equal, L_resolved_found); + testptr(temp_itbl_klass, temp_itbl_klass); + jccb(Assembler::notZero, L_loop_scan_resolved); + + jmpb(L_no_such_interface); + + Label L_ready; + + // See if we already have a holder klass. If not, go and scan for it. + bind(L_resolved_found); + testptr(temp_reg, temp_reg); + jccb(Assembler::zero, L_scan_holder); + jmpb(L_ready); + + bind(L_holder_found); + movl(temp_reg, Address(scan_temp, ooffset - ioffset - scan_step)); + + // Finally, temp_reg contains holder_klass vtable offset + bind(L_ready); + assert(itableMethodEntry::size() * wordSize == wordSize, "adjust the scaling in the code below"); + if (temp_reg2 == noreg) { // recv_klass register is clobbered for 32-bit x86 impl + load_klass(scan_temp, receiver, noreg); + movptr(method_result, Address(scan_temp, temp_reg, Address::times_1, itable_index * wordSize + itentry_off)); + } else { + movptr(method_result, Address(recv_klass, temp_reg, Address::times_1, itable_index * wordSize + itentry_off)); + } +} + // virtual method calling void MacroAssembler::lookup_virtual_method(Register recv_klass, diff -Nru openjdk-17-17.0.12+7/src/hotspot/cpu/x86/macroAssembler_x86.hpp openjdk-17-17.0.13+11/src/hotspot/cpu/x86/macroAssembler_x86.hpp --- openjdk-17-17.0.12+7/src/hotspot/cpu/x86/macroAssembler_x86.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/cpu/x86/macroAssembler_x86.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -556,6 +556,16 @@ Label& no_such_interface, bool return_method = true); + void lookup_interface_method_stub(Register recv_klass, + Register holder_klass, + Register resolved_klass, + Register method_result, + Register scan_temp, + Register temp_reg2, + Register receiver, + int itable_index, + Label& L_no_such_interface); + // virtual method calling void lookup_virtual_method(Register recv_klass, RegisterOrConstant vtable_index, diff -Nru openjdk-17-17.0.12+7/src/hotspot/cpu/x86/macroAssembler_x86_aes.cpp openjdk-17-17.0.13+11/src/hotspot/cpu/x86/macroAssembler_x86_aes.cpp --- openjdk-17-17.0.12+7/src/hotspot/cpu/x86/macroAssembler_x86_aes.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/cpu/x86/macroAssembler_x86_aes.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -798,6 +798,7 @@ const Register rounds = 0; const Register pos = r12; + const Register tail = r15; Label PRELOOP_START, EXIT_PRELOOP, REMAINDER, REMAINDER_16, LOOP, END, EXIT, END_LOOP, AES192, AES256, AES192_REMAINDER16, REMAINDER16_END_LOOP, AES256_REMAINDER16, @@ -1228,29 +1229,36 @@ // Save encrypted counter value in xmm0 for next invocation, before XOR operation movdqu(Address(saved_encCounter_start, 0), xmm0); // XOR encryted block cipher in xmm0 with PT to produce CT - evpxorq(xmm0, xmm0, Address(src_addr, pos, Address::times_1, 0), Assembler::AVX_128bit); // extract upto 15 bytes of CT from xmm0 as specified by length register testptr(len_reg, 8); jcc(Assembler::zero, EXTRACT_TAIL_4BYTES); - pextrq(Address(dest_addr, pos), xmm0, 0); + pextrq(tail, xmm0, 0); + xorq(tail, Address(src_addr, pos, Address::times_1, 0)); + movq(Address(dest_addr, pos), tail); psrldq(xmm0, 8); addl(pos, 8); bind(EXTRACT_TAIL_4BYTES); testptr(len_reg, 4); jcc(Assembler::zero, EXTRACT_TAIL_2BYTES); - pextrd(Address(dest_addr, pos), xmm0, 0); + pextrd(tail, xmm0, 0); + xorl(tail, Address(src_addr, pos, Address::times_1, 0)); + movl(Address(dest_addr, pos), tail); psrldq(xmm0, 4); addq(pos, 4); bind(EXTRACT_TAIL_2BYTES); testptr(len_reg, 2); jcc(Assembler::zero, EXTRACT_TAIL_1BYTE); - pextrw(Address(dest_addr, pos), xmm0, 0); + pextrw(tail, xmm0, 0); + xorw(tail, Address(src_addr, pos, Address::times_1, 0)); + movw(Address(dest_addr, pos), tail); psrldq(xmm0, 2); addl(pos, 2); bind(EXTRACT_TAIL_1BYTE); testptr(len_reg, 1); jcc(Assembler::zero, END); - pextrb(Address(dest_addr, pos), xmm0, 0); + pextrb(tail, xmm0, 0); + xorb(tail, Address(src_addr, pos, Address::times_1, 0)); + movb(Address(dest_addr, pos), tail); addl(pos, 1); bind(END); diff -Nru openjdk-17-17.0.12+7/src/hotspot/cpu/x86/vtableStubs_x86_32.cpp openjdk-17-17.0.13+11/src/hotspot/cpu/x86/vtableStubs_x86_32.cpp --- openjdk-17-17.0.12+7/src/hotspot/cpu/x86/vtableStubs_x86_32.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/cpu/x86/vtableStubs_x86_32.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -179,14 +179,16 @@ // rax: CompiledICHolder // rcx: Receiver - // Most registers are in use; we'll use rax, rbx, rsi, rdi + // Most registers are in use; we'll use rax, rbx, rcx, rdx, rsi, rdi // (If we need to make rsi, rdi callee-save, do a push/pop here.) const Register recv_klass_reg = rsi; const Register holder_klass_reg = rax; // declaring interface klass (DECC) - const Register resolved_klass_reg = rbx; // resolved interface klass (REFC) - const Register temp_reg = rdi; + const Register resolved_klass_reg = rdi; // resolved interface klass (REFC) + const Register temp_reg = rdx; + const Register method = rbx; + const Register icholder_reg = rax; + const Register receiver = rcx; - const Register icholder_reg = rax; __ movptr(resolved_klass_reg, Address(icholder_reg, CompiledICHolder::holder_klass_offset())); __ movptr(holder_klass_reg, Address(icholder_reg, CompiledICHolder::holder_metadata_offset())); @@ -198,35 +200,26 @@ __ load_klass(recv_klass_reg, rcx, noreg); start_pc = __ pc(); + __ push(rdx); // temp_reg // Receiver subtype check against REFC. - // Destroys recv_klass_reg value. - __ lookup_interface_method(// inputs: rec. class, interface - recv_klass_reg, resolved_klass_reg, noreg, - // outputs: scan temp. reg1, scan temp. reg2 - recv_klass_reg, temp_reg, - L_no_such_interface, - /*return_method=*/false); - - const ptrdiff_t typecheckSize = __ pc() - start_pc; - start_pc = __ pc(); - // Get selected method from declaring class and itable index - const Register method = rbx; - __ load_klass(recv_klass_reg, rcx, noreg); // restore recv_klass_reg - __ lookup_interface_method(// inputs: rec. class, interface, itable index - recv_klass_reg, holder_klass_reg, itable_index, - // outputs: method, scan temp. reg - method, temp_reg, - L_no_such_interface); - + __ lookup_interface_method_stub(recv_klass_reg, // input + holder_klass_reg, // input + resolved_klass_reg, // input + method, // output + temp_reg, + noreg, + receiver, // input (x86_32 only: to restore recv_klass value) + itable_index, + L_no_such_interface); const ptrdiff_t lookupSize = __ pc() - start_pc; // We expect we need index_dependent_slop extra bytes. Reason: // The emitted code in lookup_interface_method changes when itable_index exceeds 31. // For windows, a narrow estimate was found to be 104. Other OSes not tested. const ptrdiff_t estimate = 104; - const ptrdiff_t codesize = typecheckSize + lookupSize + index_dependent_slop; + const ptrdiff_t codesize = lookupSize + index_dependent_slop; slop_delta = (int)(estimate - codesize); slop_bytes += slop_delta; assert(slop_delta >= 0, "itable #%d: Code size estimate (%d) for lookup_interface_method too small, required: %d", itable_index, (int)estimate, (int)codesize); @@ -246,6 +239,7 @@ } #endif // ASSERT + __ pop(rdx); address ame_addr = __ pc(); __ jmp(Address(method, Method::from_compiled_offset())); @@ -255,6 +249,7 @@ // We force resolving of the call site by jumping to the "handle // wrong method" stub, and so let the interpreter runtime do all the // dirty work. + __ pop(rdx); __ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); masm->flush(); diff -Nru openjdk-17-17.0.12+7/src/hotspot/cpu/x86/vtableStubs_x86_64.cpp openjdk-17-17.0.13+11/src/hotspot/cpu/x86/vtableStubs_x86_64.cpp --- openjdk-17-17.0.12+7/src/hotspot/cpu/x86/vtableStubs_x86_64.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/cpu/x86/vtableStubs_x86_64.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -176,10 +176,12 @@ // (various calling sequences use r[cd]x, r[sd]i, r[89]; stay away from them) const Register recv_klass_reg = r10; const Register holder_klass_reg = rax; // declaring interface klass (DECC) - const Register resolved_klass_reg = rbx; // resolved interface klass (REFC) + const Register resolved_klass_reg = r14; // resolved interface klass (REFC) const Register temp_reg = r11; + const Register temp_reg2 = r13; + const Register method = rbx; + const Register icholder_reg = rax; - const Register icholder_reg = rax; __ movptr(resolved_klass_reg, Address(icholder_reg, CompiledICHolder::holder_klass_offset())); __ movptr(holder_klass_reg, Address(icholder_reg, CompiledICHolder::holder_metadata_offset())); @@ -193,25 +195,16 @@ start_pc = __ pc(); // Receiver subtype check against REFC. - // Destroys recv_klass_reg value. - __ lookup_interface_method(// inputs: rec. class, interface - recv_klass_reg, resolved_klass_reg, noreg, - // outputs: scan temp. reg1, scan temp. reg2 - recv_klass_reg, temp_reg, - L_no_such_interface, - /*return_method=*/false); - - const ptrdiff_t typecheckSize = __ pc() - start_pc; - start_pc = __ pc(); - // Get selected method from declaring class and itable index - const Register method = rbx; - __ load_klass(recv_klass_reg, j_rarg0, temp_reg); // restore recv_klass_reg - __ lookup_interface_method(// inputs: rec. class, interface, itable index - recv_klass_reg, holder_klass_reg, itable_index, - // outputs: method, scan temp. reg - method, temp_reg, - L_no_such_interface); + __ lookup_interface_method_stub(recv_klass_reg, // input + holder_klass_reg, // input + resolved_klass_reg, // input + method, // output + temp_reg, + temp_reg2, + noreg, + itable_index, + L_no_such_interface); const ptrdiff_t lookupSize = __ pc() - start_pc; @@ -219,7 +212,7 @@ // The emitted code in lookup_interface_method changes when itable_index exceeds 15. // For linux, a very narrow estimate would be 112, but Solaris requires some more space (130). const ptrdiff_t estimate = 136; - const ptrdiff_t codesize = typecheckSize + lookupSize + index_dependent_slop; + const ptrdiff_t codesize = lookupSize + index_dependent_slop; slop_delta = (int)(estimate - codesize); slop_bytes += slop_delta; assert(slop_delta >= 0, "itable #%d: Code size estimate (%d) for lookup_interface_method too small, required: %d", itable_index, (int)estimate, (int)codesize); diff -Nru openjdk-17-17.0.12+7/src/hotspot/os/aix/attachListener_aix.cpp openjdk-17-17.0.13+11/src/hotspot/os/aix/attachListener_aix.cpp --- openjdk-17-17.0.12+7/src/hotspot/os/aix/attachListener_aix.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/os/aix/attachListener_aix.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -266,7 +266,7 @@ // AixAttachOperation* AixAttachListener::read_request(int s) { char ver_str[8]; - sprintf(ver_str, "%d", ATTACH_PROTOCOL_VER); + os::snprintf_checked(ver_str, sizeof(ver_str), "%d", ATTACH_PROTOCOL_VER); // The request is a sequence of strings so we first figure out the // expected count and the maximum possible length of the request. @@ -311,7 +311,7 @@ if ((strlen(buf) != strlen(ver_str)) || (atoi(buf) != ATTACH_PROTOCOL_VER)) { char msg[32]; - sprintf(msg, "%d\n", ATTACH_ERROR_BADVERSION); + os::snprintf_checked(msg, sizeof(msg), "%d\n", ATTACH_ERROR_BADVERSION); write_fully(s, msg, strlen(msg)); return NULL; } @@ -441,7 +441,7 @@ // write operation result char msg[32]; - sprintf(msg, "%d\n", result); + os::snprintf_checked(msg, sizeof(msg), "%d\n", result); int rc = AixAttachListener::write_fully(this->socket(), msg, strlen(msg)); // write any result data @@ -544,7 +544,7 @@ char fn[PATH_MAX + 1]; int ret; struct stat64 st; - sprintf(fn, ".attach_pid%d", os::current_process_id()); + os::snprintf_checked(fn, sizeof(fn), ".attach_pid%d", os::current_process_id()); RESTARTABLE(::stat64(fn, &st), ret); if (ret == -1) { log_trace(attach)("Failed to find attach file: %s, trying alternate", fn); diff -Nru openjdk-17-17.0.12+7/src/hotspot/os/aix/os_aix.cpp openjdk-17-17.0.13+11/src/hotspot/os/aix/os_aix.cpp --- openjdk-17-17.0.12+7/src/hotspot/os/aix/os_aix.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/os/aix/os_aix.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -536,7 +536,7 @@ #endif #define EXTENSIONS_DIR "/lib/ext" - // Buffer that fits several sprintfs. + // Buffer that fits several snprintfs. // Note that the space for the trailing null is provided // by the nulls included by the sizeof operator. const size_t bufsize = @@ -584,13 +584,14 @@ // Concatenate user and invariant part of ld_library_path. // That's +1 for the colon and +1 for the trailing '\0'. - char *ld_library_path = NEW_C_HEAP_ARRAY(char, strlen(v) + 1 + sizeof(DEFAULT_LIBPATH) + 1, mtInternal); - sprintf(ld_library_path, "%s%s" DEFAULT_LIBPATH, v, v_colon); + size_t pathsize = strlen(v) + 1 + sizeof(DEFAULT_LIBPATH) + 1; + char *ld_library_path = NEW_C_HEAP_ARRAY(char, pathsize, mtInternal); + os::snprintf_checked(ld_library_path, pathsize, "%s%s" DEFAULT_LIBPATH, v, v_colon); Arguments::set_library_path(ld_library_path); FREE_C_HEAP_ARRAY(char, ld_library_path); // Extensions directories. - sprintf(buf, "%s" EXTENSIONS_DIR, Arguments::get_java_home()); + os::snprintf_checked(buf, bufsize, "%s" EXTENSIONS_DIR, Arguments::get_java_home()); Arguments::set_ext_dirs(buf); FREE_C_HEAP_ARRAY(char, buf); @@ -2068,7 +2069,7 @@ // // See http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/mprotect.htm - Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(addr), p2i(addr+size), prot); + Events::log_memprotect(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(addr), p2i(addr+size), prot); bool rc = ::mprotect(addr, size, prot) == 0 ? true : false; if (!rc) { @@ -2107,7 +2108,7 @@ // A valid strategy is just to try again. This usually works. :-/ ::usleep(1000); - Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(addr), p2i(addr+size), prot); + Events::log_memprotect(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(addr), p2i(addr+size), prot); if (::mprotect(addr, size, prot) == 0) { const bool read_protected_2 = (SafeFetch32((int*)addr, 0x12345678) == 0x12345678 && diff -Nru openjdk-17-17.0.12+7/src/hotspot/os/bsd/attachListener_bsd.cpp openjdk-17-17.0.13+11/src/hotspot/os/bsd/attachListener_bsd.cpp --- openjdk-17-17.0.12+7/src/hotspot/os/bsd/attachListener_bsd.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/os/bsd/attachListener_bsd.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -247,7 +247,7 @@ // BsdAttachOperation* BsdAttachListener::read_request(int s) { char ver_str[8]; - sprintf(ver_str, "%d", ATTACH_PROTOCOL_VER); + size_t ver_str_len = os::snprintf_checked(ver_str, sizeof(ver_str), "%d", ATTACH_PROTOCOL_VER); // The request is a sequence of strings so we first figure out the // expected count and the maximum possible length of the request. @@ -287,11 +287,11 @@ // The first string is so check it now to // check for protocol mis-match if (str_count == 1) { - if ((strlen(buf) != strlen(ver_str)) || + if ((strlen(buf) != ver_str_len) || (atoi(buf) != ATTACH_PROTOCOL_VER)) { char msg[32]; - sprintf(msg, "%d\n", ATTACH_ERROR_BADVERSION); - write_fully(s, msg, strlen(msg)); + int msg_len = os::snprintf_checked(msg, sizeof(msg), "%d\n", ATTACH_ERROR_BADVERSION); + write_fully(s, msg, msg_len); return NULL; } } @@ -410,8 +410,8 @@ // write operation result char msg[32]; - sprintf(msg, "%d\n", result); - int rc = BsdAttachListener::write_fully(this->socket(), msg, strlen(msg)); + int msg_len = os::snprintf_checked(msg, sizeof(msg), "%d\n", result); + int rc = BsdAttachListener::write_fully(this->socket(), msg, msg_len); // write any result data if (rc == 0) { diff -Nru openjdk-17-17.0.12+7/src/hotspot/os/bsd/os_bsd.cpp openjdk-17-17.0.13+11/src/hotspot/os/bsd/os_bsd.cpp --- openjdk-17-17.0.12+7/src/hotspot/os/bsd/os_bsd.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/os/bsd/os_bsd.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -338,7 +338,7 @@ #ifndef __APPLE__ - // Buffer that fits several sprintfs. + // Buffer that fits several snprintfs. // Note that the space for the colon and the trailing null are provided // by the nulls included by the sizeof operator. const size_t bufsize = @@ -394,17 +394,16 @@ const char *v_colon = ":"; if (v == NULL) { v = ""; v_colon = ""; } // That's +1 for the colon and +1 for the trailing '\0'. - char *ld_library_path = NEW_C_HEAP_ARRAY(char, - strlen(v) + 1 + - sizeof(SYS_EXT_DIR) + sizeof("/lib/") + strlen(cpu_arch) + sizeof(DEFAULT_LIBPATH) + 1, - mtInternal); - sprintf(ld_library_path, "%s%s" SYS_EXT_DIR "/lib/%s:" DEFAULT_LIBPATH, v, v_colon, cpu_arch); + const size_t ld_library_path_size = strlen(v) + 1 + sizeof(SYS_EXT_DIR) + + sizeof("/lib/") + strlen(cpu_arch) + sizeof(DEFAULT_LIBPATH) + 1; + char *ld_library_path = NEW_C_HEAP_ARRAY(char, ld_library_path_size, mtInternal); + os::snprintf_checked(ld_library_path, ld_library_path_size, "%s%s" SYS_EXT_DIR "/lib/%s:" DEFAULT_LIBPATH, v, v_colon, cpu_arch); Arguments::set_library_path(ld_library_path); FREE_C_HEAP_ARRAY(char, ld_library_path); } // Extensions directories. - sprintf(buf, "%s" EXTENSIONS_DIR ":" SYS_EXT_DIR EXTENSIONS_DIR, Arguments::get_java_home()); + os::snprintf_checked(buf, bufsize, "%s" EXTENSIONS_DIR ":" SYS_EXT_DIR EXTENSIONS_DIR, Arguments::get_java_home()); Arguments::set_ext_dirs(buf); FREE_C_HEAP_ARRAY(char, buf); @@ -419,7 +418,7 @@ size_t system_ext_size = strlen(user_home_dir) + sizeof(SYS_EXTENSIONS_DIR) + sizeof(SYS_EXTENSIONS_DIRS); - // Buffer that fits several sprintfs. + // Buffer that fits several snprintfs. // Note that the space for the colon and the trailing null are provided // by the nulls included by the sizeof operator. const size_t bufsize = @@ -489,11 +488,9 @@ // could cause a change in behavior, but Apple's Java6 behavior // can be achieved by putting "." at the beginning of the // JAVA_LIBRARY_PATH environment variable. - char *ld_library_path = NEW_C_HEAP_ARRAY(char, - strlen(v) + 1 + strlen(l) + 1 + - system_ext_size + 3, - mtInternal); - sprintf(ld_library_path, "%s%s%s%s%s" SYS_EXTENSIONS_DIR ":" SYS_EXTENSIONS_DIRS ":.", + const size_t ld_library_path_size = strlen(v) + 1 + strlen(l) + 1 + system_ext_size + 3; + char *ld_library_path = NEW_C_HEAP_ARRAY(char, ld_library_path_size, mtInternal); + os::snprintf_checked(ld_library_path, ld_library_path_size, "%s%s%s%s%s" SYS_EXTENSIONS_DIR ":" SYS_EXTENSIONS_DIRS ":.", v, v_colon, l, l_colon, user_home_dir); Arguments::set_library_path(ld_library_path); FREE_C_HEAP_ARRAY(char, ld_library_path); @@ -504,7 +501,7 @@ // Note that the space for the colon and the trailing null are provided // by the nulls included by the sizeof operator (so actually one byte more // than necessary is allocated). - sprintf(buf, "%s" SYS_EXTENSIONS_DIR ":%s" EXTENSIONS_DIR ":" SYS_EXTENSIONS_DIRS, + os::snprintf_checked(buf, bufsize, "%s" SYS_EXTENSIONS_DIR ":%s" EXTENSIONS_DIR ":" SYS_EXTENSIONS_DIRS, user_home_dir, Arguments::get_java_home()); Arguments::set_ext_dirs(buf); @@ -1609,7 +1606,7 @@ int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; #if defined(__OpenBSD__) // XXX: Work-around mmap/MAP_FIXED bug temporarily on OpenBSD - Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(addr), p2i(addr+size), prot); + Events::log_memprotect(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(addr), p2i(addr+size), prot); if (::mprotect(addr, size, prot) == 0) { return true; } @@ -1711,7 +1708,7 @@ bool os::pd_uncommit_memory(char* addr, size_t size, bool exec) { #if defined(__OpenBSD__) // XXX: Work-around mmap/MAP_FIXED bug temporarily on OpenBSD - Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with PROT_NONE", p2i(addr), p2i(addr+size)); + Events::log_memprotect(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with PROT_NONE", p2i(addr), p2i(addr+size)); return ::mprotect(addr, size, PROT_NONE) == 0; #elif defined(__APPLE__) if (exec) { @@ -1781,7 +1778,7 @@ assert(addr == bottom, "sanity check"); size = align_up(pointer_delta(addr, bottom, 1) + size, os::Bsd::page_size()); - Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(bottom), p2i(bottom+size), prot); + Events::log_memprotect(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(bottom), p2i(bottom+size), prot); return ::mprotect(bottom, size, prot) == 0; } @@ -2090,17 +2087,26 @@ if (status != 0) { log_info(os)("os::init_2 getrlimit failed: %s", os::strerror(errno)); } else { - nbr_files.rlim_cur = nbr_files.rlim_max; + rlim_t rlim_original = nbr_files.rlim_cur; -#ifdef __APPLE__ - // Darwin returns RLIM_INFINITY for rlim_max, but fails with EINVAL if - // you attempt to use RLIM_INFINITY. As per setrlimit(2), OPEN_MAX must - // be used instead - nbr_files.rlim_cur = MIN(OPEN_MAX, nbr_files.rlim_cur); -#endif + // On macOS according to setrlimit(2), OPEN_MAX must be used instead + // of RLIM_INFINITY, but testing on macOS >= 10.6, reveals that + // we can, in fact, use even RLIM_INFINITY, so try the max value + // that the system claims can be used first, same as other BSD OSes. + // However, some terminals (ksh) will internally use "int" type + // to store this value and since RLIM_INFINITY overflows an "int" + // we might end up with a negative value, so cap the system limit max + // at INT_MAX instead, just in case, for everyone. + nbr_files.rlim_cur = MIN(INT_MAX, nbr_files.rlim_max); status = setrlimit(RLIMIT_NOFILE, &nbr_files); if (status != 0) { + // If that fails then try lowering the limit to either OPEN_MAX + // (which is safe) or the original limit, whichever was greater. + nbr_files.rlim_cur = MAX(OPEN_MAX, rlim_original); + status = setrlimit(RLIMIT_NOFILE, &nbr_files); + } + if (status != 0) { log_info(os)("os::init_2 setrlimit failed: %s", os::strerror(errno)); } } diff -Nru openjdk-17-17.0.12+7/src/hotspot/os/bsd/os_perf_bsd.cpp openjdk-17-17.0.13+11/src/hotspot/os/bsd/os_perf_bsd.cpp --- openjdk-17-17.0.12+7/src/hotspot/os/bsd/os_perf_bsd.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/os/bsd/os_perf_bsd.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, 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 @@ -39,6 +39,7 @@ #include #include #include + #include #endif static const double NANOS_PER_SEC = 1000000000.0; @@ -46,10 +47,10 @@ class CPUPerformanceInterface::CPUPerformance : public CHeapObj { friend class CPUPerformanceInterface; private: - long _total_cpu_nanos; + uint64_t _jvm_real; long _total_csr_nanos; - long _jvm_user_nanos; - long _jvm_system_nanos; + uint64_t _jvm_user; + uint64_t _jvm_system; long _jvm_context_switches; long _used_ticks; long _total_ticks; @@ -83,11 +84,11 @@ }; CPUPerformanceInterface::CPUPerformance::CPUPerformance() { - _total_cpu_nanos= 0; - _total_csr_nanos= 0; + _jvm_real = 0; + _total_csr_nanos = 0; _jvm_context_switches = 0; - _jvm_user_nanos = 0; - _jvm_system_nanos = 0; + _jvm_user = 0; + _jvm_system = 0; _used_ticks = 0; _total_ticks = 0; _active_processor_count = 0; @@ -148,42 +149,35 @@ int CPUPerformanceInterface::CPUPerformance::cpu_loads_process(double* pjvmUserLoad, double* pjvmKernelLoad, double* psystemTotalLoad) { #ifdef __APPLE__ int result = cpu_load_total_process(psystemTotalLoad); - mach_port_t task = mach_task_self(); - mach_msg_type_number_t task_info_count = TASK_INFO_MAX; - task_info_data_t task_info_data; - kern_return_t kr = task_info(task, TASK_ABSOLUTETIME_INFO, (task_info_t)task_info_data, &task_info_count); - if (kr != KERN_SUCCESS) { + + struct tms buf; + clock_t jvm_real = times(&buf); + if (jvm_real == (clock_t) (-1)) { return OS_ERR; } - task_absolutetime_info_t absolutetime_info = (task_absolutetime_info_t)task_info_data; int active_processor_count = os::active_processor_count(); - long jvm_user_nanos = absolutetime_info->total_user; - long jvm_system_nanos = absolutetime_info->total_system; - - long total_cpu_nanos; - if(!now_in_nanos(&total_cpu_nanos)) { - return OS_ERR; - } + uint64_t jvm_user = buf.tms_utime; + uint64_t jvm_system = buf.tms_stime; - if (_total_cpu_nanos == 0 || active_processor_count != _active_processor_count) { - // First call or change in active processor count + if (active_processor_count != _active_processor_count) { + // Change in active processor count result = OS_ERR; - } + } else { + uint64_t delta = active_processor_count * (jvm_real - _jvm_real); + if (delta == 0) { + // Avoid division by zero + return OS_ERR; + } - long delta_nanos = active_processor_count * (total_cpu_nanos - _total_cpu_nanos); - if (delta_nanos == 0) { - // Avoid division by zero - return OS_ERR; + *pjvmUserLoad = normalize((double)(jvm_user - _jvm_user) / delta); + *pjvmKernelLoad = normalize((double)(jvm_system - _jvm_system) / delta); } - *pjvmUserLoad = normalize((double)(jvm_user_nanos - _jvm_user_nanos)/delta_nanos); - *pjvmKernelLoad = normalize((double)(jvm_system_nanos - _jvm_system_nanos)/delta_nanos); - _active_processor_count = active_processor_count; - _total_cpu_nanos = total_cpu_nanos; - _jvm_user_nanos = jvm_user_nanos; - _jvm_system_nanos = jvm_system_nanos; + _jvm_real = jvm_real; + _jvm_user = jvm_user; + _jvm_system = jvm_system; return result; #else diff -Nru openjdk-17-17.0.12+7/src/hotspot/os/linux/attachListener_linux.cpp openjdk-17-17.0.13+11/src/hotspot/os/linux/attachListener_linux.cpp --- openjdk-17-17.0.12+7/src/hotspot/os/linux/attachListener_linux.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/os/linux/attachListener_linux.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, 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 @@ -182,6 +182,8 @@ char initial_path[UNIX_PATH_MAX]; // socket file during setup int listener; // listener socket (file descriptor) + static_assert(sizeof(off_t) == 8, "Expected Large File Support in this file"); + // register function to cleanup if (!_atexit_registered) { _atexit_registered = true; @@ -247,7 +249,7 @@ // LinuxAttachOperation* LinuxAttachListener::read_request(int s) { char ver_str[8]; - sprintf(ver_str, "%d", ATTACH_PROTOCOL_VER); + os::snprintf_checked(ver_str, sizeof(ver_str), "%d", ATTACH_PROTOCOL_VER); // The request is a sequence of strings so we first figure out the // expected count and the maximum possible length of the request. @@ -290,7 +292,7 @@ if ((strlen(buf) != strlen(ver_str)) || (atoi(buf) != ATTACH_PROTOCOL_VER)) { char msg[32]; - sprintf(msg, "%d\n", ATTACH_ERROR_BADVERSION); + os::snprintf_checked(msg, sizeof(msg), "%d\n", ATTACH_ERROR_BADVERSION); write_fully(s, msg, strlen(msg)); return NULL; } @@ -384,7 +386,7 @@ // write the given buffer to the socket int LinuxAttachListener::write_fully(int s, char* buf, int len) { do { - int n = ::write(s, buf, len); + ssize_t n = ::write(s, buf, len); if (n == -1) { if (errno != EINTR) return -1; } else { @@ -410,7 +412,7 @@ // write operation result char msg[32]; - sprintf(msg, "%d\n", result); + os::snprintf_checked(msg, sizeof(msg), "%d\n", result); int rc = LinuxAttachListener::write_fully(this->socket(), msg, strlen(msg)); // write any result data @@ -444,14 +446,14 @@ void AttachListener::vm_start() { char fn[UNIX_PATH_MAX]; - struct stat64 st; + struct stat st; int ret; int n = snprintf(fn, UNIX_PATH_MAX, "%s/.java_pid%d", os::get_temp_directory(), os::current_process_id()); assert(n < (int)UNIX_PATH_MAX, "java_pid file name buffer overflow"); - RESTARTABLE(::stat64(fn, &st), ret); + RESTARTABLE(::stat(fn, &st), ret); if (ret == 0) { ret = ::unlink(fn); if (ret == -1) { @@ -471,8 +473,8 @@ bool AttachListener::check_socket_file() { int ret; - struct stat64 st; - ret = stat64(LinuxAttachListener::path(), &st); + struct stat st; + ret = stat(LinuxAttachListener::path(), &st); if (ret == -1) { // need to restart attach listener. log_debug(attach)("Socket file %s does not exist - Restart Attach Listener", LinuxAttachListener::path()); @@ -511,14 +513,14 @@ } char fn[PATH_MAX + 1]; int ret; - struct stat64 st; - sprintf(fn, ".attach_pid%d", os::current_process_id()); - RESTARTABLE(::stat64(fn, &st), ret); + struct stat st; + os::snprintf_checked(fn, sizeof(fn), ".attach_pid%d", os::current_process_id()); + RESTARTABLE(::stat(fn, &st), ret); if (ret == -1) { log_trace(attach)("Failed to find attach file: %s, trying alternate", fn); snprintf(fn, sizeof(fn), "%s/.attach_pid%d", os::get_temp_directory(), os::current_process_id()); - RESTARTABLE(::stat64(fn, &st), ret); + RESTARTABLE(::stat(fn, &st), ret); if (ret == -1) { log_debug(attach)("Failed to find attach file: %s", fn); } diff -Nru openjdk-17-17.0.12+7/src/hotspot/os/linux/os_linux.cpp openjdk-17-17.0.13+11/src/hotspot/os/linux/os_linux.cpp --- openjdk-17-17.0.12+7/src/hotspot/os/linux/os_linux.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/os/linux/os_linux.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -430,7 +430,7 @@ #define SYS_EXT_DIR "/usr/java/packages" #define EXTENSIONS_DIR "/lib/ext" - // Buffer that fits several sprintfs. + // Buffer that fits several snprintfs. // Note that the space for the colon and the trailing null are provided // by the nulls included by the sizeof operator. const size_t bufsize = @@ -485,17 +485,15 @@ const char *v_colon = ":"; if (v == NULL) { v = ""; v_colon = ""; } // That's +1 for the colon and +1 for the trailing '\0'. - char *ld_library_path = NEW_C_HEAP_ARRAY(char, - strlen(v) + 1 + - sizeof(SYS_EXT_DIR) + sizeof("/lib/") + sizeof(DEFAULT_LIBPATH) + 1, - mtInternal); - sprintf(ld_library_path, "%s%s" SYS_EXT_DIR "/lib:" DEFAULT_LIBPATH, v, v_colon); + size_t pathsize = strlen(v) + 1 + sizeof(SYS_EXT_DIR) + sizeof("/lib/") + sizeof(DEFAULT_LIBPATH) + 1; + char *ld_library_path = NEW_C_HEAP_ARRAY(char, pathsize, mtInternal); + os::snprintf_checked(ld_library_path, pathsize, "%s%s" SYS_EXT_DIR "/lib:" DEFAULT_LIBPATH, v, v_colon); Arguments::set_library_path(ld_library_path); FREE_C_HEAP_ARRAY(char, ld_library_path); } // Extensions directories. - sprintf(buf, "%s" EXTENSIONS_DIR ":" SYS_EXT_DIR EXTENSIONS_DIR, Arguments::get_java_home()); + os::snprintf_checked(buf, bufsize, "%s" EXTENSIONS_DIR ":" SYS_EXT_DIR EXTENSIONS_DIR, Arguments::get_java_home()); Arguments::set_ext_dirs(buf); FREE_C_HEAP_ARRAY(char, buf); @@ -2745,6 +2743,8 @@ void linux_wrap_code(char* base, size_t size) { static volatile jint cnt = 0; + static_assert(sizeof(off_t) == 8, "Expected Large File Support in this file"); + if (!UseOprofile) { return; } @@ -3589,7 +3589,7 @@ #ifdef CAN_SHOW_REGISTERS_ON_ASSERT if (addr != g_assert_poison) #endif - Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(bottom), p2i(bottom+size), prot); + Events::log_memprotect(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(bottom), p2i(bottom+size), prot); return ::mprotect(bottom, size, prot) == 0; } @@ -4992,14 +4992,14 @@ oflag |= O_CLOEXEC; #endif - int fd = ::open64(path, oflag, mode); + int fd = ::open(path, oflag, mode); if (fd == -1) return -1; //If the open succeeded, the file might still be a directory { - struct stat64 buf64; - int ret = ::fstat64(fd, &buf64); - int st_mode = buf64.st_mode; + struct stat buf; + int ret = ::fstat(fd, &buf); + int st_mode = buf.st_mode; if (ret != -1) { if ((st_mode & S_IFMT) == S_IFDIR) { @@ -5036,17 +5036,17 @@ int os::create_binary_file(const char* path, bool rewrite_existing) { int oflags = O_WRONLY | O_CREAT; oflags |= rewrite_existing ? O_TRUNC : O_EXCL; - return ::open64(path, oflags, S_IREAD | S_IWRITE); + return ::open(path, oflags, S_IREAD | S_IWRITE); } // return current position of file pointer jlong os::current_file_offset(int fd) { - return (jlong)::lseek64(fd, (off64_t)0, SEEK_CUR); + return (jlong)::lseek(fd, (off_t)0, SEEK_CUR); } // move file pointer to the specified offset jlong os::seek_to_file_offset(int fd, jlong offset) { - return (jlong)::lseek64(fd, (off64_t)offset, SEEK_SET); + return (jlong)::lseek(fd, (off_t)offset, SEEK_SET); } // This code originates from JDK's sysAvailable @@ -5055,10 +5055,10 @@ int os::available(int fd, jlong *bytes) { jlong cur, end; int mode; - struct stat64 buf64; + struct stat buf; - if (::fstat64(fd, &buf64) >= 0) { - mode = buf64.st_mode; + if (::fstat(fd, &buf) >= 0) { + mode = buf.st_mode; if (S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) { int n; if (::ioctl(fd, FIONREAD, &n) >= 0) { @@ -5067,11 +5067,11 @@ } } } - if ((cur = ::lseek64(fd, 0L, SEEK_CUR)) == -1) { + if ((cur = ::lseek(fd, 0L, SEEK_CUR)) == -1) { return 0; - } else if ((end = ::lseek64(fd, 0L, SEEK_END)) == -1) { + } else if ((end = ::lseek(fd, 0L, SEEK_END)) == -1) { return 0; - } else if (::lseek64(fd, cur, SEEK_SET) == -1) { + } else if (::lseek(fd, cur, SEEK_SET) == -1) { return 0; } *bytes = end - cur; diff -Nru openjdk-17-17.0.12+7/src/hotspot/os/linux/os_perf_linux.cpp openjdk-17-17.0.13+11/src/hotspot/os/linux/os_perf_linux.cpp --- openjdk-17-17.0.12+7/src/hotspot/os/linux/os_perf_linux.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/os/linux/os_perf_linux.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -847,7 +847,7 @@ bool SystemProcessInterface::SystemProcesses::ProcessIterator::initialize() { _dir = os::opendir("/proc"); _entry = NULL; - _valid = true; + _valid = _dir != NULL; // May be null if /proc is not accessible. next_process(); return true; diff -Nru openjdk-17-17.0.12+7/src/hotspot/os/posix/os_posix.cpp openjdk-17-17.0.13+11/src/hotspot/os/posix/os_posix.cpp --- openjdk-17-17.0.12+7/src/hotspot/os/posix/os_posix.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/os/posix/os_posix.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, 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 @@ -279,6 +279,7 @@ } static int util_posix_fallocate(int fd, off_t offset, off_t len) { + static_assert(sizeof(off_t) == 8, "Expected Large File Support in this file"); #ifdef __APPLE__ fstore_t store = { F_ALLOCATECONTIG, F_PEOFPOSMODE, 0, len }; // First we try to get a continuous chunk of disk space @@ -720,7 +721,7 @@ } jlong os::lseek(int fd, jlong offset, int whence) { - return (jlong) BSD_ONLY(::lseek) NOT_BSD(::lseek64)(fd, offset, whence); + return (jlong) AIX_ONLY(::lseek64) NOT_AIX(::lseek)(fd, offset, whence); } int os::fsync(int fd) { @@ -728,7 +729,7 @@ } int os::ftruncate(int fd, jlong length) { - return BSD_ONLY(::ftruncate) NOT_BSD(::ftruncate64)(fd, length); + return AIX_ONLY(::ftruncate64) NOT_AIX(::ftruncate)(fd, length); } const char* os::get_current_directory(char *buf, size_t buflen) { @@ -739,9 +740,9 @@ return ::fdopen(fd, mode); } -size_t os::write(int fd, const void *buf, unsigned int nBytes) { - size_t res; - RESTARTABLE((size_t) ::write(fd, buf, (size_t) nBytes), res); +ssize_t os::pd_write(int fd, const void *buf, size_t nBytes) { + ssize_t res; + RESTARTABLE(::write(fd, buf, nBytes), res); return res; } diff -Nru openjdk-17-17.0.12+7/src/hotspot/os/posix/os_posix.hpp openjdk-17-17.0.13+11/src/hotspot/os/posix/os_posix.hpp --- openjdk-17-17.0.12+7/src/hotspot/os/posix/os_posix.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/os/posix/os_posix.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -27,7 +27,7 @@ // Note: the Posix API aims to capture functionality available on all Posix // compliant platforms, but in practice the implementations may depend on -// non-Posix functionality. For example, the use of lseek64 and ftruncate64. +// non-Posix functionality. // This use of non-Posix API's is made possible by compiling/linking in a mode // that is not restricted to being fully Posix complaint, such as by declaring // -D_GNU_SOURCE. But be aware that in doing so we may enable non-Posix diff -Nru openjdk-17-17.0.12+7/src/hotspot/os/posix/perfMemory_posix.cpp openjdk-17-17.0.13+11/src/hotspot/os/posix/perfMemory_posix.cpp --- openjdk-17-17.0.12+7/src/hotspot/os/posix/perfMemory_posix.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/os/posix/perfMemory_posix.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2021 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -89,38 +89,25 @@ const char* destfile = PerfMemory::get_perfdata_file_path(); assert(destfile[0] != '\0', "invalid PerfData file path"); - int result; + int fd; - RESTARTABLE(os::open(destfile, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR), - result); - if (result == OS_ERR) { - if (PrintMiscellaneous && Verbose) { - warning("Could not create Perfdata save file: %s: %s\n", - destfile, os::strerror(errno)); - } + RESTARTABLE(os::open(destfile, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR), fd); + if (fd == OS_ERR) { + warning("Could not create Perfdata save file: %s: %s\n", + destfile, os::strerror(errno)); } else { - int fd = result; - - for (size_t remaining = size; remaining > 0;) { + ssize_t result; - RESTARTABLE(::write(fd, addr, remaining), result); - if (result == OS_ERR) { - if (PrintMiscellaneous && Verbose) { - warning("Could not write Perfdata save file: %s: %s\n", - destfile, os::strerror(errno)); - } - break; - } - - remaining -= (size_t)result; - addr += result; + bool successful_write = os::write(fd, addr, size); + if (!successful_write) { + warning("Could not write Perfdata save file: %s: %s\n", + destfile, os::strerror(errno)); } + result = ::close(fd); - if (PrintMiscellaneous && Verbose) { - if (result == OS_ERR) { - warning("Could not close %s: %s\n", destfile, os::strerror(errno)); - } + if (result == OS_ERR) { + warning("Could not close %s: %s\n", destfile, os::strerror(errno)); } } FREE_C_HEAP_ARRAY(char, destfile); @@ -880,9 +867,9 @@ // Open the filename in the current directory. // Cannot use O_TRUNC here; truncation of an existing file has to happen // after the is_file_secure() check below. - int result; - RESTARTABLE(os::open(filename, O_RDWR|O_CREAT|O_NOFOLLOW, S_IRUSR|S_IWUSR), result); - if (result == OS_ERR) { + int fd; + RESTARTABLE(os::open(filename, O_RDWR|O_CREAT|O_NOFOLLOW, S_IRUSR|S_IWUSR), fd); + if (fd == OS_ERR) { if (PrintMiscellaneous && Verbose) { if (errno == ELOOP) { warning("file %s is a symlink and is not secure\n", filename); @@ -898,9 +885,6 @@ // close the directory and reset the current working directory close_directory_secure_cwd(dirp, saved_cwd_fd); - // save the file descriptor - int fd = result; - // check to see if the file is secure if (!is_file_secure(fd, filename)) { ::close(fd); @@ -933,6 +917,8 @@ } #endif + ssize_t result; + // truncate the file to get rid of any existing data RESTARTABLE(::ftruncate(fd, (off_t)0), result); if (result == OS_ERR) { @@ -959,11 +945,11 @@ int zero_int = 0; result = (int)os::seek_to_file_offset(fd, (jlong)(seekpos)); if (result == -1 ) break; - RESTARTABLE(::write(fd, &zero_int, 1), result); - if (result != 1) { + if (!os::write(fd, &zero_int, 1)) { if (errno == ENOSPC) { warning("Insufficient space for shared memory file:\n %s\nTry using the -Djava.io.tmpdir= option to select an alternate temp location.\n", filename); } + result = OS_ERR; break; } } @@ -971,7 +957,7 @@ if (result != -1) { return fd; } else { - ::close(fd); + os::close(fd); return -1; } } diff -Nru openjdk-17-17.0.12+7/src/hotspot/os/windows/os_windows.cpp openjdk-17-17.0.13+11/src/hotspot/os/windows/os_windows.cpp --- openjdk-17-17.0.12+7/src/hotspot/os/windows/os_windows.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/os/windows/os_windows.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -385,8 +385,9 @@ char path[MAX_PATH]; char buf[2 * MAX_PATH + 2 * sizeof(EXT_DIR) + sizeof(PACKAGE_DIR) + 1]; GetWindowsDirectory(path, MAX_PATH); - sprintf(buf, "%s%s;%s%s%s", Arguments::get_java_home(), EXT_DIR, - path, PACKAGE_DIR, EXT_DIR); + os::snprintf_checked(buf, sizeof(buf), "%s%s;%s%s%s", + Arguments::get_java_home(), EXT_DIR, + path, PACKAGE_DIR, EXT_DIR); Arguments::set_ext_dirs(buf); } #undef EXT_DIR @@ -4842,8 +4843,19 @@ return ::_fdopen(fd, mode); } -size_t os::write(int fd, const void *buf, unsigned int nBytes) { - return ::write(fd, buf, nBytes); +ssize_t os::pd_write(int fd, const void *buf, size_t nBytes) { + ssize_t original_len = (ssize_t)nBytes; + while (nBytes > 0) { + unsigned int len = nBytes > INT_MAX ? INT_MAX : (unsigned int)nBytes; + // On Windows, ::write takes 'unsigned int' no of bytes, so nBytes should be split if larger. + ssize_t written_bytes = ::write(fd, buf, len); + if (written_bytes < 0) { + return OS_ERR; + } + nBytes -= written_bytes; + buf = (char *)buf + written_bytes; + } + return original_len; } int os::close(int fd) { diff -Nru openjdk-17-17.0.12+7/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp openjdk-17-17.0.13+11/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp --- openjdk-17-17.0.12+7/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2021 SAP SE. 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 @@ -253,7 +253,7 @@ stub = SharedRuntime::get_handle_wrong_method_stub(); } - else if ((sig == USE_POLL_BIT_ONLY ? SIGTRAP : SIGSEGV) && + else if ((sig == (USE_POLL_BIT_ONLY ? SIGTRAP : SIGSEGV)) && // A linux-ppc64 kernel before 2.6.6 doesn't set si_addr on some segfaults // in 64bit mode (cf. http://www.kernel.org/pub/linux/kernel/v2.6/ChangeLog-2.6.6), // especially when we try to read from the safepoint polling page. So the check diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/adlc/adlc.hpp openjdk-17-17.0.13+11/src/hotspot/share/adlc/adlc.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/adlc/adlc.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/adlc/adlc.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -108,4 +108,8 @@ // it everywhere it needs to be available. extern ArchDesc* globalAD; +// Performs snprintf and asserts the result is non-negative (so there was not +// an encoding error) and that the output was not truncated. +extern int snprintf_checked(char* buf, size_t len, const char* fmt, ...); + #endif // SHARE_ADLC_ADLC_HPP diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/adlc/adlparse.cpp openjdk-17-17.0.13+11/src/hotspot/share/adlc/adlparse.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/adlc/adlparse.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/adlc/adlparse.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -211,8 +211,9 @@ return; } assert(match_rules_cnt < 100," too many match rule clones"); - char* buf = (char*) AdlAllocateHeap(strlen(instr->_ident) + 4); - sprintf(buf, "%s_%d", instr->_ident, match_rules_cnt++); + const size_t buf_size = strlen(instr->_ident) + 4; + char* buf = (char*) AdlAllocateHeap(buf_size); + snprintf_checked(buf, buf_size, "%s_%d", instr->_ident, match_rules_cnt++); rule->_result = buf; // Check for commutative operations with tree operands. matchrule_clone_and_swap(rule, instr->_ident, match_rules_cnt); @@ -2805,8 +2806,9 @@ // Create a new encoding name based on the name of the instruction // definition, which should be unique. const char* prefix = "__ins_encode_"; - char* ec_name = (char*) AdlAllocateHeap(strlen(inst._ident) + strlen(prefix) + 1); - sprintf(ec_name, "%s%s", prefix, inst._ident); + const size_t ec_name_size = strlen(inst._ident) + strlen(prefix) + 1; + char* ec_name = (char*) AdlAllocateHeap(ec_name_size); + snprintf_checked(ec_name, ec_name_size, "%s%s", prefix, inst._ident); assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist"); EncClass* encoding = _AD._encode->add_EncClass(ec_name); @@ -3276,8 +3278,9 @@ // Create a new encoding name based on the name of the instruction // definition, which should be unique. const char* prefix = "__constant_"; - char* ec_name = (char*) AdlAllocateHeap(strlen(inst._ident) + strlen(prefix) + 1); - sprintf(ec_name, "%s%s", prefix, inst._ident); + const size_t ec_name_size = strlen(inst._ident) + strlen(prefix) + 1; + char* ec_name = (char*) AdlAllocateHeap(ec_name_size); + snprintf_checked(ec_name, ec_name_size, "%s%s", prefix, inst._ident); assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist"); EncClass* encoding = _AD._encode->add_EncClass(ec_name); @@ -4596,8 +4599,9 @@ // Grab a constant expression. param = get_paren_expr(description); if (param[0] != '(') { - char* buf = (char*) AdlAllocateHeap(strlen(param) + 3); - sprintf(buf, "(%s)", param); + const size_t buf_size = strlen(param) + 3; + char* buf = (char*) AdlAllocateHeap(buf_size); + snprintf_checked(buf, buf_size, "(%s)", param); param = buf; } assert(is_literal_constant(param), @@ -5204,8 +5208,9 @@ char* ADLParser::get_line_string(int linenum) { const char* file = _AD._ADL_file._name; int line = linenum ? linenum : this->linenum(); - char* location = (char *)AdlAllocateHeap(strlen(file) + 100); - sprintf(location, "\n#line %d \"%s\"\n", line, file); + const size_t location_size = strlen(file) + 100; + char* location = (char *)AdlAllocateHeap(location_size); + snprintf_checked(location, location_size, "\n#line %d \"%s\"\n", line, file); return location; } diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/adlc/archDesc.cpp openjdk-17-17.0.13+11/src/hotspot/share/adlc/archDesc.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/adlc/archDesc.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/adlc/archDesc.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -815,7 +815,7 @@ const char *mask = "_mask"; int length = (int)strlen(rc_name) + (int)strlen(mask) + 5; char *regMask = new char[length]; - sprintf(regMask,"%s%s()", rc_name, mask); + snprintf_checked(regMask, length, "%s%s()", rc_name, mask); delete[] rc_name; return regMask; } @@ -908,7 +908,7 @@ const char *stack_or = "STACK_OR_"; int length = (int)strlen(stack_or) + (int)strlen(reg_mask_name) + 1; char *result = new char[length]; - sprintf(result,"%s%s", stack_or, reg_mask_name); + snprintf_checked(result, length, "%s%s", stack_or, reg_mask_name); return result; } diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/adlc/dfa.cpp openjdk-17-17.0.13+11/src/hotspot/share/adlc/dfa.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/adlc/dfa.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/adlc/dfa.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -207,13 +207,13 @@ Expr *c = new Expr("0"); if (mList._lchild) { // If left child, add it in const char* lchild_to_upper = ArchDesc::getMachOperEnum(mList._lchild); - sprintf(Expr::buffer(), "_kids[0]->_cost[%s]", lchild_to_upper); + snprintf_checked(Expr::buffer(), STRING_BUFFER_LENGTH, "_kids[0]->_cost[%s]", lchild_to_upper); c->add(Expr::buffer()); delete[] lchild_to_upper; } if (mList._rchild) { // If right child, add it in const char* rchild_to_upper = ArchDesc::getMachOperEnum(mList._rchild); - sprintf(Expr::buffer(), "_kids[1]->_cost[%s]", rchild_to_upper); + snprintf_checked(Expr::buffer(), STRING_BUFFER_LENGTH, "_kids[1]->_cost[%s]", rchild_to_upper); c->add(Expr::buffer()); delete[] rchild_to_upper; } @@ -730,7 +730,7 @@ snprintf(string_buffer, STRING_BUFFER_LENGTH, "%s", c2->_expr); } else { - sprintf( string_buffer, "0"); + snprintf_checked(string_buffer, STRING_BUFFER_LENGTH, "0"); } string_buffer[STRING_BUFFER_LENGTH - 1] = '\0'; char *cost = strdup(string_buffer); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/adlc/formssel.cpp openjdk-17-17.0.13+11/src/hotspot/share/adlc/formssel.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/adlc/formssel.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/adlc/formssel.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -25,6 +25,8 @@ // FORMS.CPP - Definitions for ADL Parser Forms Classes #include "adlc.hpp" +#define remaining_buflen(buffer, position) (sizeof(buffer) - ((position) - (buffer))) + //==============================Instructions=================================== //------------------------------InstructForm----------------------------------- InstructForm::InstructForm(const char *id, bool ideal_only) @@ -1303,7 +1305,7 @@ void InstructForm::rep_var_format(FILE *fp, const char *rep_var) { // Handle special constant table variables. if (strcmp(rep_var, "constanttablebase") == 0) { - fprintf(fp, "char reg[128]; ra->dump_register(in(mach_constant_base_node_input()), reg);\n"); + fprintf(fp, "char reg[128]; ra->dump_register(in(mach_constant_base_node_input()), reg, sizeof(reg));\n"); fprintf(fp, " st->print(\"%%s\", reg);\n"); return; } @@ -1538,7 +1540,7 @@ s += strlen(s); } // Add predicate to working buffer - sprintf(s,"/*%s*/(",(char*)i._key); + snprintf_checked(s, remaining_buflen(buf, s), "/*%s*/(",(char*)i._key); s += strlen(s); mnode->build_instr_pred(s,(char*)i._key, 0, path_bitmask, 0); s += strlen(s); @@ -2501,7 +2503,7 @@ strcmp(ideal_type(globalAD->globalNames()), "RegFlags") == 0)) { // !!!!! !!!!! fprintf(fp," { char reg_str[128];\n"); - fprintf(fp," ra->dump_register(node,reg_str);\n"); + fprintf(fp," ra->dump_register(node,reg_str, sizeof(reg_str));\n"); fprintf(fp," st->print(\"%cs\",reg_str);\n",'%'); fprintf(fp," }\n"); } else if (_matrule && (dtype = _matrule->is_base_constant(globals)) != Form::none) { @@ -2509,7 +2511,7 @@ } else if (ideal_to_sReg_type(_ident) != Form::none) { // Special format for Stack Slot Register fprintf(fp," { char reg_str[128];\n"); - fprintf(fp," ra->dump_register(node,reg_str);\n"); + fprintf(fp," ra->dump_register(node,reg_str, sizeof(reg_str));\n"); fprintf(fp," st->print(\"%cs\",reg_str);\n",'%'); fprintf(fp," }\n"); } else { @@ -2530,7 +2532,7 @@ fprintf(fp," { char reg_str[128];\n"); fprintf(fp," ra->dump_register(node->in(idx"); if ( index != 0 ) fprintf(fp, "+%d",index); - fprintf(fp, "),reg_str);\n"); + fprintf(fp, "),reg_str,sizeof(reg_str));\n"); fprintf(fp," st->print(\"%cs\",reg_str);\n",'%'); fprintf(fp," }\n"); } else if (_matrule && (dtype = _matrule->is_base_constant(globals)) != Form::none) { @@ -2540,7 +2542,7 @@ fprintf(fp," { char reg_str[128];\n"); fprintf(fp," ra->dump_register(node->in(idx"); if ( index != 0 ) fprintf(fp, "+%d",index); - fprintf(fp, "),reg_str);\n"); + fprintf(fp, "),reg_str,sizeof(reg_str));\n"); fprintf(fp," st->print(\"%cs\",reg_str);\n",'%'); fprintf(fp," }\n"); } else { @@ -3476,7 +3478,7 @@ _rChild->_internalop : _rChild->_opType) : ""; len += (int)strlen(lstr) + (int)strlen(rstr); subtree = (char *)AdlAllocateHeap(len); - sprintf(subtree,"_%s_%s_%s", _opType, lstr, rstr); + snprintf_checked(subtree, len, "_%s_%s_%s", _opType, lstr, rstr); // Hash the subtree string in _internalOps; if a name exists, use it iop = (char *)_AD._internalOps[subtree]; // Else create a unique name, and add it to the hash table @@ -3898,8 +3900,9 @@ MatchRule* clone = new MatchRule(_AD, this); // Swap operands of commutative operation ((MatchNode*)clone)->swap_commutative_op(true, count); - char* buf = (char*) AdlAllocateHeap(strlen(instr_ident) + 4); - sprintf(buf, "%s_%d", instr_ident, match_rules_cnt++); + const size_t buf_size = strlen(instr_ident) + 4; + char* buf = (char*) AdlAllocateHeap(buf_size); + snprintf_checked(buf, buf_size, "%s_%d", instr_ident, match_rules_cnt++); clone->_result = buf; clone->_next = this->_next; diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/adlc/main.cpp openjdk-17-17.0.13+11/src/hotspot/share/adlc/main.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/adlc/main.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/adlc/main.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -467,7 +467,7 @@ int len = (int)strlen(base) + (int)strlen(suffix) + 1; char* fname = new char[len]; - sprintf(fname,"%s%s",base,suffix); + snprintf_checked(fname,len,"%s%s",base,suffix); return fname; } diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/adlc/output_c.cpp openjdk-17-17.0.13+11/src/hotspot/share/adlc/output_c.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/adlc/output_c.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/adlc/output_c.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -26,6 +26,8 @@ #include "adlc.hpp" +#define remaining_buflen(buffer, position) (sizeof(buffer) - (position - buffer)) + // Utilities to characterize effect statements static bool is_def(int usedef) { switch(usedef) { @@ -35,6 +37,16 @@ return false; } +int snprintf_checked(char* buf, size_t len, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + int result = vsnprintf(buf, len, fmt, args); + va_end(args); + assert(result >= 0, "snprintf error"); + assert(static_cast(result) < len, "snprintf truncated"); + return result; +} + // Define an array containing the machine register names, strings. static void defineRegNames(FILE *fp, RegisterForm *registers) { if (registers) { @@ -197,7 +209,8 @@ return -1; } - char *operand_stages = new char [templen]; + const size_t operand_stages_size = templen; + char *operand_stages = new char [operand_stages_size]; operand_stages[0] = 0; int i = 0; templen = 0; @@ -211,7 +224,7 @@ while ( (paramname = pipeclass->_parameters.iter()) != NULL ) { const PipeClassOperandForm *tmppipeopnd = (const PipeClassOperandForm *)pipeclass->_localUsage[paramname]; - templen += sprintf(&operand_stages[templen], " stage_%s%c\n", + templen += snprintf_checked(&operand_stages[templen], operand_stages_size - templen, " stage_%s%c\n", tmppipeopnd ? tmppipeopnd->_stage : "undefined", (++i < paramcount ? ',' : ' ') ); } @@ -278,6 +291,7 @@ int templen = 1 + commentlen + pipeline->_rescount * (max_stage + 14); // Allocate space for the resource list + const size_t resource_stages_size = templen; char * resource_stages = new char [templen]; templen = 0; @@ -285,7 +299,7 @@ const char * const resname = res_stages[i] == 0 ? "undefined" : pipeline->_stages.name(res_stages[i]-1); - templen += sprintf(&resource_stages[templen], " stage_%s%-*s // %s\n", + templen += snprintf_checked(&resource_stages[templen], resource_stages_size - templen, " stage_%s%-*s // %s\n", resname, max_stage - (int)strlen(resname) + 1, (i < pipeline->_rescount-1) ? "," : "", pipeline->_reslist.name(i)); @@ -344,7 +358,7 @@ for (i = 0; i < pipeline->_rescount; i++) { if (max_cycles < res_cycles[i]) max_cycles = res_cycles[i]; - templen = sprintf(temp, "%d", res_cycles[i]); + templen = snprintf_checked(temp, sizeof(temp), "%d", res_cycles[i]); if (cyclelen < templen) cyclelen = templen; commentlen += (int)strlen(pipeline->_reslist.name(i)); @@ -353,12 +367,13 @@ templen = 1 + commentlen + (cyclelen + 8) * pipeline->_rescount; // Allocate space for the resource list - char * resource_cycles = new char [templen]; + const size_t resource_cycles_size = templen; + char * resource_cycles = new char [resource_cycles_size]; templen = 0; for (i = 0; i < pipeline->_rescount; i++) { - templen += sprintf(&resource_cycles[templen], " %*d%c // %s\n", + templen += snprintf_checked(&resource_cycles[templen], resource_cycles_size - templen, " %*d%c // %s\n", cyclelen, res_cycles[i], (i < pipeline->_rescount-1) ? ',' : ' ', pipeline->_reslist.name(i)); } @@ -431,7 +446,8 @@ (cyclemasksize * 12) + masklen + (cycledigit * 2) + 30) * element_count; // Allocate space for the resource list - char * resource_mask = new char [templen]; + const size_t resource_mask_size = templen; + char * resource_mask = new char [resource_mask_size]; char * last_comma = NULL; templen = 0; @@ -456,7 +472,7 @@ } int formatlen = - sprintf(&resource_mask[templen], " %s(0x%0*x, %*d, %*d, %s %s(", + snprintf_checked(&resource_mask[templen], resource_mask_size - templen, " %s(0x%0*x, %*d, %*d, %s %s(", pipeline_use_element, masklen, used_mask, cycledigit, lb, cycledigit, ub, @@ -496,7 +512,7 @@ for (j = cyclemasksize-1; j >= 0; j--) { formatlen = - sprintf(&resource_mask[templen], "0x%08x%s", res_mask[j], j > 0 ? ", " : ""); + snprintf_checked(&resource_mask[templen], resource_mask_size - templen, "0x%08x%s", res_mask[j], j > 0 ? ", " : ""); templen += formatlen; } @@ -527,9 +543,8 @@ // "0x012345678, 0x012345678, 4294967295" char* args = new char [36 + 1]; - int printed = sprintf(args, "0x%x, 0x%x, %u", - resources_used, resources_used_exclusively, element_count); - assert(printed <= 36, "overflow"); + snprintf_checked(args, 36 + 1, "0x%x, 0x%x, %u", + resources_used, resources_used_exclusively, element_count); pipeline_res_args.addName(args); } @@ -1066,9 +1081,9 @@ InstructForm *inst = globals[inst_name]->is_instruction(); if( inst != NULL ) { char inst_prefix[] = "instXXXX_"; - sprintf(inst_prefix, "inst%d_", inst_position); + snprintf_checked(inst_prefix, sizeof(inst_prefix), "inst%d_", inst_position); char receiver[] = "instXXXX->"; - sprintf(receiver, "inst%d->", inst_position); + snprintf_checked(receiver, sizeof(receiver), "inst%d->", inst_position); inst->index_temps( fp, globals, inst_prefix, receiver ); } } @@ -1162,7 +1177,7 @@ char left_reg_index[] = ",inst4294967295_idx4294967295"; if( left_op_index != 0 ) { // Must have index into operands - sprintf(left_reg_index,",inst%u_idx%u", (unsigned)left_index, (unsigned)left_op_index); + snprintf_checked(left_reg_index, sizeof(left_reg_index), ",inst%u_idx%u", (unsigned)left_index, (unsigned)left_op_index); } else { strcpy(left_reg_index, ""); } @@ -1174,7 +1189,7 @@ char right_reg_index[] = ",inst4294967295_idx4294967295"; if( right_op_index != 0 ) { // Must have index into operands - sprintf(right_reg_index,",inst%u_idx%u", (unsigned)right_index, (unsigned)right_op_index); + snprintf_checked(right_reg_index, sizeof(right_reg_index), ",inst%u_idx%u", (unsigned)right_index, (unsigned)right_op_index); } else { strcpy(right_reg_index, ""); } @@ -2516,19 +2531,19 @@ const char* arg_name = ins_encode->rep_var_name(inst, param_no); int idx = inst.operand_position_format(arg_name); if (strcmp(arg_name, "constanttablebase") == 0) { - ib += sprintf(ib, " unsigned idx_%-5s = mach_constant_base_node_input(); \t// %s, \t%s\n", + ib += snprintf_checked(ib, remaining_buflen(idxbuf, ib), " unsigned idx_%-5s = mach_constant_base_node_input(); \t// %s, \t%s\n", name, type, arg_name); - nb += sprintf(nb, " Node *n_%-7s = lookup(idx_%s);\n", name, name); + nb += snprintf_checked(nb, remaining_buflen(nbuf, nb), " Node *n_%-7s = lookup(idx_%s);\n", name, name); // There is no operand for the constanttablebase. } else if (inst.is_noninput_operand(idx)) { globalAD->syntax_err(inst._linenum, "In %s: you can not pass the non-input %s to a postalloc expand encoding.\n", inst._ident, arg_name); } else { - ib += sprintf(ib, " unsigned idx_%-5s = idx%d; \t// %s, \t%s\n", + ib += snprintf_checked(ib, remaining_buflen(idxbuf, ib), " unsigned idx_%-5s = idx%d; \t// %s, \t%s\n", name, idx, type, arg_name); - nb += sprintf(nb, " Node *n_%-7s = lookup(idx_%s);\n", name, name); - ob += sprintf(ob, " %sOper *op_%s = (%sOper *)opnd_array(%d);\n", type, name, type, idx); + nb += snprintf_checked(nb, remaining_buflen(nbuf, nb), " Node *n_%-7s = lookup(idx_%s);\n", name, name); + ob += snprintf_checked(ob, remaining_buflen(opbuf, ob), " %sOper *op_%s = (%sOper *)opnd_array(%d);\n", type, name, type, idx); } param_no++; } diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/c1/c1_Runtime1.cpp openjdk-17-17.0.13+11/src/hotspot/share/c1/c1_Runtime1.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/c1/c1_Runtime1.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/c1/c1_Runtime1.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -657,7 +657,7 @@ const int len = 35; assert(len < strlen("Index %d out of bounds for length %d"), "Must allocate more space for message."); char message[2 * jintAsStringSize + len]; - sprintf(message, "Index %d out of bounds for length %d", index, a->length()); + os::snprintf_checked(message, sizeof(message), "Index %d out of bounds for length %d", index, a->length()); SharedRuntime::throw_and_post_jvmti_exception(current, vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), message); JRT_END @@ -665,7 +665,7 @@ JRT_ENTRY(void, Runtime1::throw_index_exception(JavaThread* current, int index)) NOT_PRODUCT(_throw_index_exception_count++;) char message[16]; - sprintf(message, "%d", index); + os::snprintf_checked(message, sizeof(message), "%d", index); SharedRuntime::throw_and_post_jvmti_exception(current, vmSymbols::java_lang_IndexOutOfBoundsException(), message); JRT_END diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/cds/filemap.cpp openjdk-17-17.0.13+11/src/hotspot/share/cds/filemap.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/cds/filemap.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/cds/filemap.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -158,7 +158,7 @@ strncpy(header_version, vm_version, JVM_IDENT_MAX-9); // Append the hash code as eight hex digits. - sprintf(&header_version[JVM_IDENT_MAX-9], "%08x", hash); + os::snprintf_checked(&header_version[JVM_IDENT_MAX-9], 9, "%08x", hash); header_version[JVM_IDENT_MAX-1] = 0; // Null terminate. } @@ -1420,8 +1420,7 @@ void FileMapInfo::write_bytes(const void* buffer, size_t nbytes) { assert(_file_open, "must be"); - size_t n = os::write(_fd, buffer, (unsigned int)nbytes); - if (n != nbytes) { + if (!os::write(_fd, buffer, nbytes)) { // If the shared archive is corrupted, close it and remove it. close(); remove(_full_path); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/classfile/classLoaderDataGraph.cpp openjdk-17-17.0.13+11/src/hotspot/share/classfile/classLoaderDataGraph.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/classfile/classLoaderDataGraph.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/classfile/classLoaderDataGraph.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -186,7 +186,7 @@ // on the stack or in the code cache, so we only have to repeat the full walk if // they were found at that time. // TODO: have redefinition clean old methods out of the code cache. They still exist in some places. - bool walk_all_metadata = InstanceKlass::has_previous_versions_and_reset(); + bool walk_all_metadata = InstanceKlass::should_clean_previous_versions_and_reset(); MetadataOnStackMark md_on_stack(walk_all_metadata, /*redefinition_walk*/false); clean_deallocate_lists(walk_all_metadata); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/classfile/classLoaderDataGraph.inline.hpp openjdk-17-17.0.13+11/src/hotspot/share/classfile/classLoaderDataGraph.inline.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/classfile/classLoaderDataGraph.inline.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/classfile/classLoaderDataGraph.inline.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -73,7 +73,7 @@ // Only clean metaspaces after full GC. bool do_cleaning = _safepoint_cleanup_needed; #if INCLUDE_JVMTI - do_cleaning = do_cleaning && (_should_clean_deallocate_lists || InstanceKlass::has_previous_versions()); + do_cleaning = do_cleaning && (_should_clean_deallocate_lists || InstanceKlass::should_clean_previous_versions()); #else do_cleaning = do_cleaning && _should_clean_deallocate_lists; #endif diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/classfile/javaClasses.cpp openjdk-17-17.0.13+11/src/hotspot/share/classfile/javaClasses.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/classfile/javaClasses.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/classfile/javaClasses.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -2375,17 +2375,18 @@ } // Allocate temporary buffer with extra space for formatting and line number - char* buf = NEW_RESOURCE_ARRAY(char, buf_len + 64); + const size_t buf_size = buf_len + 64; + char* buf = NEW_RESOURCE_ARRAY(char, buf_size); // Print stack trace line in buffer - sprintf(buf, "\tat %s.%s(", klass_name, method_name); + size_t buf_off = os::snprintf_checked(buf, buf_size, "\tat %s.%s(", klass_name, method_name); // Print module information if (module_name != NULL) { if (module_version != NULL) { - sprintf(buf + (int)strlen(buf), "%s@%s/", module_name, module_version); + buf_off += os::snprintf_checked(buf + buf_off, buf_size - buf_off, "%s@%s/", module_name, module_version); } else { - sprintf(buf + (int)strlen(buf), "%s/", module_name); + buf_off += os::snprintf_checked(buf + buf_off, buf_size - buf_off, "%s/", module_name); } } @@ -2400,17 +2401,17 @@ } else { if (source_file_name != NULL && (line_number != -1)) { // Sourcename and linenumber - sprintf(buf + (int)strlen(buf), "%s:%d)", source_file_name, line_number); + buf_off += os::snprintf_checked(buf + buf_off, buf_size - buf_off, "%s:%d)", source_file_name, line_number); } else if (source_file_name != NULL) { // Just sourcename - sprintf(buf + (int)strlen(buf), "%s)", source_file_name); + buf_off += os::snprintf_checked(buf + buf_off, buf_size - buf_off, "%s)", source_file_name); } else { // Neither sourcename nor linenumber - sprintf(buf + (int)strlen(buf), "Unknown Source)"); + buf_off += os::snprintf_checked(buf + buf_off, buf_size - buf_off, "Unknown Source)"); } CompiledMethod* nm = method->code(); if (WizardMode && nm != NULL) { - sprintf(buf + (int)strlen(buf), "(nmethod " INTPTR_FORMAT ")", (intptr_t)nm); + os::snprintf_checked(buf + buf_off, buf_size - buf_off, "(nmethod " INTPTR_FORMAT ")", (intptr_t)nm); } } } diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/classfile/symbolTable.cpp openjdk-17-17.0.13+11/src/hotspot/share/classfile/symbolTable.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/classfile/symbolTable.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/classfile/symbolTable.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -56,6 +56,31 @@ // -------------------------------------------------------------------------- +Symbol* volatile TempSymbolCleanupDelayer::_queue[QueueSize] = {}; +volatile uint TempSymbolCleanupDelayer::_index = 0; + +// Keep this symbol alive for some time to allow for reuse. +// Temp symbols for the same string can often be created in quick succession, +// and this queue allows them to be reused instead of churning. +void TempSymbolCleanupDelayer::delay_cleanup(Symbol* sym) { + assert(sym != nullptr, "precondition"); + sym->increment_refcount(); + uint i = Atomic::add(&_index, 1u) % QueueSize; + Symbol* old = Atomic::xchg(&_queue[i], sym); + if (old != nullptr) { + old->decrement_refcount(); + } +} + +void TempSymbolCleanupDelayer::drain_queue() { + for (uint i = 0; i < QueueSize; i++) { + Symbol* sym = Atomic::xchg(&_queue[i], (Symbol*) nullptr); + if (sym != nullptr) { + sym->decrement_refcount(); + } + } +} + inline bool symbol_equals_compact_hashtable_entry(Symbol* value, const char* key, int len) { if (value->equals(key, len)) { return true; diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/classfile/symbolTable.hpp openjdk-17-17.0.13+11/src/hotspot/share/classfile/symbolTable.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/classfile/symbolTable.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/classfile/symbolTable.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, 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 @@ -33,6 +33,16 @@ class JavaThread; template class GrowableArray; +class TempSymbolCleanupDelayer : AllStatic { + static Symbol* volatile _queue[]; + static volatile uint _index; + +public: + static const uint QueueSize = 128; + static void delay_cleanup(Symbol* s); + static void drain_queue(); +}; + // TempNewSymbol acts as a handle class in a handle/body idiom and is // responsible for proper resource management of the body (which is a Symbol*). // The body is resource managed by a reference counting scheme. @@ -54,7 +64,14 @@ // Conversion from a Symbol* to a TempNewSymbol. // Does not increment the current reference count. - TempNewSymbol(Symbol *s) : _temp(s) {} + TempNewSymbol(Symbol *s) : _temp(s) { + // Delay cleanup for temp symbols. Refcount is incremented while in + // queue. But don't requeue existing entries, or entries that are held + // elsewhere - it's a waste of effort. + if (s != nullptr && s->refcount() == 1) { + TempSymbolCleanupDelayer::delay_cleanup(s); + } + } // Copy constructor increments reference count. TempNewSymbol(const TempNewSymbol& rhs) : _temp(rhs._temp) { diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/classfile/verifier.cpp openjdk-17-17.0.13+11/src/hotspot/share/classfile/verifier.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/classfile/verifier.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/classfile/verifier.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -32,6 +32,7 @@ #include "classfile/stackMapTableFormat.hpp" #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" +#include "classfile/systemDictionaryShared.hpp" #include "classfile/verifier.hpp" #include "classfile/vmClasses.hpp" #include "classfile/vmSymbols.hpp" @@ -211,6 +212,12 @@ exception_name == vmSymbols::java_lang_ClassFormatError())) { log_info(verification)("Fail over class verification to old verifier for: %s", klass->external_name()); log_info(class, init)("Fail over class verification to old verifier for: %s", klass->external_name()); + // Exclude any classes that fail over during dynamic dumping + if (CDS_ONLY(DynamicDumpSharedSpaces) NOT_CDS(false)) { + ResourceMark rm; + log_warning(cds)("Skipping %s: Failed over class verification while dynamic dumping", klass->name()->as_C_string()); + SystemDictionaryShared::set_excluded(klass); + } message_buffer = NEW_RESOURCE_ARRAY(char, message_buffer_len); exception_message = message_buffer; exception_name = inference_verify( diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/code/codeCache.cpp openjdk-17-17.0.13+11/src/hotspot/share/code/codeCache.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/code/codeCache.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/code/codeCache.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -101,22 +101,37 @@ scopes_pcs_size = 0; } - int total() { return total_size; } - bool is_empty() { return count == 0; } + int total() const { return total_size; } + bool is_empty() const { return count == 0; } - void print(const char* title) { - tty->print_cr(" #%d %s = %dK (hdr %d%%, loc %d%%, code %d%%, stub %d%%, [oops %d%%, metadata %d%%, data %d%%, pcs %d%%])", - count, - title, - (int)(total() / K), - header_size * 100 / total_size, - relocation_size * 100 / total_size, - code_size * 100 / total_size, - stub_size * 100 / total_size, - scopes_oop_size * 100 / total_size, - scopes_metadata_size * 100 / total_size, - scopes_data_size * 100 / total_size, - scopes_pcs_size * 100 / total_size); + void print(const char* title) const { + if (is_empty()) { + tty->print_cr(" #%d %s = %dK", + count, + title, + total() / (int)K); + } else { + tty->print_cr(" #%d %s = %dK (hdr %dK %d%%, loc %dK %d%%, code %dK %d%%, stub %dK %d%%, [oops %dK %d%%, metadata %dK %d%%, data %dK %d%%, pcs %dK %d%%])", + count, + title, + total() / (int)K, + header_size / (int)K, + header_size * 100 / total_size, + relocation_size / (int)K, + relocation_size * 100 / total_size, + code_size / (int)K, + code_size * 100 / total_size, + stub_size / (int)K, + stub_size * 100 / total_size, + scopes_oop_size / (int)K, + scopes_oop_size * 100 / total_size, + scopes_metadata_size / (int)K, + scopes_metadata_size * 100 / total_size, + scopes_data_size / (int)K, + scopes_data_size * 100 / total_size, + scopes_pcs_size / (int)K, + scopes_pcs_size * 100 / total_size); + } } void add(CodeBlob* cb) { @@ -1468,27 +1483,73 @@ #ifndef PRODUCT if (!Verbose) return; - CodeBlob_sizes live; - CodeBlob_sizes dead; + CodeBlob_sizes live[CompLevel_full_optimization + 1]; + CodeBlob_sizes dead[CompLevel_full_optimization + 1]; + CodeBlob_sizes runtimeStub; + CodeBlob_sizes uncommonTrapStub; + CodeBlob_sizes deoptimizationStub; + CodeBlob_sizes adapter; + CodeBlob_sizes bufferBlob; + CodeBlob_sizes other; FOR_ALL_ALLOCABLE_HEAPS(heap) { FOR_ALL_BLOBS(cb, *heap) { - if (!cb->is_alive()) { - dead.add(cb); + if (cb->is_nmethod()) { + const int level = cb->as_nmethod()->comp_level(); + assert(0 <= level && level <= CompLevel_full_optimization, "Invalid compilation level"); + if (!cb->is_alive()) { + dead[level].add(cb); + } else { + live[level].add(cb); + } + } else if (cb->is_runtime_stub()) { + runtimeStub.add(cb); + } else if (cb->is_deoptimization_stub()) { + deoptimizationStub.add(cb); + } else if (cb->is_uncommon_trap_stub()) { + uncommonTrapStub.add(cb); + } else if (cb->is_adapter_blob()) { + adapter.add(cb); + } else if (cb->is_buffer_blob()) { + bufferBlob.add(cb); } else { - live.add(cb); + other.add(cb); } } } - tty->print_cr("CodeCache:"); tty->print_cr("nmethod dependency checking time %fs", dependentCheckTime.seconds()); - if (!live.is_empty()) { - live.print("live"); - } - if (!dead.is_empty()) { - dead.print("dead"); + tty->print_cr("nmethod blobs per compilation level:"); + for (int i = 0; i <= CompLevel_full_optimization; i++) { + const char *level_name; + switch (i) { + case CompLevel_none: level_name = "none"; break; + case CompLevel_simple: level_name = "simple"; break; + case CompLevel_limited_profile: level_name = "limited profile"; break; + case CompLevel_full_profile: level_name = "full profile"; break; + case CompLevel_full_optimization: level_name = "full optimization"; break; + default: assert(false, "invalid compilation level"); + } + tty->print_cr("%s:", level_name); + live[i].print("live"); + dead[i].print("dead"); + } + + struct { + const char* name; + const CodeBlob_sizes* sizes; + } non_nmethod_blobs[] = { + { "runtime", &runtimeStub }, + { "uncommon trap", &uncommonTrapStub }, + { "deoptimization", &deoptimizationStub }, + { "adapter", &adapter }, + { "buffer blob", &bufferBlob }, + { "other", &other }, + }; + tty->print_cr("Non-nmethod blobs:"); + for (auto& blob: non_nmethod_blobs) { + blob.sizes->print(blob.name); } if (WizardMode) { diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/code/dependencies.cpp openjdk-17-17.0.13+11/src/hotspot/share/code/dependencies.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/code/dependencies.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/code/dependencies.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -769,7 +769,8 @@ xtty->object("x", arg.metadata_value()); } } else { - char xn[12]; sprintf(xn, "x%d", j); + char xn[12]; + os::snprintf_checked(xn, sizeof(xn), "x%d", j); if (arg.is_oop()) { xtty->object(xn, Handle(thread, arg.oop_value())); } else { diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/code/nmethod.cpp openjdk-17-17.0.13+11/src/hotspot/share/code/nmethod.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/code/nmethod.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/code/nmethod.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -1550,7 +1550,7 @@ assert_locked_or_safepoint(CodeCache_lock); // completely deallocate this method - Events::log(JavaThread::current(), "flushing nmethod " INTPTR_FORMAT, p2i(this)); + Events::log_nmethod_flush(Thread::current(), "flushing %s nmethod " INTPTR_FORMAT, is_osr_method() ? "osr" : "", p2i(this)); if (PrintMethodFlushing) { tty->print_cr("*flushing %s nmethod %3d/" INTPTR_FORMAT ". Live blobs:" UINT32_FORMAT "/Free CodeCache:" SIZE_FORMAT "Kb", diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/compiler/compilationPolicy.cpp openjdk-17-17.0.13+11/src/hotspot/share/compiler/compilationPolicy.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/compiler/compilationPolicy.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/compiler/compilationPolicy.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -1011,7 +1011,7 @@ if (force_comp_at_level_simple(method)) { next_level = CompLevel_simple; } else { - if (is_trivial(method)) { + if (is_trivial(method) || method->is_native()) { next_level = CompilationModeFlag::disable_intermediate() ? CompLevel_full_optimization : CompLevel_simple; } else { switch(cur_level) { diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/compiler/compileBroker.cpp openjdk-17-17.0.13+11/src/hotspot/share/compiler/compileBroker.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/compiler/compileBroker.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/compiler/compileBroker.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -998,7 +998,7 @@ // for JVMCI compiler which can create further ones on demand. JVMCI_ONLY(if (!UseJVMCICompiler || !UseDynamicNumberOfCompilerThreads || i == 0) {) // Create a name for our thread. - sprintf(name_buffer, "%s CompilerThread%d", _compilers[1]->name(), i); + os::snprintf_checked(name_buffer, sizeof(name_buffer), "%s CompilerThread%d", _compilers[1]->name(), i); Handle thread_oop = create_thread_oop(name_buffer, CHECK); thread_handle = JNIHandles::make_global(thread_oop); JVMCI_ONLY(}) @@ -1022,7 +1022,7 @@ for (int i = 0; i < _c1_count; i++) { // Create a name for our thread. - sprintf(name_buffer, "C1 CompilerThread%d", i); + os::snprintf_checked(name_buffer, sizeof(name_buffer), "C1 CompilerThread%d", i); Handle thread_oop = create_thread_oop(name_buffer, CHECK); jobject thread_handle = JNIHandles::make_global(thread_oop); _compiler1_objects[i] = thread_handle; @@ -1095,7 +1095,7 @@ // transitions if we bind them to new JavaThreads. if (!THREAD->can_call_java()) break; char name_buffer[256]; - sprintf(name_buffer, "%s CompilerThread%d", _compilers[1]->name(), i); + os::snprintf_checked(name_buffer, sizeof(name_buffer), "%s CompilerThread%d", _compilers[1]->name(), i); Handle thread_oop; { // We have to give up the lock temporarily for the Java calls. @@ -2731,7 +2731,7 @@ char tier_name[256]; for (int tier = CompLevel_simple; tier <= CompilationPolicy::highest_compile_level(); tier++) { CompilerStatistics* stats = &_stats_per_level[tier-1]; - sprintf(tier_name, "Tier%d", tier); + os::snprintf_checked(tier_name, sizeof(tier_name), "Tier%d", tier); print_times(tier_name, stats); } } diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/gc/g1/g1Allocator.cpp openjdk-17-17.0.13+11/src/hotspot/share/gc/g1/g1Allocator.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/gc/g1/g1Allocator.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/gc/g1/g1Allocator.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -192,11 +192,14 @@ uint node_index = current_node_index(); HeapRegion* hr = mutator_alloc_region(node_index)->get(); size_t max_tlab = _g1h->max_tlab_size() * wordSize; - if (hr == NULL) { + + if (hr == NULL || hr->free() < MinTLABSize) { + // The next TLAB allocation will most probably happen in a new region, + // therefore we can attempt to allocate the maximum allowed TLAB size. return max_tlab; - } else { - return clamp(hr->free(), MinTLABSize, max_tlab); } + + return MIN2(hr->free(), max_tlab); } size_t G1Allocator::used_in_alloc_regions() { @@ -292,6 +295,8 @@ for (uint node_index = 0; node_index < length; node_index++) { _alloc_buffers[state][node_index] = new PLAB(_g1h->desired_plab_sz(state)); } + _num_plab_fills[state] = 0; + _num_direct_allocations[state] = 0; } } @@ -324,6 +329,8 @@ PLAB* alloc_buf = alloc_buffer(dest, node_index); alloc_buf->retire(); + _num_plab_fills[dest.type()]++; + size_t actual_plab_size = 0; HeapWord* buf = _allocator->par_allocate_during_gc(dest, required_in_plab, @@ -332,7 +339,7 @@ node_index); assert(buf == NULL || ((actual_plab_size >= required_in_plab) && (actual_plab_size <= plab_word_size)), - "Requested at minimum " SIZE_FORMAT ", desired " SIZE_FORMAT " words, but got " SIZE_FORMAT " at " PTR_FORMAT, + "Requested at minimum %zu, desired %zu words, but got %zu at " PTR_FORMAT, required_in_plab, plab_word_size, actual_plab_size, p2i(buf)); if (buf != NULL) { @@ -340,7 +347,7 @@ HeapWord* const obj = alloc_buf->allocate(word_sz); assert(obj != NULL, "PLAB should have been big enough, tried to allocate " - SIZE_FORMAT " requiring " SIZE_FORMAT " PLAB size " SIZE_FORMAT, + "%zu requiring %zu PLAB size %zu", word_sz, required_in_plab, plab_word_size); return obj; } @@ -351,6 +358,7 @@ HeapWord* result = _allocator->par_allocate_during_gc(dest, word_sz, node_index); if (result != NULL) { _direct_allocated[dest.type()] += word_sz; + _num_direct_allocations[dest.type()]++; } return result; } @@ -368,8 +376,9 @@ buf->flush_and_retire_stats(stats); } } + stats->add_num_plab_filled(_num_plab_fills[state]); stats->add_direct_allocated(_direct_allocated[state]); - _direct_allocated[state] = 0; + stats->add_num_direct_allocated(_num_direct_allocations[state]); } } diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/gc/g1/g1Allocator.hpp openjdk-17-17.0.13+11/src/hotspot/share/gc/g1/g1Allocator.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/gc/g1/g1Allocator.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/gc/g1/g1Allocator.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -161,6 +161,10 @@ // Number of words allocated directly (not counting PLAB allocation). size_t _direct_allocated[G1HeapRegionAttr::Num]; + // Number of PLAB refills experienced so far. + size_t _num_plab_fills[G1HeapRegionAttr::Num]; + size_t _num_direct_allocations[G1HeapRegionAttr::Num]; + void flush_and_retire_stats(); inline PLAB* alloc_buffer(G1HeapRegionAttr dest, uint node_index) const; inline PLAB* alloc_buffer(region_type_t dest, uint node_index) const; diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/gc/g1/g1CollectedHeap.cpp openjdk-17-17.0.13+11/src/hotspot/share/gc/g1/g1CollectedHeap.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/gc/g1/g1CollectedHeap.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/gc/g1/g1CollectedHeap.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -2545,7 +2545,8 @@ G1EvacSummary G1CollectedHeap::create_g1_evac_summary(G1EvacStats* stats) { return G1EvacSummary(stats->allocated(), stats->wasted(), stats->undo_wasted(), stats->unused(), stats->used(), stats->region_end_waste(), - stats->regions_filled(), stats->direct_allocated(), + stats->regions_filled(), stats->num_plab_filled(), + stats->direct_allocated(), stats->num_direct_allocated(), stats->failure_used(), stats->failure_waste()); } diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/gc/g1/g1EvacStats.cpp openjdk-17-17.0.13+11/src/hotspot/share/gc/g1/g1EvacStats.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/gc/g1/g1EvacStats.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/gc/g1/g1EvacStats.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -33,15 +33,19 @@ void G1EvacStats::log_plab_allocation() { PLABStats::log_plab_allocation(); log_debug(gc, plab)("%s other allocation: " - "region end waste: " SIZE_FORMAT "B, " + "region end waste: %zuB, " "regions filled: %u, " - "direct allocated: " SIZE_FORMAT "B, " - "failure used: " SIZE_FORMAT "B, " - "failure wasted: " SIZE_FORMAT "B", + "num plab filled: %zu, " + "direct allocated: %zuB, " + "num direct allocated: %zu, " + "failure used: %zuB, " + "failure wasted: %zuB", _description, _region_end_waste * HeapWordSize, _regions_filled, + _num_plab_filled, _direct_allocated * HeapWordSize, + _num_direct_allocated, _failure_used * HeapWordSize, _failure_waste * HeapWordSize); } @@ -94,7 +98,9 @@ PLABStats(description, default_per_thread_plab_size, default_per_thread_plab_size * ParallelGCThreads, wt), _region_end_waste(0), _regions_filled(0), + _num_plab_filled(0), _direct_allocated(0), + _num_direct_allocated(0), _failure_used(0), _failure_waste(0) { } diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/gc/g1/g1EvacStats.hpp openjdk-17-17.0.13+11/src/hotspot/share/gc/g1/g1EvacStats.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/gc/g1/g1EvacStats.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/gc/g1/g1EvacStats.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -32,7 +32,9 @@ private: size_t _region_end_waste; // Number of words wasted due to skipping to the next region. uint _regions_filled; // Number of regions filled completely. + size_t _num_plab_filled; // Number of PLABs filled and retired. size_t _direct_allocated; // Number of words allocated directly into the regions. + size_t _num_direct_allocated; // Number of direct allocation attempts. // Number of words in live objects remaining in regions that ultimately suffered an // evacuation failure. This is used in the regions when the regions are made old regions. @@ -46,7 +48,9 @@ PLABStats::reset(); _region_end_waste = 0; _regions_filled = 0; + _num_plab_filled = 0; _direct_allocated = 0; + _num_direct_allocated = 0; _failure_used = 0; _failure_waste = 0; } @@ -61,15 +65,19 @@ ~G1EvacStats(); uint regions_filled() const { return _regions_filled; } + size_t num_plab_filled() const { return _num_plab_filled; } size_t region_end_waste() const { return _region_end_waste; } size_t direct_allocated() const { return _direct_allocated; } + size_t num_direct_allocated() const { return _num_direct_allocated; } // Amount of space in heapwords used in the failing regions when an evacuation failure happens. size_t failure_used() const { return _failure_used; } // Amount of space in heapwords wasted (unused) in the failing regions when an evacuation failure happens. size_t failure_waste() const { return _failure_waste; } + inline void add_num_plab_filled(size_t value); inline void add_direct_allocated(size_t value); + inline void add_num_direct_allocated(size_t value); inline void add_region_end_waste(size_t value); inline void add_failure_used_and_waste(size_t used, size_t waste); }; diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/gc/g1/g1EvacStats.inline.hpp openjdk-17-17.0.13+11/src/hotspot/share/gc/g1/g1EvacStats.inline.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/gc/g1/g1EvacStats.inline.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/gc/g1/g1EvacStats.inline.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -33,6 +33,14 @@ Atomic::add(&_direct_allocated, value); } +inline void G1EvacStats::add_num_plab_filled(size_t value) { + Atomic::add(&_num_plab_filled, value); +} + +inline void G1EvacStats::add_num_direct_allocated(size_t value) { + Atomic::add(&_num_direct_allocated, value); +} + inline void G1EvacStats::add_region_end_waste(size_t value) { Atomic::add(&_region_end_waste, value); Atomic::inc(&_regions_filled); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp openjdk-17-17.0.13+11/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -169,22 +169,6 @@ _major_timer.start(); } -// If the remaining free space in the old generation is less that -// that expected to be needed by the next collection, do a full -// collection now. -bool PSAdaptiveSizePolicy::should_full_GC(size_t old_free_in_bytes) { - - // A similar test is done in the scavenge's should_attempt_scavenge(). If - // this is changed, decide if that test should also be changed. - bool result = padded_average_promoted_in_bytes() > (float) old_free_in_bytes; - log_trace(gc, ergo)("%s after scavenge average_promoted " SIZE_FORMAT " padded_average_promoted " SIZE_FORMAT " free in old gen " SIZE_FORMAT, - result ? "Full" : "No full", - (size_t) average_promoted_in_bytes(), - (size_t) padded_average_promoted_in_bytes(), - old_free_in_bytes); - return result; -} - void PSAdaptiveSizePolicy::clear_generation_free_space_flags() { AdaptiveSizePolicy::clear_generation_free_space_flags(); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp openjdk-17-17.0.13+11/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -306,10 +306,6 @@ } float major_collection_slope() { return _major_collection_estimator->slope();} - // Given the amount of live data in the heap, should we - // perform a Full GC? - bool should_full_GC(size_t live_in_old_gen); - // Calculates optimal (free) space sizes for both the young and old // generations. Stores results in _eden_size and _promo_size. // Takes current used space in all generations as input, as well diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/gc/parallel/psScavenge.cpp openjdk-17-17.0.13+11/src/hotspot/share/gc/parallel/psScavenge.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/gc/parallel/psScavenge.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/gc/parallel/psScavenge.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -238,8 +238,7 @@ IsGCActiveMark mark; const bool scavenge_done = PSScavenge::invoke_no_policy(); - const bool need_full_gc = !scavenge_done || - policy->should_full_GC(heap->old_gen()->free_in_bytes()); + const bool need_full_gc = !scavenge_done; bool full_gc_done = false; if (UsePerfData) { @@ -739,8 +738,6 @@ // Test to see if the scavenge will likely fail. PSAdaptiveSizePolicy* policy = heap->size_policy(); - // A similar test is done in the policy's should_full_GC(). If this is - // changed, decide if that test should also be changed. size_t avg_promoted = (size_t) policy->padded_average_promoted_in_bytes(); size_t promotion_estimate = MIN2(avg_promoted, young_gen->used_in_bytes()); bool result = promotion_estimate < old_gen->free_in_bytes(); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/gc/shared/gcHeapSummary.hpp openjdk-17-17.0.13+11/src/hotspot/share/gc/shared/gcHeapSummary.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/gc/shared/gcHeapSummary.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/gc/shared/gcHeapSummary.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -177,7 +177,9 @@ size_t _region_end_waste; // Number of words wasted due to skipping to the next region. uint _regions_filled; // Number of regions filled completely. + size_t _num_plab_filled; // Number of PLABs refilled/retired. size_t _direct_allocated; // Number of words allocated directly into the regions. + size_t _num_direct_allocated; // Number of direct allocations. // Number of words in live objects remaining in regions that ultimately suffered an // evacuation failure. This is used in the regions when the regions are made old regions. @@ -187,12 +189,23 @@ // end of regions. size_t _failure_waste; public: - G1EvacSummary(size_t allocated, size_t wasted, size_t undo_wasted, size_t unused, - size_t used, size_t region_end_waste, uint regions_filled, size_t direct_allocated, - size_t failure_used, size_t failure_waste) : + G1EvacSummary(size_t allocated, + size_t wasted, + size_t undo_wasted, + size_t unused, + size_t used, + size_t region_end_waste, + uint regions_filled, + size_t num_plab_filled, + size_t direct_allocated, + size_t num_direct_allocated, + size_t failure_used, + size_t failure_waste) : _allocated(allocated), _wasted(wasted), _undo_wasted(undo_wasted), _unused(unused), - _used(used), _region_end_waste(region_end_waste), _regions_filled(regions_filled), - _direct_allocated(direct_allocated), _failure_used(failure_used), _failure_waste(failure_waste) + _used(used), _region_end_waste(region_end_waste), + _regions_filled(regions_filled), _num_plab_filled(num_plab_filled), + _direct_allocated(direct_allocated),_num_direct_allocated(num_direct_allocated), + _failure_used(failure_used), _failure_waste(failure_waste) { } size_t allocated() const { return _allocated; } @@ -202,7 +215,9 @@ size_t used() const { return _used; } size_t region_end_waste() const { return _region_end_waste; } uint regions_filled() const { return _regions_filled; } + size_t num_plab_filled() const { return _num_plab_filled; } size_t direct_allocated() const { return _direct_allocated; } + size_t num_direct_allocated() const { return _num_direct_allocated; } size_t failure_used() const { return _failure_used; } size_t failure_waste() const { return _failure_waste; } }; diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/gc/shared/memAllocator.cpp openjdk-17-17.0.13+11/src/hotspot/share/gc/shared/memAllocator.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/gc/shared/memAllocator.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/gc/shared/memAllocator.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -308,18 +308,15 @@ PTR_FORMAT " min: " SIZE_FORMAT ", desired: " SIZE_FORMAT, p2i(mem), min_tlab_size, new_tlab_size); + // ...and clear or zap just allocated TLAB, if needed. if (ZeroTLAB) { - // ..and clear it. Copy::zero_to_words(mem, allocation._allocated_tlab_size); - } else { - // ...and zap just allocated object. -#ifdef ASSERT + } else if (ZapTLAB) { // Skip mangling the space corresponding to the object header to // ensure that the returned space is not considered parsable by // any concurrent GC thread. size_t hdr_size = oopDesc::header_size(); Copy::fill_to_words(mem + hdr_size, allocation._allocated_tlab_size - hdr_size, badHeapWordVal); -#endif // ASSERT } tlab.fill(mem, mem + _word_size, allocation._allocated_tlab_size); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/gc/shared/oopStorage.inline.hpp openjdk-17-17.0.13+11/src/hotspot/share/gc/shared/oopStorage.inline.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/gc/shared/oopStorage.inline.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/gc/shared/oopStorage.inline.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -28,8 +28,6 @@ #include "gc/shared/oopStorage.hpp" #include "memory/allocation.hpp" -#include "metaprogramming/conditional.hpp" -#include "metaprogramming/isConst.hpp" #include "oops/oop.hpp" #include "runtime/safepoint.hpp" #include "utilities/align.hpp" @@ -37,6 +35,8 @@ #include "utilities/debug.hpp" #include "utilities/globalDefinitions.hpp" +#include + // Array of all active blocks. Refcounted for lock-free reclaim of // old array when a new array is allocated for expansion. class OopStorage::ActiveArray { @@ -361,7 +361,7 @@ assert_at_safepoint(); // Propagate const/non-const iteration to the block layer, by using // const or non-const blocks as corresponding to Storage. - typedef typename Conditional::value, const Block*, Block*>::type BlockPtr; + using BlockPtr = std::conditional_t::value, const Block*, Block*>; ActiveArray* blocks = storage->_active_array; size_t limit = blocks->block_count(); for (size_t i = 0; i < limit; ++i) { diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/gc/shared/oopStorageParState.hpp openjdk-17-17.0.13+11/src/hotspot/share/gc/shared/oopStorageParState.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/gc/shared/oopStorageParState.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/gc/shared/oopStorageParState.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -28,6 +28,8 @@ #include "gc/shared/oopStorage.hpp" #include "utilities/globalDefinitions.hpp" +#include + ////////////////////////////////////////////////////////////////////////////// // Support for parallel and optionally concurrent state iteration. // @@ -167,9 +169,7 @@ class OopStorage::ParState { BasicParState _basic_state; - typedef typename Conditional::type StoragePtr; + using StoragePtr = std::conditional_t; public: ParState(StoragePtr storage, diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/gc/shared/oopStorageParState.inline.hpp openjdk-17-17.0.13+11/src/hotspot/share/gc/shared/oopStorageParState.inline.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/gc/shared/oopStorageParState.inline.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/gc/shared/oopStorageParState.inline.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -28,9 +28,10 @@ #include "gc/shared/oopStorageParState.hpp" #include "gc/shared/oopStorage.inline.hpp" -#include "metaprogramming/conditional.hpp" #include "utilities/macros.hpp" +#include + template class OopStorage::BasicParState::AlwaysTrueFn { F _f; @@ -56,7 +57,7 @@ while (claim_next_segment(&data)) { assert(data._segment_start < data._segment_end, "invariant"); assert(data._segment_end <= _block_count, "invariant"); - typedef typename Conditional::type BlockPtr; + using BlockPtr = std::conditional_t; size_t i = data._segment_start; do { BlockPtr block = _active_array->at(i); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/gc/shared/threadLocalAllocBuffer.inline.hpp openjdk-17-17.0.13+11/src/hotspot/share/gc/shared/threadLocalAllocBuffer.inline.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/gc/shared/threadLocalAllocBuffer.inline.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/gc/shared/threadLocalAllocBuffer.inline.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -39,14 +39,8 @@ invariants(); HeapWord* obj = top(); if (pointer_delta(end(), obj) >= size) { - // successful thread-local allocation -#ifdef ASSERT - // Skip mangling the space corresponding to the object header to - // ensure that the returned space is not considered parsable by - // any concurrent GC thread. - size_t hdr_size = oopDesc::header_size(); - Copy::fill_to_words(obj + hdr_size, size - hdr_size, badHeapWordVal); -#endif // ASSERT + // Successful thread-local allocation. + // This addition is safe because we know that top is // at least size below end, so the add can't wrap. set_top(obj + size); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetNMethod.cpp openjdk-17-17.0.13+11/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetNMethod.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetNMethod.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetNMethod.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -36,13 +36,19 @@ #include "runtime/threadWXSetters.inline.hpp" bool ShenandoahBarrierSetNMethod::nmethod_entry_barrier(nmethod* nm) { + if (!is_armed(nm)) { + // Some other thread got here first and healed the oops + // and disarmed the nmethod. No need to continue. + return true; + } + ShenandoahReentrantLock* lock = ShenandoahNMethod::lock_for_nmethod(nm); assert(lock != NULL, "Must be"); ShenandoahReentrantLocker locker(lock); if (!is_armed(nm)) { - // Some other thread got here first and healed the oops - // and disarmed the nmethod. + // Some other thread managed to complete while we were + // waiting for lock. No need to continue. return true; } diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp openjdk-17-17.0.13+11/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,6 @@ /* - * Copyright (c) 2017, 2021, Red Hat, Inc. All rights reserved. + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, 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 @@ -163,13 +164,6 @@ AbstractGangTask("Shenandoah Disarm NMethods"), _iterator(ShenandoahCodeRoots::table()) { assert(SafepointSynchronize::is_at_safepoint(), "Only at a safepoint"); - MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - _iterator.nmethods_do_begin(); - } - - ~ShenandoahDisarmNMethodsTask() { - MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - _iterator.nmethods_do_end(); } virtual void work(uint worker_id) { @@ -269,15 +263,7 @@ AbstractGangTask("Shenandoah Unlink NMethods"), _cl(unloading_occurred), _verifier(verifier), - _iterator(ShenandoahCodeRoots::table()) { - MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - _iterator.nmethods_do_begin(); - } - - ~ShenandoahUnlinkTask() { - MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - _iterator.nmethods_do_end(); - } + _iterator(ShenandoahCodeRoots::table()) {} virtual void work(uint worker_id) { ICRefillVerifierMark mark(_verifier); @@ -329,15 +315,7 @@ ShenandoahNMethodPurgeTask() : AbstractGangTask("Shenandoah Purge NMethods"), _cl(), - _iterator(ShenandoahCodeRoots::table()) { - MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - _iterator.nmethods_do_begin(); - } - - ~ShenandoahNMethodPurgeTask() { - MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - _iterator.nmethods_do_end(); - } + _iterator(ShenandoahCodeRoots::table()) {} virtual void work(uint worker_id) { _iterator.nmethods_do(&_cl); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp openjdk-17-17.0.13+11/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,6 @@ /* - * Copyright (c) 2021, Red Hat, Inc. All rights reserved. + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, 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 @@ -748,18 +749,9 @@ _vm_roots(phase), _cld_roots(phase, ShenandoahHeap::heap()->workers()->active_workers()), _nmethod_itr(ShenandoahCodeRoots::table()), - _phase(phase) { - if (ShenandoahHeap::heap()->unload_classes()) { - MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - _nmethod_itr.nmethods_do_begin(); - } - } + _phase(phase) {} ~ShenandoahConcurrentWeakRootsEvacUpdateTask() { - if (ShenandoahHeap::heap()->unload_classes()) { - MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - _nmethod_itr.nmethods_do_end(); - } // Notify runtime data structures of potentially dead oops _vm_roots.report_num_dead(); } @@ -860,19 +852,7 @@ _phase(phase), _vm_roots(phase), _cld_roots(phase, ShenandoahHeap::heap()->workers()->active_workers()), - _nmethod_itr(ShenandoahCodeRoots::table()) { - if (!ShenandoahHeap::heap()->unload_classes()) { - MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - _nmethod_itr.nmethods_do_begin(); - } - } - - ~ShenandoahConcurrentRootsEvacUpdateTask() { - if (!ShenandoahHeap::heap()->unload_classes()) { - MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - _nmethod_itr.nmethods_do_end(); - } - } + _nmethod_itr(ShenandoahCodeRoots::table()) {} void work(uint worker_id) { ShenandoahConcurrentWorkerSession worker_session(worker_id); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp openjdk-17-17.0.13+11/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -361,11 +361,13 @@ _compact_point = _to_region->bottom(); } - // Object fits into current region, record new location: + // Object fits into current region, record new location, if object does not move: assert(_compact_point + obj_size <= _to_region->end(), "must fit"); shenandoah_assert_not_forwarded(NULL, p); - _preserved_marks->push_if_necessary(p, p->mark()); - p->forward_to(cast_to_oop(_compact_point)); + if (_compact_point != cast_from_oop(p)) { + _preserved_marks->push_if_necessary(p, p->mark()); + p->forward_to(cast_to_oop(_compact_point)); + } _compact_point += obj_size; } }; @@ -845,6 +847,7 @@ if (p->is_forwarded()) { HeapWord* compact_from = cast_from_oop(p); HeapWord* compact_to = cast_from_oop(p->forwardee()); + assert(compact_from != compact_to, "Forwarded object should move"); Copy::aligned_conjoint_words(compact_from, compact_to, size); oop new_obj = cast_to_oop(compact_to); new_obj->init_mark(); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp openjdk-17-17.0.13+11/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -778,18 +778,15 @@ assert (size <= actual_size, "allocation should fit"); + // ...and clear or zap just allocated TLAB, if needed. if (ZeroTLAB) { - // ..and clear it. Copy::zero_to_words(gclab_buf, actual_size); - } else { - // ...and zap just allocated object. -#ifdef ASSERT + } else if (ZapTLAB) { // Skip mangling the space corresponding to the object header to // ensure that the returned space is not considered parsable by // any concurrent GC thread. size_t hdr_size = oopDesc::header_size(); Copy::fill_to_words(gclab_buf + hdr_size, actual_size - hdr_size, badHeapWordVal); -#endif // ASSERT } gclab->set_buf(gclab_buf, actual_size); return gclab->allocate(size); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp openjdk-17-17.0.13+11/src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,6 @@ /* - * Copyright (c) 2019, 2021, Red Hat, Inc. All rights reserved. + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, 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 @@ -28,6 +29,7 @@ #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahNMethod.inline.hpp" #include "memory/resourceArea.hpp" +#include "runtime/safepointVerifiers.hpp" ShenandoahNMethod::ShenandoahNMethod(nmethod* nm, GrowableArray& oops, bool non_immediate_oops) : _nm(nm), _oops(NULL), _oops_count(0), _unregistered(false) { @@ -542,21 +544,40 @@ } ShenandoahConcurrentNMethodIterator::ShenandoahConcurrentNMethodIterator(ShenandoahNMethodTable* table) : - _table(table), _table_snapshot(NULL) { -} - -void ShenandoahConcurrentNMethodIterator::nmethods_do_begin() { - assert(CodeCache_lock->owned_by_self(), "Lock must be held"); - _table_snapshot = _table->snapshot_for_iteration(); -} + _table(table), + _table_snapshot(nullptr), + _started_workers(0), + _finished_workers(0) {} void ShenandoahConcurrentNMethodIterator::nmethods_do(NMethodClosure* cl) { - assert(_table_snapshot != NULL, "Must first call nmethod_do_begin()"); - _table_snapshot->concurrent_nmethods_do(cl); -} + // Cannot safepoint when iteration is running, because this can cause deadlocks + // with other threads waiting on iteration to be over. + NoSafepointVerifier nsv; + + MutexLocker ml(CodeCache_lock, Mutex::_no_safepoint_check_flag); + + if (_finished_workers > 0) { + // Some threads have already finished. We are now in rampdown: we are now + // waiting for all currently recorded workers to finish. No new workers + // should start. + return; + } -void ShenandoahConcurrentNMethodIterator::nmethods_do_end() { - assert(CodeCache_lock->owned_by_self(), "Lock must be held"); - _table->finish_iteration(_table_snapshot); - CodeCache_lock->notify_all(); + // Record a new worker and initialize the snapshot if it is a first visitor. + if (_started_workers++ == 0) { + _table_snapshot = _table->snapshot_for_iteration(); + } + + // All set, relinquish the lock and go concurrent. + { + MutexUnlocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); + _table_snapshot->concurrent_nmethods_do(cl); + } + + // Record completion. Last worker shuts down the iterator and notifies any waiters. + uint count = ++_finished_workers; + if (count == _started_workers) { + _table->finish_iteration(_table_snapshot); + CodeCache_lock->notify_all(); + } } diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/gc/shenandoah/shenandoahNMethod.hpp openjdk-17-17.0.13+11/src/hotspot/share/gc/shenandoah/shenandoahNMethod.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/gc/shenandoah/shenandoahNMethod.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/gc/shenandoah/shenandoahNMethod.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -187,13 +187,13 @@ private: ShenandoahNMethodTable* const _table; ShenandoahNMethodTableSnapshot* _table_snapshot; + uint _started_workers; + uint _finished_workers; public: ShenandoahConcurrentNMethodIterator(ShenandoahNMethodTable* table); - void nmethods_do_begin(); void nmethods_do(NMethodClosure* cl); - void nmethods_do_end(); }; #endif // SHARE_GC_SHENANDOAH_SHENANDOAHNMETHOD_HPP diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/gc/z/zSafeDelete.hpp openjdk-17-17.0.13+11/src/hotspot/share/gc/z/zSafeDelete.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/gc/z/zSafeDelete.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/gc/z/zSafeDelete.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -26,12 +26,13 @@ #include "gc/z/zArray.hpp" #include "gc/z/zLock.hpp" -#include "metaprogramming/removeExtent.hpp" + +#include template class ZSafeDeleteImpl { private: - typedef typename RemoveExtent::type ItemT; + using ItemT = std::remove_extent_t; ZLock* _lock; uint64_t _enabled; diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/gc/z/zSafeDelete.inline.hpp openjdk-17-17.0.13+11/src/hotspot/share/gc/z/zSafeDelete.inline.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/gc/z/zSafeDelete.inline.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/gc/z/zSafeDelete.inline.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -27,9 +27,10 @@ #include "gc/z/zSafeDelete.hpp" #include "gc/z/zArray.inline.hpp" -#include "metaprogramming/isArray.hpp" #include "utilities/debug.hpp" +#include + template ZSafeDeleteImpl::ZSafeDeleteImpl(ZLock* lock) : _lock(lock), @@ -49,7 +50,7 @@ template void ZSafeDeleteImpl::immediate_delete(ItemT* item) { - if (IsArray::value) { + if (std::is_array::value) { delete [] item; } else { delete item; diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/interpreter/bootstrapInfo.cpp openjdk-17-17.0.13+11/src/hotspot/share/interpreter/bootstrapInfo.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/interpreter/bootstrapInfo.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/interpreter/bootstrapInfo.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -230,9 +230,9 @@ st = st ? st : tty; if (_indy_index != -1) - sprintf(what, "indy#%d", decode_indy_index()); + os::snprintf_checked(what, sizeof(what), "indy#%d", decode_indy_index()); else - sprintf(what, "condy"); + os::snprintf_checked(what, sizeof(what), "condy"); bool have_msg = (msg != NULL && strlen(msg) > 0); st->print_cr("%s%sBootstrap in %s %s@CP[%d] %s:%s%s BSMS[%d] BSM@CP[%d]%s argc=%d%s", (have_msg ? msg : ""), (have_msg ? " " : ""), @@ -251,11 +251,11 @@ for (int i = 0; i < _argc; i++) { int pos = (int) strlen(argbuf); if (pos + 20 > (int)sizeof(argbuf)) { - sprintf(argbuf + pos, "..."); + os::snprintf_checked(argbuf + pos, sizeof(argbuf) - pos, "..."); break; } if (i > 0) argbuf[pos++] = ','; - sprintf(argbuf+pos, "%d", arg_index(i)); + os::snprintf_checked(argbuf+pos, sizeof(argbuf) - pos, "%d", arg_index(i)); } st->print_cr(" argument indexes: {%s}", argbuf); } diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/interpreter/zero/bytecodeInterpreter.cpp openjdk-17-17.0.13+11/src/hotspot/share/interpreter/zero/bytecodeInterpreter.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/interpreter/zero/bytecodeInterpreter.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/interpreter/zero/bytecodeInterpreter.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -1942,11 +1942,9 @@ size_t obj_size = ik->size_helper(); HeapWord* result = THREAD->tlab().allocate(obj_size); if (result != NULL) { - // Initialize object field block: - // - if TLAB is pre-zeroed, we can skip this path - // - in debug mode, ThreadLocalAllocBuffer::allocate mangles - // this area, and we still need to initialize it - if (DEBUG_ONLY(true ||) !ZeroTLAB) { + // Initialize object field block. + if (!ZeroTLAB) { + // The TLAB was not pre-zeroed, we need to clear the memory here. size_t hdr_size = oopDesc::header_size(); Copy::fill_to_words(result + hdr_size, obj_size - hdr_size, 0); } diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp openjdk-17-17.0.13+11/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -214,9 +214,6 @@ StackTraceBlobInstaller() : _cache(JfrOptionSet::old_object_queue_size()) { prepare_for_resolution(); } - ~StackTraceBlobInstaller() { - JfrStackTraceRepository::clear_leak_profiler(); - } void sample_do(ObjectSample* sample) { if (stack_trace_precondition(sample)) { install(sample); @@ -270,11 +267,14 @@ assert(LeakProfiler::is_running(), "invariant"); JavaThread* const thread = JavaThread::current(); DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(thread);) - // can safepoint here - ThreadInVMfromNative transition(thread); - MutexLocker lock(ClassLoaderDataGraph_lock); - // the lock is needed to ensure the unload lists do not grow in the middle of inspection. - install_stack_traces(sampler); + { + // can safepoint here + ThreadInVMfromNative transition(thread); + MutexLocker lock(ClassLoaderDataGraph_lock); + // the lock is needed to ensure the unload lists do not grow in the middle of inspection. + install_stack_traces(sampler); + } + JfrStackTraceRepository::clear_leak_profiler(); } static bool is_klass_unloaded(traceid klass_id) { diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/jfr/metadata/metadata.xml openjdk-17-17.0.13+11/src/hotspot/share/jfr/metadata/metadata.xml --- openjdk-17-17.0.12+7/src/hotspot/share/jfr/metadata/metadata.xml 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/jfr/metadata/metadata.xml 2024-10-10 14:01:59.000000000 +0000 @@ -350,7 +350,9 @@ + + @@ -658,7 +660,7 @@ - + diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp openjdk-17-17.0.13+11/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -103,6 +103,9 @@ // preallocate buffer count to each of the epoch live lists for (size_t i = 0; i < global_buffer_prealloc_count * 2; ++i) { Buffer* const buffer = mspace_allocate(global_buffer_size, _global_mspace); + if (buffer == nullptr) { + return false; + } _global_mspace->add_to_live_list(buffer, i % 2 == 0); } assert(_global_mspace->free_list_is_empty(), "invariant"); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp openjdk-17-17.0.13+11/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -228,7 +228,7 @@ writer->write(cld != NULL ? cld_id(cld, leakp) : 0); writer->write(mark_symbol(klass, leakp)); writer->write(package_id(klass, leakp)); - writer->write(get_flags(klass)); + writer->write(klass->modifier_flags()); writer->write(klass->is_hidden()); return 1; } @@ -429,8 +429,6 @@ assert(value != NULL, "invariant"); if (USED_PREVIOUS_EPOCH(value)) { callback->do_artifact(value); - assert(IS_NOT_SERIALIZED(value), "invariant"); - return; } if (IS_SERIALIZED(value)) { CLEAR_SERIALIZED(value); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp openjdk-17-17.0.13+11/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -207,7 +207,7 @@ const oop mirror = ik->java_mirror_no_keepalive(); assert(mirror != NULL, "invariant"); char hash_buf[40]; - sprintf(hash_buf, "/" UINTX_FORMAT, hash); + snprintf(hash_buf, sizeof(hash_buf), "/" UINTX_FORMAT, hash); const size_t hash_len = strlen(hash_buf); const size_t result_len = ik->name()->utf8_length(); hidden_symbol = NEW_RESOURCE_ARRAY(char, result_len + hash_len + 1); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdLoadBarrier.inline.hpp openjdk-17-17.0.13+11/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdLoadBarrier.inline.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdLoadBarrier.inline.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdLoadBarrier.inline.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -109,7 +109,14 @@ inline traceid JfrTraceIdLoadBarrier::load(const ClassLoaderData* cld) { assert(cld != NULL, "invariant"); - return cld->has_class_mirror_holder() ? 0 : set_used_and_get(cld); + if (cld->has_class_mirror_holder()) { + return 0; + } + const Klass* const class_loader_klass = cld->class_loader_klass(); + if (class_loader_klass != nullptr && should_tag(class_loader_klass)) { + load_barrier(class_loader_klass); + } + return set_used_and_get(cld); } inline traceid JfrTraceIdLoadBarrier::load_leakp(const Klass* klass, const Method* method) { diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp openjdk-17-17.0.13+11/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -350,13 +350,17 @@ const ssize_t read_result = os::read_at(current_fd, copy_block, (int)block_size, bytes_read); if (-1 == read_result) { log_info(jfr)( // For user, should not be "jfr, system" - "Unable to recover JFR data"); + "Unable to recover JFR data, read failed."); break; } bytes_read += (int64_t)read_result; assert(bytes_read - bytes_written <= (int64_t)block_size, "invariant"); - bytes_written += (int64_t)os::write(emergency_fd, copy_block, bytes_read - bytes_written); - assert(bytes_read == bytes_written, "invariant"); + if (!os::write(emergency_fd, copy_block, bytes_read - bytes_written)) { + log_info(jfr)( // For user, should not be "jfr, system" + "Unable to recover JFR data, write failed."); + break; + } + bytes_written = bytes_read; } os::close(current_fd); } diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp openjdk-17-17.0.13+11/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -543,9 +543,7 @@ ObjectSampleCheckpoint::on_rotation(ObjectSampler::acquire()); } write_storage(_storage, _chunkwriter); - if (_stack_trace_repository.is_modified()) { - write_stacktrace(_stack_trace_repository, _chunkwriter, false); - } + write_stacktrace(_stack_trace_repository, _chunkwriter, true); } void JfrRecorderService::invoke_safepoint_write() { diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTraceRepository.cpp openjdk-17-17.0.13+11/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTraceRepository.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTraceRepository.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTraceRepository.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -98,11 +98,10 @@ } size_t JfrStackTraceRepository::write(JfrChunkWriter& sw, bool clear) { + MutexLocker lock(JfrStacktrace_lock, Mutex::_no_safepoint_check_flag); if (_entries == 0) { return 0; } - MutexLocker lock(JfrStacktrace_lock, Mutex::_no_safepoint_check_flag); - assert(_entries > 0, "invariant"); int count = 0; for (u4 i = 0; i < TABLE_SIZE; ++i) { JfrStackTrace* stacktrace = _table[i]; diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/jfr/recorder/stringpool/jfrStringPool.cpp openjdk-17-17.0.13+11/src/hotspot/share/jfr/recorder/stringpool/jfrStringPool.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/jfr/recorder/stringpool/jfrStringPool.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/jfr/recorder/stringpool/jfrStringPool.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -85,6 +85,9 @@ // preallocate buffer count to each of the epoch live lists for (size_t i = 0; i < string_pool_cache_count * 2; ++i) { Buffer* const buffer = mspace_allocate(string_pool_buffer_size, _mspace); + if (buffer == nullptr) { + return false; + } _mspace->add_to_live_list(buffer, i % 2 == 0); } assert(_mspace->free_list_is_empty(), "invariant"); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/jfr/writers/jfrStreamWriterHost.inline.hpp openjdk-17-17.0.13+11/src/hotspot/share/jfr/writers/jfrStreamWriterHost.inline.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/jfr/writers/jfrStreamWriterHost.inline.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/jfr/writers/jfrStreamWriterHost.inline.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -76,14 +76,14 @@ assert(len >= 0, "invariant"); while (len > 0) { const unsigned int nBytes = len > INT_MAX ? INT_MAX : (unsigned int)len; - const ssize_t num_written = (ssize_t)os::write(_fd, buf, nBytes); - if (errno == ENOSPC) { + const bool successful_write = os::write(_fd, buf, nBytes); + if (!successful_write && errno == ENOSPC) { JfrJavaSupport::abort("Failed to write to jfr stream because no space left on device", false); } - guarantee(num_written > 0, "Nothing got written, or os::write() failed"); - _stream_pos += num_written; - len -= num_written; - buf += num_written; + guarantee(successful_write, "Not all the bytes got written, or os::write() failed"); + _stream_pos += nBytes; + len -= nBytes; + buf += nBytes; } } diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp openjdk-17-17.0.13+11/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -303,9 +303,9 @@ JVMCIObjectArray vmFields = JVMCIENV->new_VMField_array(len, JVMCI_CHECK_NULL); for (int i = 0; i < len ; i++) { VMStructEntry vmField = JVMCIVMStructs::localHotSpotVMStructs[i]; - size_t name_buf_len = strlen(vmField.typeName) + strlen(vmField.fieldName) + 2 /* "::" */; - char* name_buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, name_buf_len + 1); - sprintf(name_buf, "%s::%s", vmField.typeName, vmField.fieldName); + const size_t name_buf_size = strlen(vmField.typeName) + strlen(vmField.fieldName) + 2 + 1 /* "::" */; + char* name_buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, name_buf_size); + os::snprintf_checked(name_buf, name_buf_size, "%s::%s", vmField.typeName, vmField.fieldName); CSTRING_TO_JSTRING(name, name_buf); CSTRING_TO_JSTRING(type, vmField.typeString); JVMCIObject box; diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/memory/iterator.inline.hpp openjdk-17-17.0.13+11/src/hotspot/share/memory/iterator.inline.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/memory/iterator.inline.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/memory/iterator.inline.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -39,6 +39,8 @@ #include "oops/typeArrayKlass.inline.hpp" #include "utilities/debug.hpp" +#include + // Defaults to strong claiming. inline MetadataVisitingOopIterateClosure::MetadataVisitingOopIterateClosure(ReferenceDiscoverer* rd) : ClaimMetadataVisitingOopIterateClosure(ClassLoaderData::_claim_strong, rd) {} @@ -94,16 +96,16 @@ // p - The oop (or narrowOop) field to pass to the closure template -static typename EnableIf::value, void>::type +static typename EnableIf::value, void>::type call_do_oop(void (Receiver::*)(T*), void (Base::*)(T*), OopClosureType* closure, T* p) { closure->do_oop(p); } template -static typename EnableIf::value, void>::type +static typename EnableIf::value, void>::type call_do_oop(void (Receiver::*)(T*), void (Base::*)(T*), OopClosureType* closure, T* p) { // Sanity check - STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!std::is_same::value)); closure->OopClosureType::do_oop(p); } @@ -115,13 +117,13 @@ // Implementation of the non-virtual do_metadata dispatch. template -static typename EnableIf::value, bool>::type +static typename EnableIf::value, bool>::type call_do_metadata(bool (Receiver::*)(), bool (Base::*)(), OopClosureType* closure) { return closure->do_metadata(); } template -static typename EnableIf::value, bool>::type +static typename EnableIf::value, bool>::type call_do_metadata(bool (Receiver::*)(), bool (Base::*)(), OopClosureType* closure) { return closure->OopClosureType::do_metadata(); } @@ -134,13 +136,13 @@ // Implementation of the non-virtual do_klass dispatch. template -static typename EnableIf::value, void>::type +static typename EnableIf::value, void>::type call_do_klass(void (Receiver::*)(Klass*), void (Base::*)(Klass*), OopClosureType* closure, Klass* k) { closure->do_klass(k); } template -static typename EnableIf::value, void>::type +static typename EnableIf::value, void>::type call_do_klass(void (Receiver::*)(Klass*), void (Base::*)(Klass*), OopClosureType* closure, Klass* k) { closure->OopClosureType::do_klass(k); } @@ -153,13 +155,13 @@ // Implementation of the non-virtual do_cld dispatch. template -static typename EnableIf::value, void>::type +static typename EnableIf::value, void>::type call_do_cld(void (Receiver::*)(ClassLoaderData*), void (Base::*)(ClassLoaderData*), OopClosureType* closure, ClassLoaderData* cld) { closure->do_cld(cld); } template -static typename EnableIf::value, void>::type +static typename EnableIf::value, void>::type call_do_cld(void (Receiver::*)(ClassLoaderData*), void (Base::*)(ClassLoaderData*), OopClosureType* closure, ClassLoaderData* cld) { closure->OopClosureType::do_cld(cld); } diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/memory/metaspace/counters.hpp openjdk-17-17.0.13+11/src/hotspot/share/memory/metaspace/counters.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/memory/metaspace/counters.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/memory/metaspace/counters.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -26,11 +26,12 @@ #ifndef SHARE_MEMORY_METASPACE_COUNTERS_HPP #define SHARE_MEMORY_METASPACE_COUNTERS_HPP -#include "metaprogramming/isSigned.hpp" #include "runtime/atomic.hpp" #include "utilities/debug.hpp" #include "utilities/globalDefinitions.hpp" +#include + namespace metaspace { // We seem to be counting a lot of things which makes it worthwhile to @@ -43,7 +44,7 @@ T _c; // Only allow unsigned values for now - STATIC_ASSERT(IsSigned::value == false); + STATIC_ASSERT(std::is_signed::value == false); public: @@ -88,7 +89,7 @@ volatile T _c; // Only allow unsigned values for now - STATIC_ASSERT(IsSigned::value == false); + STATIC_ASSERT(std::is_signed::value == false); public: diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/memory/metaspace.cpp openjdk-17-17.0.13+11/src/hotspot/share/memory/metaspace.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/memory/metaspace.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/memory/metaspace.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -566,12 +566,6 @@ "wrong alignment"); MetaspaceContext::initialize_class_space_context(rs); - - // This does currently not work because rs may be the result of a split - // operation and NMT seems not to be able to handle splits. - // Will be fixed with JDK-8243535. - // MemTracker::record_virtual_memory_type((address)rs.base(), mtClass); - } // Returns true if class space has been setup (initialize_class_space). @@ -840,6 +834,9 @@ CompressedClassSpaceSize)); } + // Mark class space as such + MemTracker::record_virtual_memory_type((address)rs.base(), mtClass); + // Initialize space Metaspace::initialize_class_space(rs); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/conditional.hpp openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/conditional.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/conditional.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/conditional.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. - * 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. - * - */ - -#ifndef SHARE_METAPROGRAMMING_CONDITIONAL_HPP -#define SHARE_METAPROGRAMMING_CONDITIONAL_HPP - -#include "memory/allocation.hpp" - -// This trait evaluates its typedef called "type" to TrueType iff the condition -// is true. Otherwise it evaluates to FalseType. - -template -struct Conditional: AllStatic { - typedef TrueType type; -}; - -template -struct Conditional: AllStatic { - typedef FalseType type; -}; - -#endif // SHARE_METAPROGRAMMING_CONDITIONAL_HPP diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/decay.hpp openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/decay.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/decay.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/decay.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. - * 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. - * - */ - -#ifndef SHARE_METAPROGRAMMING_DECAY_HPP -#define SHARE_METAPROGRAMMING_DECAY_HPP - -#include "memory/allocation.hpp" -#include "metaprogramming/removeCV.hpp" -#include "metaprogramming/removeReference.hpp" - -// This trait trims the type from CV qualifiers and references. -// This trait provides a subset of the functionality of std::decay; -// array types and function types are not supported here. - -template -struct Decay: AllStatic { - typedef typename RemoveCV::type>::type type; -}; - -#endif // SHARE_METAPROGRAMMING_DECAY_HPP diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/integralConstant.hpp openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/integralConstant.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/integralConstant.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/integralConstant.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. - * 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. - * - */ - -#ifndef SHARE_METAPROGRAMMING_INTEGRALCONSTANT_HPP -#define SHARE_METAPROGRAMMING_INTEGRALCONSTANT_HPP - - -// An Integral Constant is a class providing a compile-time value of an -// integral type. An Integral Constant is also a nullary metafunction, -// returning itself. An integral constant object is implicitly -// convertible to the associated value. -// -// A type n is a model of Integral Constant if it meets the following -// requirements: -// -// n::ValueType : The integral type of n::value -// n::value : An integral constant expression -// n::type : IsSame::value is true -// n::value_type const c = n() : c == n::value - -// A model of the Integer Constant concept. -// T is an integral type, and is the value_type. -// v is an integral constant, and is the value. -template -struct IntegralConstant { - typedef T value_type; - static const value_type value = v; - typedef IntegralConstant type; - operator value_type() { return value; } -}; - -// A bool valued IntegralConstant whose value is true. -typedef IntegralConstant TrueType; - -// A bool valued IntegralConstant whose value is false. -typedef IntegralConstant FalseType; - -#endif // SHARE_METAPROGRAMMING_INTEGRALCONSTANT_HPP diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/isArray.hpp openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/isArray.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/isArray.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/isArray.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * 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. - * - */ - -#ifndef SHARE_METAPROGRAMMING_ISARRAY_HPP -#define SHARE_METAPROGRAMMING_ISARRAY_HPP - -#include "metaprogramming/integralConstant.hpp" - -template struct IsArray: public FalseType {}; - -template struct IsArray: public TrueType {}; -template struct IsArray: public TrueType {}; - -#endif // SHARE_METAPROGRAMMING_ISARRAY_HPP diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/isConst.hpp openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/isConst.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/isConst.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/isConst.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. - * 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. - * - */ - -#ifndef SHARE_METAPROGRAMMING_ISCONST_HPP -#define SHARE_METAPROGRAMMING_ISCONST_HPP - -#include "metaprogramming/integralConstant.hpp" - -template struct IsConst: public FalseType {}; -template struct IsConst: public TrueType {}; - -#endif // SHARE_METAPROGRAMMING_ISCONST_HPP diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/isFloatingPoint.hpp openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/isFloatingPoint.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/isFloatingPoint.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/isFloatingPoint.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. - * 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. - * - */ - -#ifndef SHARE_METAPROGRAMMING_ISFLOATINGPOINT_HPP -#define SHARE_METAPROGRAMMING_ISFLOATINGPOINT_HPP - -#include "metaprogramming/integralConstant.hpp" - -// This metafunction returns true iff the type T (irrespective of CV qualifiers) -// is a floating point type. - -template struct IsFloatingPoint: public FalseType {}; - -template <> struct IsFloatingPoint: public TrueType {}; -template <> struct IsFloatingPoint: public TrueType {}; -template <> struct IsFloatingPoint: public TrueType {}; -template <> struct IsFloatingPoint: public TrueType {}; - -template <> struct IsFloatingPoint: public TrueType {}; -template <> struct IsFloatingPoint: public TrueType {}; -template <> struct IsFloatingPoint: public TrueType {}; -template <> struct IsFloatingPoint: public TrueType {}; - -template <> struct IsFloatingPoint: public TrueType {}; -template <> struct IsFloatingPoint: public TrueType {}; -template <> struct IsFloatingPoint: public TrueType {}; -template <> struct IsFloatingPoint: public TrueType {}; - -#endif // SHARE_METAPROGRAMMING_ISFLOATINGPOINT_HPP diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/isIntegral.hpp openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/isIntegral.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/isIntegral.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/isIntegral.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. - * 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. - * - */ - - -#ifndef SHARE_METAPROGRAMMING_ISINTEGRAL_HPP -#define SHARE_METAPROGRAMMING_ISINTEGRAL_HPP - -#include "metaprogramming/integralConstant.hpp" -#include "metaprogramming/isSigned.hpp" -#include "metaprogramming/removeCV.hpp" -#include - -// This metafunction returns true iff the type T (irrespective of CV qualifiers) -// is an integral type. Note that this is false for enums. - -template -struct IsIntegral - : public IntegralConstant::type>::is_integer> -{}; - -// This metafunction returns true iff the type T (irrespective of CV qualifiers) -// is a signed integral type. Note that this is false for enums. - -template -struct IsSignedIntegral - : public IntegralConstant::value && IsSigned::value> -{}; - -// This metafunction returns true iff the type T (irrespective of CV qualifiers) -// is an unsigned integral type. Note that this is false for enums. - -template -struct IsUnsignedIntegral - : public IntegralConstant::value && !IsSigned::value> -{}; - -#endif // SHARE_METAPROGRAMMING_ISINTEGRAL_HPP diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/isPointer.hpp openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/isPointer.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/isPointer.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/isPointer.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. - * 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. - * - */ - -#ifndef SHARE_METAPROGRAMMING_ISPOINTER_HPP -#define SHARE_METAPROGRAMMING_ISPOINTER_HPP - -#include "metaprogramming/integralConstant.hpp" - -// This metafunction returns true iff the type T is (irrespective of CV qualifiers) -// a pointer type. - -template class IsPointer: public FalseType {}; - -template class IsPointer: public TrueType {}; -template class IsPointer: public TrueType {}; -template class IsPointer: public TrueType {}; -template class IsPointer: public TrueType {}; - -#endif // SHARE_METAPROGRAMMING_ISPOINTER_HPP diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/isSame.hpp openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/isSame.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/isSame.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/isSame.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. - * 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. - * - */ - -#ifndef SHARE_METAPROGRAMMING_ISSAME_HPP -#define SHARE_METAPROGRAMMING_ISSAME_HPP - -#include "metaprogramming/integralConstant.hpp" - -// This trait returns true iff the two types X and Y are the same - -template -struct IsSame: public FalseType {}; - -template -struct IsSame: public TrueType {}; - -#endif // SHARE_METAPROGRAMMING_ISSAME_HPP diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/isSigned.hpp openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/isSigned.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/isSigned.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/isSigned.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. - * 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. - * - */ - -#ifndef SHARE_METAPROGRAMMING_ISSIGNED_HPP -#define SHARE_METAPROGRAMMING_ISSIGNED_HPP - -#include "metaprogramming/integralConstant.hpp" -#include "metaprogramming/removeCV.hpp" -#include - -template -struct IsSigned - : public IntegralConstant::type>::is_signed> -{}; - -#endif // SHARE_METAPROGRAMMING_ISSIGNED_HPP diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/isVolatile.hpp openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/isVolatile.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/isVolatile.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/isVolatile.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. - * 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. - * - */ - -#ifndef SHARE_METAPROGRAMMING_ISVOLATILE_HPP -#define SHARE_METAPROGRAMMING_ISVOLATILE_HPP - -#include "metaprogramming/integralConstant.hpp" - -template struct IsVolatile: public FalseType {}; -template struct IsVolatile: public TrueType {}; - -#endif // SHARE_METAPROGRAMMING_ISVOLATILE_HPP diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/removeCV.hpp openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/removeCV.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/removeCV.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/removeCV.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. - * 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. - * - */ - -#ifndef SHARE_METAPROGRAMMING_REMOVECV_HPP -#define SHARE_METAPROGRAMMING_REMOVECV_HPP - -#include "memory/allocation.hpp" - -template -struct RemoveCV: AllStatic { - typedef T type; -}; - -template -struct RemoveCV: AllStatic { - typedef T type; -}; - -template -struct RemoveCV: AllStatic { - typedef T type; -}; - -template -struct RemoveCV: AllStatic { - typedef T type; -}; - -#endif // SHARE_METAPROGRAMMING_REMOVECV_HPP diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/removeExtent.hpp openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/removeExtent.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/removeExtent.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/removeExtent.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * 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. - * - */ - -#ifndef SHARE_METAPROGRAMMING_REMOVEEXTENT_HPP -#define SHARE_METAPROGRAMMING_REMOVEEXTENT_HPP - -#include "memory/allocation.hpp" - -template struct RemoveExtent: AllStatic { typedef T type; }; - -template struct RemoveExtent: AllStatic { typedef T type; }; -template struct RemoveExtent: AllStatic { typedef T type; }; - -#endif // SHARE_METAPROGRAMMING_REMOVEEXTENT_HPP diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/removePointer.hpp openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/removePointer.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/removePointer.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/removePointer.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. - * 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. - * - */ - -#ifndef SHARE_METAPROGRAMMING_REMOVEPOINTER_HPP -#define SHARE_METAPROGRAMMING_REMOVEPOINTER_HPP - -#include "memory/allocation.hpp" - -// This metafunction returns for a type T either the underlying type behind -// the pointer iff T is a pointer type (irrespective of CV qualifiers), -// or the same type T if T is not a pointer type. - -template struct RemovePointer: AllStatic { typedef T type; }; - -template struct RemovePointer: AllStatic { typedef T type; }; -template struct RemovePointer: AllStatic { typedef T type; }; -template struct RemovePointer: AllStatic { typedef T type; }; -template struct RemovePointer: AllStatic { typedef T type; }; - -#endif // SHARE_METAPROGRAMMING_REMOVEPOINTER_HPP diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/removeReference.hpp openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/removeReference.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/metaprogramming/removeReference.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/metaprogramming/removeReference.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. - * 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. - * - */ - -#ifndef SHARE_METAPROGRAMMING_REMOVEREFERENCE_HPP -#define SHARE_METAPROGRAMMING_REMOVEREFERENCE_HPP - -#include "memory/allocation.hpp" - -// This metafunction returns for a type T either the underlying type behind -// the reference iff T is a reference type, or the same type T if T is not -// a reference type. - -template struct RemoveReference: AllStatic { typedef T type; }; - -template struct RemoveReference: AllStatic { typedef T type; }; - -#endif // SHARE_METAPROGRAMMING_REMOVEREFERENCE_HPP diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/oops/accessBackend.hpp openjdk-17-17.0.13+11/src/hotspot/share/oops/accessBackend.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/oops/accessBackend.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/oops/accessBackend.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -27,21 +27,14 @@ #include "gc/shared/barrierSetConfig.hpp" #include "memory/allocation.hpp" -#include "metaprogramming/conditional.hpp" -#include "metaprogramming/decay.hpp" #include "metaprogramming/enableIf.hpp" -#include "metaprogramming/integralConstant.hpp" -#include "metaprogramming/isFloatingPoint.hpp" -#include "metaprogramming/isIntegral.hpp" -#include "metaprogramming/isPointer.hpp" -#include "metaprogramming/isSame.hpp" -#include "metaprogramming/isVolatile.hpp" #include "oops/accessDecorators.hpp" #include "oops/oopsHierarchy.hpp" #include "runtime/globals.hpp" #include "utilities/debug.hpp" #include "utilities/globalDefinitions.hpp" +#include // This metafunction returns either oop or narrowOop depending on whether // an access needs to use compressed oops or not. @@ -49,7 +42,7 @@ struct HeapOopType: AllStatic { static const bool needs_oop_compress = HasDecorator::value && HasDecorator::value; - typedef typename Conditional::type type; + using type = std::conditional_t; }; namespace AccessInternal { @@ -67,18 +60,18 @@ }; template - struct MustConvertCompressedOop: public IntegralConstant::value && - IsSame::type, narrowOop>::value && - IsSame::value> {}; + std::is_same::type, narrowOop>::value && + std::is_same::value> {}; // This metafunction returns an appropriate oop type if the value is oop-like // and otherwise returns the same type T. template struct EncodedType: AllStatic { - typedef typename Conditional< - HasDecorator::value, - typename HeapOopType::type, T>::type type; + using type = std::conditional_t::value, + typename HeapOopType::type, + T>; }; template @@ -92,9 +85,9 @@ // locking to support wide atomics or not. template #ifdef SUPPORTS_NATIVE_CX8 - struct PossiblyLockedAccess: public IntegralConstant {}; + struct PossiblyLockedAccess: public std::false_type {}; #else - struct PossiblyLockedAccess: public IntegralConstant 4)> {}; + struct PossiblyLockedAccess: public std::integral_constant 4)> {}; #endif template @@ -425,7 +418,7 @@ // to compile, as desired. template struct OopOrNarrowOop: AllStatic { - typedef typename OopOrNarrowOopInternal::type>::type type; + typedef typename OopOrNarrowOopInternal>::type type; }; inline void* field_addr(oop base, ptrdiff_t byte_offset) { @@ -617,7 +610,7 @@ // not possible. struct PreRuntimeDispatch: AllStatic { template - struct CanHardwireRaw: public IntegralConstant< + struct CanHardwireRaw: public std::integral_constant< bool, !HasDecorator::value || // primitive access !HasDecorator::value || // don't care about compressed oops (oop* address) @@ -1081,20 +1074,20 @@ // If this fails to compile, then you have sent in something that is // not recognized as a valid primitive type to a primitive Access function. STATIC_ASSERT((HasDecorator::value || // oops have already been validated - (IsPointer::value || IsIntegral::value) || - IsFloatingPoint::value)); // not allowed primitive type + (std::is_pointer::value || std::is_integral::value) || + std::is_floating_point::value)); // not allowed primitive type } template inline void store(P* addr, T value) { verify_types(); - typedef typename Decay

::type DecayedP; - typedef typename Decay::type DecayedT; + using DecayedP = std::decay_t

; + using DecayedT = std::decay_t; DecayedT decayed_value = value; // If a volatile address is passed in but no memory ordering decorator, // set the memory ordering to MO_RELAXED by default. const DecoratorSet expanded_decorators = DecoratorFixup< - (IsVolatile

::value && !HasDecorator::value) ? + (std::is_volatile

::value && !HasDecorator::value) ? (MO_RELAXED | decorators) : decorators>::value; store_reduce_types(const_cast(addr), decayed_value); } @@ -1102,7 +1095,7 @@ template inline void store_at(oop base, ptrdiff_t offset, T value) { verify_types(); - typedef typename Decay::type DecayedT; + using DecayedT = std::decay_t; DecayedT decayed_value = value; const DecoratorSet expanded_decorators = DecoratorFixup::value ? @@ -1113,14 +1106,14 @@ template inline T load(P* addr) { verify_types(); - typedef typename Decay

::type DecayedP; - typedef typename Conditional::value, - typename OopOrNarrowOop::type, - typename Decay::type>::type DecayedT; + using DecayedP = std::decay_t

; + using DecayedT = std::conditional_t::value, + typename OopOrNarrowOop::type, + std::decay_t>; // If a volatile address is passed in but no memory ordering decorator, // set the memory ordering to MO_RELAXED by default. const DecoratorSet expanded_decorators = DecoratorFixup< - (IsVolatile

::value && !HasDecorator::value) ? + (std::is_volatile

::value && !HasDecorator::value) ? (MO_RELAXED | decorators) : decorators>::value; return load_reduce_types(const_cast(addr)); } @@ -1128,9 +1121,9 @@ template inline T load_at(oop base, ptrdiff_t offset) { verify_types(); - typedef typename Conditional::value, - typename OopOrNarrowOop::type, - typename Decay::type>::type DecayedT; + using DecayedT = std::conditional_t::value, + typename OopOrNarrowOop::type, + std::decay_t>; // Expand the decorators (figure out sensible defaults) // Potentially remember if we need compressed oop awareness const DecoratorSet expanded_decorators = DecoratorFixup inline T atomic_cmpxchg(P* addr, T compare_value, T new_value) { verify_types(); - typedef typename Decay

::type DecayedP; - typedef typename Decay::type DecayedT; + using DecayedP = std::decay_t

; + using DecayedT = std::decay_t; DecayedT new_decayed_value = new_value; DecayedT compare_decayed_value = compare_value; const DecoratorSet expanded_decorators = DecoratorFixup< @@ -1157,7 +1150,7 @@ template inline T atomic_cmpxchg_at(oop base, ptrdiff_t offset, T compare_value, T new_value) { verify_types(); - typedef typename Decay::type DecayedT; + using DecayedT = std::decay_t; DecayedT new_decayed_value = new_value; DecayedT compare_decayed_value = compare_value; // Determine default memory ordering @@ -1175,8 +1168,8 @@ template inline T atomic_xchg(P* addr, T new_value) { verify_types(); - typedef typename Decay

::type DecayedP; - typedef typename Decay::type DecayedT; + using DecayedP = std::decay_t

; + using DecayedT = std::decay_t; DecayedT new_decayed_value = new_value; // atomic_xchg is only available in SEQ_CST flavour. const DecoratorSet expanded_decorators = DecoratorFixup::value; @@ -1187,7 +1180,7 @@ template inline T atomic_xchg_at(oop base, ptrdiff_t offset, T new_value) { verify_types(); - typedef typename Decay::type DecayedT; + using DecayedT = std::decay_t; DecayedT new_decayed_value = new_value; // atomic_xchg is only available in SEQ_CST flavour. const DecoratorSet expanded_decorators = DecoratorFixup::value || - (IsSame::value || IsIntegral::value) || - IsFloatingPoint::value)); // arraycopy allows type erased void elements - typedef typename Decay::type DecayedT; + (std::is_same::value || std::is_integral::value) || + std::is_floating_point::value)); // arraycopy allows type erased void elements + using DecayedT = std::decay_t; const DecoratorSet expanded_decorators = DecoratorFixup::value; return arraycopy_reduce_types(src_obj, src_offset_in_bytes, const_cast(src_raw), dst_obj, dst_offset_in_bytes, const_cast(dst_raw), diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/oops/accessBackend.inline.hpp openjdk-17-17.0.13+11/src/hotspot/share/oops/accessBackend.inline.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/oops/accessBackend.inline.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/oops/accessBackend.inline.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -34,6 +34,8 @@ #include "runtime/atomic.hpp" #include "runtime/orderAccess.hpp" +#include + template template inline typename EnableIf< @@ -251,7 +253,7 @@ } class RawAccessBarrierArrayCopy: public AllStatic { - template struct IsHeapWordSized: public IntegralConstant { }; + template struct IsHeapWordSized: public std::integral_constant { }; public: template static inline typename EnableIf< @@ -334,7 +336,7 @@ } }; -template<> struct RawAccessBarrierArrayCopy::IsHeapWordSized: public IntegralConstant { }; +template<> struct RawAccessBarrierArrayCopy::IsHeapWordSized: public std::false_type { }; template template diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/oops/accessDecorators.hpp openjdk-17-17.0.13+11/src/hotspot/share/oops/accessDecorators.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/oops/accessDecorators.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/oops/accessDecorators.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -27,9 +27,10 @@ #include "gc/shared/barrierSetConfig.hpp" #include "memory/allocation.hpp" -#include "metaprogramming/integralConstant.hpp" #include "utilities/globalDefinitions.hpp" +#include + // A decorator is an attribute or property that affects the way a memory access is performed in some way. // There are different groups of decorators. Some have to do with memory ordering, others to do with, // e.g. strength of references, strength of GC barriers, or whether compression should be applied or not. @@ -41,7 +42,7 @@ // The HasDecorator trait can help at compile-time determining whether a decorator set // has an intersection with a certain other decorator set template -struct HasDecorator: public IntegralConstant {}; +struct HasDecorator: public std::integral_constant {}; // == General Decorators == // * DECORATORS_NONE: This is the name for the empty decorator set (in absence of other decorators). diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/oops/generateOopMap.cpp openjdk-17-17.0.13+11/src/hotspot/share/oops/generateOopMap.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/oops/generateOopMap.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/oops/generateOopMap.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, 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 @@ -1732,7 +1732,7 @@ } void GenerateOopMap::ppush1(CellTypeState in) { - assert(in.is_reference() | in.is_value(), "sanity check"); + assert(in.is_reference() || in.is_value(), "sanity check"); push(in); } diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/oops/instanceKlass.cpp openjdk-17-17.0.13+11/src/hotspot/share/oops/instanceKlass.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/oops/instanceKlass.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/oops/instanceKlass.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -3941,18 +3941,18 @@ // Globally, there is at least one previous version of a class to walk // during class unloading, which is saved because old methods in the class // are still running. Otherwise the previous version list is cleaned up. -bool InstanceKlass::_has_previous_versions = false; +bool InstanceKlass::_should_clean_previous_versions = false; // Returns true if there are previous versions of a class for class // unloading only. Also resets the flag to false. purge_previous_version // will set the flag to true if there are any left, i.e., if there's any // work to do for next time. This is to avoid the expensive code cache // walk in CLDG::clean_deallocate_lists(). -bool InstanceKlass::has_previous_versions_and_reset() { - bool ret = _has_previous_versions; - log_trace(redefine, class, iklass, purge)("Class unloading: has_previous_versions = %s", +bool InstanceKlass::should_clean_previous_versions_and_reset() { + bool ret = _should_clean_previous_versions; + log_trace(redefine, class, iklass, purge)("Class unloading: should_clean_previous_versions = %s", ret ? "true" : "false"); - _has_previous_versions = false; + _should_clean_previous_versions = false; return ret; } @@ -4027,12 +4027,17 @@ version++; continue; } else { - log_trace(redefine, class, iklass, purge)("previous version " INTPTR_FORMAT " is alive", p2i(pv_node)); assert(pvcp->pool_holder() != NULL, "Constant pool with no holder"); guarantee (!loader_data->is_unloading(), "unloaded classes can't be on the stack"); live_count++; - // found a previous version for next time we do class unloading - _has_previous_versions = true; + if (pvcp->is_shared()) { + // Shared previous versions can never be removed so no cleaning is needed. + log_trace(redefine, class, iklass, purge)("previous version " PTR_FORMAT " is shared", p2i(pv_node)); + } else { + // Previous version alive, set that clean is needed for next time. + _should_clean_previous_versions = true; + log_trace(redefine, class, iklass, purge)("previous version " PTR_FORMAT " is alive", p2i(pv_node)); + } } // next previous version @@ -4132,13 +4137,19 @@ return; } - // Add previous version if any methods are still running. - // Set has_previous_version flag for processing during class unloading. - _has_previous_versions = true; - log_trace(redefine, class, iklass, add) ("scratch class added; one of its methods is on_stack."); + // Add previous version if any methods are still running or if this is + // a shared class which should never be removed. assert(scratch_class->previous_versions() == NULL, "shouldn't have a previous version"); scratch_class->link_previous_versions(previous_versions()); link_previous_versions(scratch_class); + if (cp_ref->is_shared()) { + log_trace(redefine, class, iklass, add) ("scratch class added; class is shared"); + } else { + // We only set clean_previous_versions flag for processing during class + // unloading for non-shared classes. + _should_clean_previous_versions = true; + log_trace(redefine, class, iklass, add) ("scratch class added; one of its methods is on_stack."); + } } // end add_previous_version() #endif // INCLUDE_JVMTI diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/oops/instanceKlass.hpp openjdk-17-17.0.13+11/src/hotspot/share/oops/instanceKlass.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/oops/instanceKlass.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/oops/instanceKlass.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -815,7 +815,7 @@ } private: - static bool _has_previous_versions; + static bool _should_clean_previous_versions; public: static void purge_previous_versions(InstanceKlass* ik) { if (ik->has_been_redefined()) { @@ -823,8 +823,8 @@ } } - static bool has_previous_versions_and_reset(); - static bool has_previous_versions() { return _has_previous_versions; } + static bool should_clean_previous_versions_and_reset(); + static bool should_clean_previous_versions() { return _should_clean_previous_versions; } // JVMTI: Support for caching a class file before it is modified by an agent that can do retransformation void set_cached_class_file(JvmtiCachedClassFileData *data) { @@ -844,7 +844,7 @@ #else // INCLUDE_JVMTI static void purge_previous_versions(InstanceKlass* ik) { return; }; - static bool has_previous_versions_and_reset() { return false; } + static bool should_clean_previous_versions_and_reset() { return false; } void set_cached_class_file(JvmtiCachedClassFileData *data) { assert(data == NULL, "unexpected call with JVMTI disabled"); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/oops/markWord.hpp openjdk-17-17.0.13+11/src/hotspot/share/oops/markWord.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/oops/markWord.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/oops/markWord.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -25,11 +25,12 @@ #ifndef SHARE_OOPS_MARKWORD_HPP #define SHARE_OOPS_MARKWORD_HPP -#include "metaprogramming/integralConstant.hpp" #include "metaprogramming/primitiveConversions.hpp" #include "oops/oopsHierarchy.hpp" #include "runtime/globals.hpp" +#include + // The markWord describes the header of an object. // // Bit-format of an object header (most significant first, big endian layout below): @@ -356,7 +357,7 @@ // Support atomic operations. template<> -struct PrimitiveConversions::Translate : public TrueType { +struct PrimitiveConversions::Translate : public std::true_type { typedef markWord Value; typedef uintptr_t Decayed; diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/oops/oopHandle.hpp openjdk-17-17.0.13+11/src/hotspot/share/oops/oopHandle.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/oops/oopHandle.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/oops/oopHandle.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -28,6 +28,8 @@ #include "metaprogramming/primitiveConversions.hpp" #include "oops/oopsHierarchy.hpp" +#include + class OopStorage; // Simple classes for wrapping oop and atomically accessed oop pointers @@ -77,7 +79,7 @@ // Convert OopHandle to oop* template<> -struct PrimitiveConversions::Translate : public TrueType { +struct PrimitiveConversions::Translate : public std::true_type { typedef OopHandle Value; typedef oop* Decayed; diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/oops/oopsHierarchy.hpp openjdk-17-17.0.13+11/src/hotspot/share/oops/oopsHierarchy.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/oops/oopsHierarchy.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/oops/oopsHierarchy.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -25,10 +25,11 @@ #ifndef SHARE_OOPS_OOPSHIERARCHY_HPP #define SHARE_OOPS_OOPSHIERARCHY_HPP -#include "metaprogramming/integralConstant.hpp" #include "metaprogramming/primitiveConversions.hpp" #include "utilities/globalDefinitions.hpp" +#include + // OBJECT hierarchy // This hierarchy is a representation hierarchy, i.e. if A is a superclass // of B, A's representation is a prefix of B's representation. @@ -107,7 +108,7 @@ }; template<> -struct PrimitiveConversions::Translate : public TrueType { +struct PrimitiveConversions::Translate : public std::true_type { typedef oop Value; typedef oopDesc* Decayed; @@ -115,31 +116,31 @@ static Value recover(Decayed x) { return oop(x); } }; -#define DEF_OOP(type) \ - class type##OopDesc; \ - class type##Oop : public oop { \ - public: \ - type##Oop() : oop() {} \ - type##Oop(const type##Oop& o) : oop(o) {} \ - type##Oop(const oop& o) : oop(o) {} \ - type##Oop(type##OopDesc* o) : oop((oopDesc*)o) {} \ - operator type##OopDesc* () const { return (type##OopDesc*)obj(); } \ - type##OopDesc* operator->() const { \ - return (type##OopDesc*)obj(); \ - } \ - type##Oop& operator=(const type##Oop& o) { \ - oop::operator=(o); \ - return *this; \ - } \ - }; \ - \ - template<> \ - struct PrimitiveConversions::Translate : public TrueType { \ - typedef type##Oop Value; \ - typedef type##OopDesc* Decayed; \ - \ - static Decayed decay(Value x) { return (type##OopDesc*)x.obj(); } \ - static Value recover(Decayed x) { return type##Oop(x); } \ +#define DEF_OOP(type) \ + class type##OopDesc; \ + class type##Oop : public oop { \ + public: \ + type##Oop() : oop() {} \ + type##Oop(const type##Oop& o) : oop(o) {} \ + type##Oop(const oop& o) : oop(o) {} \ + type##Oop(type##OopDesc* o) : oop((oopDesc*)o) {} \ + operator type##OopDesc* () const { return (type##OopDesc*)obj(); } \ + type##OopDesc* operator->() const { \ + return (type##OopDesc*)obj(); \ + } \ + type##Oop& operator=(const type##Oop& o) { \ + oop::operator=(o); \ + return *this; \ + } \ + }; \ + \ + template<> \ + struct PrimitiveConversions::Translate : public std::true_type { \ + typedef type##Oop Value; \ + typedef type##OopDesc* Decayed; \ + \ + static Decayed decay(Value x) { return (type##OopDesc*)x.obj(); } \ + static Value recover(Decayed x) { return type##Oop(x); } \ }; DEF_OOP(instance); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/opto/callGenerator.cpp openjdk-17-17.0.13+11/src/hotspot/share/opto/callGenerator.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/opto/callGenerator.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/opto/callGenerator.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -1177,13 +1177,14 @@ const int receiver_skip = target->is_static() ? 0 : 1; // Cast receiver to its type. if (!target->is_static()) { - Node* arg = kit.argument(0); - const TypeOopPtr* arg_type = arg->bottom_type()->isa_oopptr(); - const Type* sig_type = TypeOopPtr::make_from_klass(signature->accessing_klass()); - if (arg_type != nullptr && !arg_type->higher_equal(sig_type)) { - const Type* recv_type = arg_type->filter_speculative(sig_type); // keep speculative part - Node* cast_obj = gvn.transform(new CheckCastPPNode(kit.control(), arg, recv_type)); - kit.set_argument(0, cast_obj); + Node* recv = kit.argument(0); + Node* casted_recv = kit.maybe_narrow_object_type(recv, signature->accessing_klass()); + if (casted_recv->is_top()) { + print_inlining_failure(C, callee, jvms->depth() - 1, jvms->bci(), + "argument types mismatch"); + return nullptr; // FIXME: effectively dead; issue a halt node instead + } else if (casted_recv != recv) { + kit.set_argument(0, casted_recv); } } // Cast reference arguments to its type. @@ -1191,12 +1192,13 @@ ciType* t = signature->type_at(i); if (t->is_klass()) { Node* arg = kit.argument(receiver_skip + j); - const TypeOopPtr* arg_type = arg->bottom_type()->isa_oopptr(); - const Type* sig_type = TypeOopPtr::make_from_klass(t->as_klass()); - if (arg_type != nullptr && !arg_type->higher_equal(sig_type)) { - const Type* narrowed_arg_type = arg_type->filter_speculative(sig_type); // keep speculative part - Node* cast_obj = gvn.transform(new CheckCastPPNode(kit.control(), arg, narrowed_arg_type)); - kit.set_argument(receiver_skip + j, cast_obj); + Node* casted_arg = kit.maybe_narrow_object_type(arg, t->as_klass()); + if (casted_arg->is_top()) { + print_inlining_failure(C, callee, jvms->depth() - 1, jvms->bci(), + "argument types mismatch"); + return nullptr; // FIXME: effectively dead; issue a halt node instead + } else if (casted_arg != arg) { + kit.set_argument(receiver_skip + j, casted_arg); } } j += t->size(); // long and double take two slots diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/opto/callnode.cpp openjdk-17-17.0.13+11/src/hotspot/share/opto/callnode.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/opto/callnode.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/opto/callnode.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -361,7 +361,7 @@ if (regalloc->node_regs_max_index() > 0 && OptoReg::is_valid(regalloc->get_reg_first(n))) { // Check for undefined char buf[50]; - regalloc->dump_register(n,buf); + regalloc->dump_register(n,buf,sizeof(buf)); st->print(" %s%d]=%s",msg,i,buf); } else { // No register, but might be constant const Type *t = n->bottom_type(); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/opto/cfgnode.cpp openjdk-17-17.0.13+11/src/hotspot/share/opto/cfgnode.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/opto/cfgnode.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/opto/cfgnode.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -2816,7 +2816,7 @@ st->print(", "); } char buf[128]; - ra->dump_register(n, buf); + ra->dump_register(n, buf, sizeof(buf)); st->print("%s", buf); } } diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/opto/chaitin.cpp openjdk-17-17.0.13+11/src/hotspot/share/opto/chaitin.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/opto/chaitin.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/opto/chaitin.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -2156,42 +2156,42 @@ tty->cr(); } -static char *print_reg(OptoReg::Name reg, const PhaseChaitin* pc, char* buf) { +static char *print_reg(OptoReg::Name reg, const PhaseChaitin* pc, char* buf, size_t buf_size) { if ((int)reg < 0) - sprintf(buf, "", (int)reg); + os::snprintf_checked(buf, buf_size, "", (int)reg); else if (OptoReg::is_reg(reg)) strcpy(buf, Matcher::regName[reg]); else - sprintf(buf,"%s + #%d",OptoReg::regname(OptoReg::c_frame_pointer), + os::snprintf_checked(buf, buf_size, "%s + #%d",OptoReg::regname(OptoReg::c_frame_pointer), pc->reg2offset(reg)); return buf+strlen(buf); } // Dump a register name into a buffer. Be intelligent if we get called // before allocation is complete. -char *PhaseChaitin::dump_register(const Node* n, char* buf) const { +char *PhaseChaitin::dump_register(const Node* n, char* buf, size_t buf_size) const { if( _node_regs ) { // Post allocation, use direct mappings, no LRG info available - print_reg( get_reg_first(n), this, buf ); + print_reg( get_reg_first(n), this, buf, buf_size); } else { uint lidx = _lrg_map.find_const(n); // Grab LRG number if( !_ifg ) { - sprintf(buf,"L%d",lidx); // No register binding yet + os::snprintf_checked(buf, buf_size, "L%d",lidx); // No register binding yet } else if( !lidx ) { // Special, not allocated value strcpy(buf,"Special"); } else { if (lrgs(lidx)._is_vector) { if (lrgs(lidx).mask().is_bound_set(lrgs(lidx).num_regs())) - print_reg( lrgs(lidx).reg(), this, buf ); // a bound machine register + print_reg( lrgs(lidx).reg(), this, buf, buf_size); // a bound machine register else - sprintf(buf,"L%d",lidx); // No register binding yet + os::snprintf_checked(buf, buf_size, "L%d",lidx); // No register binding yet } else if( (lrgs(lidx).num_regs() == 1) ? lrgs(lidx).mask().is_bound1() : lrgs(lidx).mask().is_bound_pair() ) { // Hah! We have a bound machine register - print_reg( lrgs(lidx).reg(), this, buf ); + print_reg( lrgs(lidx).reg(), this, buf, buf_size); } else { - sprintf(buf,"L%d",lidx); // No register binding yet + os::snprintf_checked(buf, buf_size, "L%d",lidx); // No register binding yet } } } diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/opto/chaitin.hpp openjdk-17-17.0.13+11/src/hotspot/share/opto/chaitin.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/opto/chaitin.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/opto/chaitin.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -802,7 +802,7 @@ public: void dump_frame() const; - char *dump_register(const Node* n, char* buf) const; + char *dump_register(const Node* n, char* buf, size_t buf_size) const; private: static void print_chaitin_statistics(); #endif // not PRODUCT diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/opto/graphKit.cpp openjdk-17-17.0.13+11/src/hotspot/share/opto/graphKit.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/opto/graphKit.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/opto/graphKit.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -4320,3 +4320,14 @@ } return nullptr; } + +Node* GraphKit::maybe_narrow_object_type(Node* obj, ciKlass* type) { + const TypeOopPtr* obj_type = obj->bottom_type()->isa_oopptr(); + const TypeOopPtr* sig_type = TypeOopPtr::make_from_klass(type); + if (obj_type != nullptr && sig_type->klass()->is_loaded() && !obj_type->higher_equal(sig_type)) { + const Type* narrow_obj_type = obj_type->filter_speculative(sig_type); // keep speculative part + Node* casted_obj = gvn().transform(new CheckCastPPNode(control(), obj, narrow_obj_type)); + return casted_obj; + } + return obj; +} diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/opto/graphKit.hpp openjdk-17-17.0.13+11/src/hotspot/share/opto/graphKit.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/opto/graphKit.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/opto/graphKit.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -445,6 +445,8 @@ // Replace all occurrences of one node by another. void replace_in_map(Node* old, Node* neww); + Node* maybe_narrow_object_type(Node* obj, ciKlass* type); + void push(Node* n) { map_not_null(); _map->set_stack(_map->_jvms, _sp++ , n); } Node* pop() { map_not_null(); return _map->stack( _map->_jvms, --_sp ); } Node* peek(int off = 0) { map_not_null(); return _map->stack( _map->_jvms, _sp - off - 1 ); } diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/opto/idealGraphPrinter.cpp openjdk-17-17.0.13+11/src/hotspot/share/opto/idealGraphPrinter.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/opto/idealGraphPrinter.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/opto/idealGraphPrinter.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -141,21 +141,24 @@ _depth = 0; _current_method = nullptr; _network_stream = nullptr; + _append = append; if (file_name != nullptr) { - init_file_stream(file_name, use_multiple_files, append); + init_file_stream(file_name, use_multiple_files); } else { init_network_stream(); } _xml = new (ResourceObj::C_HEAP, mtCompiler) xmlStream(_output); - if (!append) { + if (!_append) { head(TOP_ELEMENT); } } // Destructor, close file or network stream IdealGraphPrinter::~IdealGraphPrinter() { - tail(TOP_ELEMENT); + if (!_append) { + tail(TOP_ELEMENT); + } // tty->print_cr("Walk time: %d", (int)_walk_time.milliseconds()); // tty->print_cr("Output time: %d", (int)_output_time.milliseconds()); @@ -508,7 +511,7 @@ if (index >= 10) { print_prop(short_name, "PA"); } else { - sprintf(buffer, "P%d", index); + os::snprintf_checked(buffer, sizeof(buffer), "P%d", index); print_prop(short_name, buffer); } } else if (strcmp(node->Name(), "IfTrue") == 0) { @@ -524,7 +527,7 @@ // max. 2 chars allowed if (value >= -9 && value <= 99) { - sprintf(buffer, "%d", value); + os::snprintf_checked(buffer, sizeof(buffer), "%d", value); print_prop(short_name, buffer); } else { print_prop(short_name, "I"); @@ -538,7 +541,7 @@ // max. 2 chars allowed if (value >= -9 && value <= 99) { - sprintf(buffer, JLONG_FORMAT, value); + os::snprintf_checked(buffer, sizeof(buffer), JLONG_FORMAT, value); print_prop(short_name, buffer); } else { print_prop(short_name, "L"); @@ -601,7 +604,7 @@ if (_chaitin && _chaitin != (PhaseChaitin *)((intptr_t)0xdeadbeef)) { buffer[0] = 0; - _chaitin->dump_register(node, buffer); + _chaitin->dump_register(node, buffer, sizeof(buffer)); print_prop("reg", buffer); uint lrg_id = 0; if (node->_idx < _chaitin->_lrg_map.size()) { @@ -729,10 +732,10 @@ _xml->flush(); } -void IdealGraphPrinter::init_file_stream(const char* file_name, bool use_multiple_files, bool append) { +void IdealGraphPrinter::init_file_stream(const char* file_name, bool use_multiple_files) { ThreadCritical tc; if (use_multiple_files && _file_count != 0) { - assert(!append, "append should only be used for debugging with a single file"); + assert(!_append, "append should only be used for debugging with a single file"); ResourceMark rm; stringStream st; const char* dot = strrchr(file_name, '.'); @@ -744,10 +747,10 @@ } _output = new (ResourceObj::C_HEAP, mtCompiler) fileStream(st.as_string(), "w"); } else { - _output = new (ResourceObj::C_HEAP, mtCompiler) fileStream(file_name, append ? "a" : "w"); + _output = new (ResourceObj::C_HEAP, mtCompiler) fileStream(file_name, _append ? "a" : "w"); } if (use_multiple_files) { - assert(!append, "append should only be used for debugging with a single file"); + assert(!_append, "append should only be used for debugging with a single file"); _file_count++; } } @@ -778,9 +781,16 @@ assert(C != nullptr, "must already be set"); if (current_method != _current_method) { // If a different method, end the old and begin with the new one. - end_method(); - _current_method = nullptr; - begin_method(); + if (_append) { + // Do not call `end_method` if we are appending, just update `_current_method`, + // because `begin_method` is not called in the constructor in append mode. + _current_method = current_method; + } else { + // End the old method and begin a new one. + // Don't worry about `_current_method`, `end_method` will clear it. + end_method(); + begin_method(); + } } } diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/opto/idealGraphPrinter.hpp openjdk-17-17.0.13+11/src/hotspot/share/opto/idealGraphPrinter.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/opto/idealGraphPrinter.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/opto/idealGraphPrinter.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -93,6 +93,7 @@ bool _traverse_outs; Compile *C; double _max_freq; + bool _append; void print_method(ciMethod *method, int bci, InlineTree *tree); void print_inline_tree(InlineTree *tree); @@ -110,7 +111,7 @@ void head(const char *name); void text(const char *s); void init(const char* file_name, bool use_multiple_files, bool append); - void init_file_stream(const char* file_name, bool use_multiple_files, bool append); + void init_file_stream(const char* file_name, bool use_multiple_files); void init_network_stream(); IdealGraphPrinter(); ~IdealGraphPrinter(); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/opto/loopnode.cpp openjdk-17-17.0.13+11/src/hotspot/share/opto/loopnode.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/opto/loopnode.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/opto/loopnode.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -2128,7 +2128,7 @@ const TypeInt* init_t = phase->type(in(Init) )->is_int(); const TypeInt* limit_t = phase->type(in(Limit))->is_int(); - int stride_p; + jlong stride_p; jlong lim, ini; julong max; if (stride_con > 0) { @@ -2137,10 +2137,10 @@ ini = init_t->_lo; max = (julong)max_jint; } else { - stride_p = -stride_con; + stride_p = -(jlong)stride_con; lim = init_t->_hi; ini = limit_t->_lo; - max = (julong)min_jint; + max = (julong)(juint)min_jint; // double cast to get 0x0000000080000000, not 0xffffffff80000000 } julong range = lim - ini + stride_p; if (range <= max) { diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/opto/output.cpp openjdk-17-17.0.13+11/src/hotspot/share/opto/output.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/opto/output.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/opto/output.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -176,6 +176,11 @@ // Add a node to the current bundle void AddNodeToBundle(Node *n, const Block *bb); + // Return an integer less than, equal to, or greater than zero + // if the stack offset of the first argument is respectively + // less than, equal to, or greater than the second. + int compare_two_spill_nodes(Node* first, Node* second); + // Add a node to the list of available nodes void AddNodeToAvailableList(Node *n); @@ -2306,6 +2311,29 @@ return _available[0]; } +int Scheduling::compare_two_spill_nodes(Node* first, Node* second) { + assert(first->is_MachSpillCopy() && second->is_MachSpillCopy(), ""); + + OptoReg::Name first_src_lo = _regalloc->get_reg_first(first->in(1)); + OptoReg::Name first_dst_lo = _regalloc->get_reg_first(first); + OptoReg::Name second_src_lo = _regalloc->get_reg_first(second->in(1)); + OptoReg::Name second_dst_lo = _regalloc->get_reg_first(second); + + // Comparison between stack -> reg and stack -> reg + if (OptoReg::is_stack(first_src_lo) && OptoReg::is_stack(second_src_lo) && + OptoReg::is_reg(first_dst_lo) && OptoReg::is_reg(second_dst_lo)) { + return _regalloc->reg2offset(first_src_lo) - _regalloc->reg2offset(second_src_lo); + } + + // Comparison between reg -> stack and reg -> stack + if (OptoReg::is_stack(first_dst_lo) && OptoReg::is_stack(second_dst_lo) && + OptoReg::is_reg(first_src_lo) && OptoReg::is_reg(second_src_lo)) { + return _regalloc->reg2offset(first_dst_lo) - _regalloc->reg2offset(second_dst_lo); + } + + return 0; // Not comparable +} + void Scheduling::AddNodeToAvailableList(Node *n) { assert( !n->is_Proj(), "projections never directly made available" ); #ifndef PRODUCT @@ -2317,11 +2345,20 @@ int latency = _current_latency[n->_idx]; - // Insert in latency order (insertion sort) + // Insert in latency order (insertion sort). If two MachSpillCopyNodes + // for stack spilling or unspilling have the same latency, we sort + // them in the order of stack offset. Some ports (e.g. aarch64) may also + // have more opportunities to do ld/st merging uint i; - for ( i=0; i < _available.size(); i++ ) - if (_current_latency[_available[i]->_idx] > latency) + for (i = 0; i < _available.size(); i++) { + if (_current_latency[_available[i]->_idx] > latency) { break; + } else if (_current_latency[_available[i]->_idx] == latency && + n->is_MachSpillCopy() && _available[i]->is_MachSpillCopy() && + compare_two_spill_nodes(n, _available[i]) > 0) { + break; + } + } // Special Check for compares following branches if( n->is_Mach() && _scheduled.size() > 0 ) { diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/opto/regalloc.hpp openjdk-17-17.0.13+11/src/hotspot/share/opto/regalloc.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/opto/regalloc.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/opto/regalloc.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -127,7 +127,7 @@ static int _max_framesize; virtual void dump_frame() const = 0; - virtual char *dump_register( const Node *n, char *buf ) const = 0; + virtual char *dump_register( const Node *n, char *buf, size_t buf_size) const = 0; static void print_statistics(); #endif }; diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/opto/superword.cpp openjdk-17-17.0.13+11/src/hotspot/share/opto/superword.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/opto/superword.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/opto/superword.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -3742,6 +3742,10 @@ _mem(mem), _slp(slp), _base(nullptr), _adr(nullptr), _scale(0), _offset(0), _invar(nullptr), _negate_invar(false), _invar_scale(nullptr), + _has_int_index_after_convI2L(false), + _int_index_after_convI2L_offset(0), + _int_index_after_convI2L_invar(nullptr), + _int_index_after_convI2L_scale(0), _nstack(nstack), _analyze_only(analyze_only), _stack_idx(0) #ifndef PRODUCT @@ -3800,6 +3804,11 @@ NOT_PRODUCT(if(_slp->is_trace_alignment()) _tracer.restore_depth();) NOT_PRODUCT(_tracer.ctor_6(mem);) + if (!is_safe_to_use_as_simple_form(base, adr)) { + assert(!valid(), "does not have simple form"); + return; + } + _base = base; _adr = adr; assert(valid(), "Usable"); @@ -3811,6 +3820,10 @@ _mem(p->_mem), _slp(p->_slp), _base(nullptr), _adr(nullptr), _scale(0), _offset(0), _invar(nullptr), _negate_invar(false), _invar_scale(nullptr), + _has_int_index_after_convI2L(false), + _int_index_after_convI2L_offset(0), + _int_index_after_convI2L_invar(nullptr), + _int_index_after_convI2L_scale(0), _nstack(p->_nstack), _analyze_only(p->_analyze_only), _stack_idx(p->_stack_idx) #ifndef PRODUCT @@ -3818,6 +3831,354 @@ #endif {} +// We would like to make decisions about aliasing (i.e. removing memory edges) and adjacency +// (i.e. which loads/stores can be packed) based on the simple form: +// +// s_pointer = adr + offset + invar + scale * ConvI2L(iv) +// +// However, we parse the compound-long-int form: +// +// c_pointer = adr + long_offset + long_invar + long_scale * ConvI2L(int_index) +// int_index = int_offset + int_invar + int_scale * iv +// +// In general, the simple and the compound-long-int form do not always compute the same pointer +// at runtime. For example, the simple form would give a different result due to an overflow +// in the int_index. +// +// Example: +// For both forms, we have: +// iv = 0 +// scale = 1 +// +// We now account the offset and invar once to the long part and once to the int part: +// Pointer 1 (long offset and long invar): +// long_offset = min_int +// long_invar = min_int +// int_offset = 0 +// int_invar = 0 +// +// Pointer 2 (int offset and int invar): +// long_offset = 0 +// long_invar = 0 +// int_offset = min_int +// int_invar = min_int +// +// This gives us the following pointers: +// Compound-long-int form pointers: +// Form: +// c_pointer = adr + long_offset + long_invar + long_scale * ConvI2L(int_offset + int_invar + int_scale * iv) +// +// Pointers: +// c_pointer1 = adr + min_int + min_int + 1 * ConvI2L(0 + 0 + 1 * 0) +// = adr + min_int + min_int +// = adr - 2^32 +// +// c_pointer2 = adr + 0 + 0 + 1 * ConvI2L(min_int + min_int + 1 * 0) +// = adr + ConvI2L(min_int + min_int) +// = adr + 0 +// = adr +// +// Simple form pointers: +// Form: +// s_pointer = adr + offset + invar + scale * ConvI2L(iv) +// s_pointer = adr + (long_offset + int_offset) + (long_invar + int_invar) + (long_scale * int_scale) * ConvI2L(iv) +// +// Pointers: +// s_pointer1 = adr + (min_int + 0 ) + (min_int + 0 ) + 1 * 0 +// = adr + min_int + min_int +// = adr - 2^32 +// s_pointer2 = adr + (0 + min_int ) + (0 + min_int ) + 1 * 0 +// = adr + min_int + min_int +// = adr - 2^32 +// +// We see that the two addresses are actually 2^32 bytes apart (derived from the c_pointers), but their simple form look identical. +// +// Hence, we need to determine in which cases it is safe to make decisions based on the simple +// form, rather than the compound-long-int form. If we cannot prove that using the simple form +// is safe (i.e. equivalent to the compound-long-int form), then we do not get a valid SWPointer, +// and the associated memop cannot be vectorized. +bool SWPointer::is_safe_to_use_as_simple_form(Node* base, Node* adr) const { +#ifndef _LP64 + // On 32-bit platforms, there is never an explicit int_index with ConvI2L for the iv. Thus, the + // parsed pointer form is always the simple form, with int operations: + // + // pointer = adr + offset + invar + scale * iv + // + assert(!_has_int_index_after_convI2L, "32-bit never has an int_index with ConvI2L for the iv"); + return true; +#else + + // Array accesses that are not Unsafe always have a RangeCheck which ensures that there is no + // int_index overflow. This implies that the conversion to long can be done separately: + // + // ConvI2L(int_index) = ConvI2L(int_offset) + ConvI2L(int_invar) + ConvI2L(scale) * ConvI2L(iv) + // + // And hence, the simple form is guaranteed to be identical to the compound-long-int form at + // runtime and the SWPointer is safe/valid to be used. + const TypeAryPtr* ary_ptr_t = _mem->adr_type()->isa_aryptr(); + if (ary_ptr_t != nullptr) { + if (!_mem->is_unsafe_access()) { + return true; + } + } + + // We did not find the int_index. Just to be safe, reject this SWPointer. + if (!_has_int_index_after_convI2L) { + return false; + } + + int int_offset = _int_index_after_convI2L_offset; + Node* int_invar = _int_index_after_convI2L_invar; + int int_scale = _int_index_after_convI2L_scale; + int long_scale = _scale / int_scale; + + // If "int_index = iv", then the simple form is identical to the compound-long-int form. + // + // int_index = int_offset + int_invar + int_scale * iv + // = 0 0 1 * iv + // = iv + if (int_offset == 0 && int_invar == nullptr && int_scale == 1) { + return true; + } + + // Intuition: What happens if the int_index overflows? Let us look at two pointers on the "overflow edge": + // + // pointer1 = adr + ConvI2L(int_index1) + // pointer2 = adr + ConvI2L(int_index2) + // + // int_index1 = max_int + 0 = max_int -> very close to but before the overflow + // int_index2 = max_int + 1 = min_int -> just enough to get the overflow + // + // When looking at the difference of pointer1 and pointer2, we notice that it is very large + // (almost 2^32). Since arrays have at most 2^31 elements, chances are high that pointer2 is + // an actual out-of-bounds access at runtime. These would normally be prevented by range checks + // at runtime. However, if the access was done by using Unsafe, where range checks are omitted, + // then an out-of-bounds access constitutes undefined behavior. This means that we are allowed to + // do anything, including changing the behavior. + // + // If we can set the right conditions, we have a guarantee that an overflow is either impossible + // (no overflow or range checks preventing that) or undefined behavior. In both cases, we are + // safe to do a vectorization. + // + // Approach: We want to prove a lower bound for the distance between these two pointers, and an + // upper bound for the size of a memory object. We can derive such an upper bound for + // arrays. We know they have at most 2^31 elements. If we know the size of the elements + // in bytes, we have: + // + // array_element_size_in_bytes * 2^31 >= max_possible_array_size_in_bytes + // >= array_size_in_bytes (ARR) + // + // If some small difference "delta" leads to an int_index overflow, we know that the + // int_index1 before overflow must have been close to max_int, and the int_index2 after + // the overflow must be close to min_int: + // + // pointer1 = adr + long_offset + long_invar + long_scale * ConvI2L(int_index1) + // =approx adr + long_offset + long_invar + long_scale * max_int + // + // pointer2 = adr + long_offset + long_invar + long_scale * ConvI2L(int_index2) + // =approx adr + long_offset + long_invar + long_scale * min_int + // + // We realize that the pointer difference is very large: + // + // difference =approx long_scale * 2^32 + // + // Hence, if we set the right condition for long_scale and array_element_size_in_bytes, + // we can prove that an overflow is impossible (or would imply undefined behaviour). + // + // We must now take this intuition, and develop a rigorous proof. We start by stating the problem + // more precisely, with the help of some definitions and the Statement we are going to prove. + // + // Definition: + // Two SWPointers are "comparable" (i.e. SWPointer::comparable is true, set with SWPointer::cmp()), + // iff all of these conditions apply for the simple form: + // 1) Both SWPointers are valid. + // 2) The adr are identical, or both are array bases of different arrays. + // 3) They have identical scale. + // 4) They have identical invar. + // 5) The difference in offsets is limited: abs(offset1 - offset2) < 2^31. (DIFF) + // + // For the Vectorization Optimization, we pair-wise compare SWPointers and determine if they are: + // 1) "not comparable": + // We do not optimize them (assume they alias, not assume adjacency). + // + // Whenever we chose this option based on the simple form, it is also correct based on the + // compound-long-int form, since we make no optimizations based on it. + // + // 2) "comparable" with different array bases at runtime: + // We assume they do not alias (remove memory edges), but not assume adjacency. + // + // Whenever we have two different array bases for the simple form, we also have different + // array bases for the compound-long-form. Since SWPointers provably point to different + // memory objects, they can never alias. + // + // 3) "comparable" with the same base address: + // We compute the relative pointer difference, and based on the load/store size we can + // compute aliasing and adjacency. + // + // We must find a condition under which the pointer difference of the simple form is + // identical to the pointer difference of the compound-long-form. We do this with the + // Statement below, which we then proceed to prove. + // + // Statement: + // If two SWPointers satisfy these 3 conditions: + // 1) They are "comparable". + // 2) They have the same base address. + // 3) Their long_scale is a multiple of the array element size in bytes: + // + // abs(long_scale) % array_element_size_in_bytes = 0 (A) + // + // Then their pointer difference of the simple form is identical to the pointer difference + // of the compound-long-int form. + // + // More precisely: + // Such two SWPointers by definition have identical adr, invar, and scale. + // Their simple form is: + // + // s_pointer1 = adr + offset1 + invar + scale * ConvI2L(iv) (B1) + // s_pointer2 = adr + offset2 + invar + scale * ConvI2L(iv) (B2) + // + // Thus, the pointer difference of the simple forms collapses to the difference in offsets: + // + // s_difference = s_pointer1 - s_pointer2 = offset1 - offset2 (C) + // + // Their compound-long-int form for these SWPointer is: + // + // c_pointer1 = adr + long_offset1 + long_invar1 + long_scale1 * ConvI2L(int_index1) (D1) + // int_index1 = int_offset1 + int_invar1 + int_scale1 * iv (D2) + // + // c_pointer2 = adr + long_offset2 + long_invar2 + long_scale2 * ConvI2L(int_index2) (D3) + // int_index2 = int_offset2 + int_invar2 + int_scale2 * iv (D4) + // + // And these are the offset1, offset2, invar and scale from the simple form (B1) and (B2): + // + // offset1 = long_offset1 + long_scale1 * ConvI2L(int_offset1) (D5) + // offset2 = long_offset2 + long_scale2 * ConvI2L(int_offset2) (D6) + // + // invar = long_invar1 + long_scale1 * ConvI2L(int_invar1) + // = long_invar2 + long_scale2 * ConvI2L(int_invar2) (D7) + // + // scale = long_scale1 * ConvI2L(int_scale1) + // = long_scale2 * ConvI2L(int_scale2) (D8) + // + // The pointer difference of the compound-long-int form is defined as: + // + // c_difference = c_pointer1 - c_pointer2 + // + // Thus, the statement claims that for the two SWPointer we have: + // + // s_difference = c_difference (Statement) + // + // We prove the Statement with the help of a Lemma: + // + // Lemma: + // There is some integer x, such that: + // + // c_difference = s_difference + array_element_size_in_bytes * x * 2^32 (Lemma) + // + // From condition (DIFF), we can derive: + // + // abs(s_difference) < 2^31 (E) + // + // Assuming the Lemma, we prove the Statement: + // If "x = 0" (intuitively: the int_index does not overflow), then: + // c_difference = s_difference + // and hence the simple form computes the same pointer difference as the compound-long-int form. + // If "x != 0" (intuitively: the int_index overflows), then: + // abs(c_difference) >= abs(s_difference + array_element_size_in_bytes * x * 2^32) + // >= array_element_size_in_bytes * 2^32 - abs(s_difference) + // -- apply (E) -- + // > array_element_size_in_bytes * 2^32 - 2^31 + // >= array_element_size_in_bytes * 2^31 + // -- apply (ARR) -- + // >= max_possible_array_size_in_bytes + // >= array_size_in_bytes + // + // This shows that c_pointer1 and c_pointer2 have a distance that exceeds the maximum array size. + // Thus, at least one of the two pointers must be outside of the array bounds. But we can assume + // that out-of-bounds accesses do not happen. If they still do, it is undefined behavior. Hence, + // we are allowed to do anything. We can also "safely" use the simple form in this case even though + // it might not match the compound-long-int form at runtime. + // QED Statement. + // + // We must now prove the Lemma. + // + // ConvI2L always truncates by some power of 2^32, i.e. there is some integer y such that: + // + // ConvI2L(y1 + y2) = ConvI2L(y1) + ConvI2L(y2) + 2^32 * y (F) + // + // It follows, that there is an integer y1 such that: + // + // ConvI2L(int_index1) = ConvI2L(int_offset1 + int_invar1 + int_scale1 * iv) + // -- apply (F) -- + // = ConvI2L(int_offset1) + // + ConvI2L(int_invar1) + // + ConvI2L(int_scale1) * ConvI2L(iv) + // + y1 * 2^32 (G) + // + // Thus, we can write the compound-long-int form (D1) as: + // + // c_pointer1 = adr + long_offset1 + long_invar1 + long_scale1 * ConvI2L(int_index1) + // -- apply (G) -- + // = adr + // + long_offset1 + // + long_invar1 + // + long_scale1 * ConvI2L(int_offset1) + // + long_scale1 * ConvI2L(int_invar1) + // + long_scale1 * ConvI2L(int_scale1) * ConvI2L(iv) + // + long_scale1 * y1 * 2^32 (H) + // + // And we can write the simple form as: + // + // s_pointer1 = adr + offset1 + invar + scale * ConvI2L(iv) + // -- apply (D5, D7, D8) -- + // = adr + // + long_offset1 + // + long_scale1 * ConvI2L(int_offset1) + // + long_invar1 + // + long_scale1 * ConvI2L(int_invar1) + // + long_scale1 * ConvI2L(int_scale1) * ConvI2L(iv) (K) + // + // We now compute the pointer difference between the simple (K) and compound-long-int form (H). + // Most terms cancel out immediately: + // + // sc_difference1 = c_pointer1 - s_pointer1 = long_scale1 * y1 * 2^32 (L) + // + // Rearranging the equation (L), we get: + // + // c_pointer1 = s_pointer1 + long_scale1 * y1 * 2^32 (M) + // + // And since long_scale1 is a multiple of array_element_size_in_bytes, there is some integer + // x1, such that (M) implies: + // + // c_pointer1 = s_pointer1 + array_element_size_in_bytes * x1 * 2^32 (N) + // + // With an analogue equation for c_pointer2, we can now compute the pointer difference for + // the compound-long-int form: + // + // c_difference = c_pointer1 - c_pointer2 + // -- apply (N) -- + // = s_pointer1 + array_element_size_in_bytes * x1 * 2^32 + // -(s_pointer2 + array_element_size_in_bytes * x2 * 2^32) + // -- where "x = x1 - x2" -- + // = s_pointer1 - s_pointer2 + array_element_size_in_bytes * x * 2^32 + // -- apply (C) -- + // = s_difference + array_element_size_in_bytes * x * 2^32 + // QED Lemma. + if (ary_ptr_t != nullptr) { + BasicType array_element_bt = ary_ptr_t->elem()->array_element_basic_type(); + if (is_java_primitive(array_element_bt)) { + int array_element_size_in_bytes = type2aelembytes(array_element_bt); + if (abs(long_scale) % array_element_size_in_bytes == 0) { + return true; + } + } + } + + // General case: we do not know if it is safe to use the simple form. + return false; +#endif +} + bool SWPointer::is_main_loop_member(Node* n) const { Node* n_c = phase()->get_ctrl(n); return lpt()->is_member(phase()->get_loop(n_c)); @@ -3867,11 +4228,42 @@ } } else if (opc == Op_SubI) { if (offset_plus_k(n->in(2), true) && scaled_iv_plus_offset(n->in(1))) { + // (offset1 + invar1 + scale * iv) - (offset2) or + // (offset1 + scale * iv) - (offset2 + invar1) + // Subtraction handled via "negate" flag of "offset_plus_k". NOT_PRODUCT(_tracer.scaled_iv_plus_offset_6(n);) return true; } - if (offset_plus_k(n->in(1)) && scaled_iv_plus_offset(n->in(2))) { - _scale *= -1; + SWPointer tmp(this); + if (offset_plus_k(n->in(1)) && tmp.scaled_iv_plus_offset(n->in(2))) { + // (offset1 + invar1) - (offset2 + scale * iv) or + // (offset1) - (offset2 + invar1 + scale * iv) + // Subtraction handled explicitly below. + assert(_scale == 0, "shouldn't be set yet"); + // _scale = -tmp._scale + if (!try_MulI_no_overflow(-1, tmp._scale, _scale)) { + return false; // mul overflow. + } + // _offset -= tmp._offset + if (!try_SubI_no_overflow(_offset, tmp._offset, _offset)) { + return false; // sub overflow. + } + // _invar -= tmp._invar + if (tmp._invar != nullptr) { + if (_invar != nullptr) { + return false; + } + _invar = tmp._invar; + _invar_scale = tmp._invar_scale; + _negate_invar = !tmp._negate_invar; + } + + // SWPointer tmp does not have an integer part to be forwarded + // (tmp._has_int_index_after_convI2L is false) because n is a SubI, all + // nodes above must also be of integer type (ConvL2I is not handled + // to allow a long) and ConvI2L (the only node that can add an integer + // part) won't be present. + NOT_PRODUCT(_tracer.scaled_iv_plus_offset_7(n);) return true; } @@ -3914,10 +4306,57 @@ } } else if (opc == Op_LShiftI) { if (n->in(1) == iv() && n->in(2)->is_Con()) { - _scale = 1 << n->in(2)->get_int(); + if (!try_LShiftI_no_overflow(1, n->in(2)->get_int(), _scale)) { + return false; // shift overflow. + } NOT_PRODUCT(_tracer.scaled_iv_6(n, _scale);) return true; } + } else if (opc == Op_ConvI2L && !has_iv()) { + // So far we have not found the iv yet, and are about to enter a ConvI2L subgraph, + // which may be the int index (that might overflow) for the memory access, of the form: + // + // int_index = int_offset + int_invar + int_scale * iv + // + // If we simply continue parsing with the current SWPointer, then the int_offset and + // int_invar simply get added to the long offset and invar. But for the checks in + // SWPointer::is_safe_to_use_as_simple_form() we need to have explicit access to the + // int_index. Thus, we must parse it explicitly here. For this, we use a temporary + // SWPointer, to pattern match the int_index sub-expression of the address. + + NOT_PRODUCT(Tracer::Depth dddd;) + SWPointer tmp(this); + NOT_PRODUCT(_tracer.scaled_iv_8(n, &tmp);) + + if (tmp.scaled_iv_plus_offset(n->in(1)) && tmp.has_iv()) { + // We successfully matched an integer index, of the form: + // int_index = int_offset + int_invar + int_scale * iv + // Forward scale. + assert(_scale == 0 && tmp._scale != 0, "iv only found just now"); + _scale = tmp._scale; + // Accumulate offset. + if (!try_AddI_no_overflow(_offset, tmp._offset, _offset)) { + return false; // add overflow. + } + // Forward invariant if not already found. + if (tmp._invar != nullptr) { + if (_invar != nullptr) { + return false; + } + _invar = tmp._invar; + _invar_scale = tmp._invar_scale; + _negate_invar = tmp._negate_invar; + } + // Set info about the int_index: + assert(!_has_int_index_after_convI2L, "no previous int_index discovered"); + _has_int_index_after_convI2L = true; + _int_index_after_convI2L_offset = tmp._offset; + _int_index_after_convI2L_invar = tmp._invar; + _int_index_after_convI2L_scale = tmp._scale; + + NOT_PRODUCT(_tracer.scaled_iv_7(n);) + return true; + } } else if (opc == Op_ConvI2L || opc == Op_CastII) { if (scaled_iv_plus_offset(n->in(1))) { NOT_PRODUCT(_tracer.scaled_iv_7(n);) @@ -3933,14 +4372,33 @@ NOT_PRODUCT(_tracer.scaled_iv_8(n, &tmp);) if (tmp.scaled_iv_plus_offset(n->in(1))) { - int scale = n->in(2)->get_int(); - _scale = tmp._scale << scale; - _offset += tmp._offset << scale; + int shift = n->in(2)->get_int(); + // Accumulate scale. + if (!try_LShiftI_no_overflow(tmp._scale, shift, _scale)) { + return false; // shift overflow. + } + // Accumulate offset. + int shifted_offset = 0; + if (!try_LShiftI_no_overflow(tmp._offset, shift, shifted_offset)) { + return false; // shift overflow. + } + if (!try_AddI_no_overflow(_offset, shifted_offset, _offset)) { + return false; // add overflow. + } + // Accumulate invar. _invar = tmp._invar; if (_invar != nullptr) { _negate_invar = tmp._negate_invar; _invar_scale = n->in(2); } + + // Forward info about the int_index: + assert(!_has_int_index_after_convI2L, "no previous int_index discovered"); + _has_int_index_after_convI2L = tmp._has_int_index_after_convI2L; + _int_index_after_convI2L_offset = tmp._int_index_after_convI2L_offset; + _int_index_after_convI2L_invar = tmp._int_index_after_convI2L_invar; + _int_index_after_convI2L_scale = tmp._int_index_after_convI2L_scale; + NOT_PRODUCT(_tracer.scaled_iv_9(n, _scale, _offset, _invar, _negate_invar);) return true; } @@ -3959,7 +4417,9 @@ int opc = n->Opcode(); if (opc == Op_ConI) { - _offset += negate ? -(n->get_int()) : n->get_int(); + if (!try_AddSubI_no_overflow(_offset, n->get_int(), negate, _offset)) { + return false; // add/sub overflow. + } NOT_PRODUCT(_tracer.offset_plus_k_2(n, _offset);) return true; } else if (opc == Op_ConL) { @@ -3968,7 +4428,9 @@ if (t->higher_equal(TypeLong::INT)) { jlong loff = n->get_long(); jint off = (jint)loff; - _offset += negate ? -off : loff; + if (!try_AddSubI_no_overflow(_offset, off, negate, _offset)) { + return false; // add/sub overflow. + } NOT_PRODUCT(_tracer.offset_plus_k_3(n, _offset);) return true; } @@ -3987,11 +4449,15 @@ if (n->in(2)->is_Con() && invariant(n->in(1))) { _negate_invar = negate; _invar = n->in(1); - _offset += negate ? -(n->in(2)->get_int()) : n->in(2)->get_int(); + if (!try_AddSubI_no_overflow(_offset, n->in(2)->get_int(), negate, _offset)) { + return false; // add/sub overflow. + } NOT_PRODUCT(_tracer.offset_plus_k_6(n, _invar, _negate_invar, _offset);) return true; } else if (n->in(1)->is_Con() && invariant(n->in(2))) { - _offset += negate ? -(n->in(1)->get_int()) : n->in(1)->get_int(); + if (!try_AddSubI_no_overflow(_offset, n->in(1)->get_int(), negate, _offset)) { + return false; // add/sub overflow. + } _negate_invar = negate; _invar = n->in(2); NOT_PRODUCT(_tracer.offset_plus_k_7(n, _invar, _negate_invar, _offset);) @@ -4002,11 +4468,15 @@ if (n->in(2)->is_Con() && invariant(n->in(1))) { _negate_invar = negate; _invar = n->in(1); - _offset += !negate ? -(n->in(2)->get_int()) : n->in(2)->get_int(); + if (!try_AddSubI_no_overflow(_offset, n->in(2)->get_int(), !negate, _offset)) { + return false; // add/sub overflow. + } NOT_PRODUCT(_tracer.offset_plus_k_8(n, _invar, _negate_invar, _offset);) return true; } else if (n->in(1)->is_Con() && invariant(n->in(2))) { - _offset += negate ? -(n->in(1)->get_int()) : n->in(1)->get_int(); + if (!try_AddSubI_no_overflow(_offset, n->in(1)->get_int(), negate, _offset)) { + return false; // add/sub overflow. + } _negate_invar = !negate; _invar = n->in(2); NOT_PRODUCT(_tracer.offset_plus_k_9(n, _invar, _negate_invar, _offset);) @@ -4037,6 +4507,57 @@ return false; } +bool SWPointer::try_AddI_no_overflow(int offset1, int offset2, int& result) { + jlong long_offset = java_add((jlong)(offset1), (jlong)(offset2)); + jint int_offset = java_add((jint)(offset1), (jint)(offset2)); + if (long_offset != int_offset) { + return false; + } + result = int_offset; + return true; +} + +bool SWPointer::try_SubI_no_overflow(int offset1, int offset2, int& result) { + jlong long_offset = java_subtract((jlong)(offset1), (jlong)(offset2)); + jint int_offset = java_subtract((jint)(offset1), (jint)(offset2)); + if (long_offset != int_offset) { + return false; + } + result = int_offset; + return true; +} + +bool SWPointer::try_AddSubI_no_overflow(int offset1, int offset2, bool is_sub, int& result) { + if (is_sub) { + return try_SubI_no_overflow(offset1, offset2, result); + } else { + return try_AddI_no_overflow(offset1, offset2, result); + } +} + +bool SWPointer::try_LShiftI_no_overflow(int offset, int shift, int& result) { + if (shift < 0 || shift > 31) { + return false; + } + jlong long_offset = java_shift_left((jlong)(offset), (julong)((jlong)(shift))); + jint int_offset = java_shift_left((jint)(offset), (juint)((jint)(shift))); + if (long_offset != int_offset) { + return false; + } + result = int_offset; + return true; +} + +bool SWPointer::try_MulI_no_overflow(int offset1, int offset2, int& result) { + jlong long_offset = java_multiply((jlong)(offset1), (jlong)(offset2)); + jint int_offset = java_multiply((jint)(offset1), (jint)(offset2)); + if (long_offset != int_offset) { + return false; + } + result = int_offset; + return true; +} + //----------------------------print------------------------ void SWPointer::print() { #ifndef PRODUCT diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/opto/superword.hpp openjdk-17-17.0.13+11/src/hotspot/share/opto/superword.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/opto/superword.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/opto/superword.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -572,13 +572,51 @@ //------------------------------SWPointer--------------------------- // Information about an address for dependence checking and vector alignment +// +// We parse and represent pointers of the simple form: +// +// pointer = adr + offset + invar + scale * ConvI2L(iv) +// +// Where: +// +// adr: the base address of an array (base = adr) +// OR +// some address to off-heap memory (base = TOP) +// +// offset: a constant offset +// invar: a runtime variable, which is invariant during the loop +// scale: scaling factor +// iv: loop induction variable +// +// But more precisely, we parse the composite-long-int form: +// +// pointer = adr + long_offset + long_invar + long_scale * ConvI2L(int_offset + inv_invar + int_scale * iv) +// +// pointer = adr + long_offset + long_invar + long_scale * ConvI2L(int_index) +// int_index = int_offset + int_invar + int_scale * iv +// +// However, for aliasing and adjacency checks (e.g. SWPointer::cmp()) we always use the simple form to make +// decisions. Hence, we must make sure to only create a "valid" SWPointer if the optimisations based on the +// simple form produce the same result as the compound-long-int form would. Intuitively, this depends on +// if the int_index overflows, but the precise conditions are given in SWPointer::is_safe_to_use_as_simple_form(). +// +// ConvI2L(int_index) = ConvI2L(int_offset + int_invar + int_scale * iv) +// = Convi2L(int_offset) + ConvI2L(int_invar) + ConvI2L(int_scale) * ConvI2L(iv) +// +// scale = long_scale * ConvI2L(int_scale) +// offset = long_offset + long_scale * ConvI2L(int_offset) +// invar = long_invar + long_scale * ConvI2L(int_invar) +// +// pointer = adr + offset + invar + scale * ConvI2L(iv) +// class SWPointer { protected: MemNode* _mem; // My memory reference node SuperWord* _slp; // SuperWord class - Node* _base; // null if unsafe nonheap reference - Node* _adr; // address pointer + // Components of the simple form: + Node* _base; // Base address of an array OR null if some off-heap memory. + Node* _adr; // Same as _base if an array pointer OR some off-heap memory pointer. int _scale; // multiplier for iv (in bytes), 0 if no loop iv int _offset; // constant offset (in bytes) @@ -586,6 +624,13 @@ bool _negate_invar; // if true then use: (0 - _invar) Node* _invar_scale; // multiplier for invariant + // The int_index components of the compound-long-int form. Used to decide if it is safe to use the + // simple form rather than the compound-long-int form that was parsed. + bool _has_int_index_after_convI2L; + int _int_index_after_convI2L_offset; + Node* _int_index_after_convI2L_invar; + int _int_index_after_convI2L_scale; + Node_Stack* _nstack; // stack used to record a swpointer trace of variants bool _analyze_only; // Used in loop unrolling only for swpointer trace uint _stack_idx; // Used in loop unrolling only for swpointer trace @@ -604,6 +649,8 @@ // Match: offset is (k [+/- invariant]) bool offset_plus_k(Node* n, bool negate = false); + bool is_safe_to_use_as_simple_form(Node* base, Node* adr) const; + public: enum CMP { Less = 1, @@ -639,10 +686,43 @@ _negate_invar == q._negate_invar); } + // We compute if and how two SWPointers can alias at runtime, i.e. if the two addressed regions of memory can + // ever overlap. There are essentially 3 relevant return states: + // - NotComparable: Synonymous to "unknown aliasing". + // We have no information about how the two SWPointers can alias. They could overlap, refer + // to another location in the same memory object, or point to a completely different object. + // -> Memory edge required. Aliasing unlikely but possible. + // + // - Less / Greater: Synonymous to "never aliasing". + // The two SWPointers may point into the same memory object, but be non-aliasing (i.e. we + // know both address regions inside the same memory object, but these regions are non- + // overlapping), or the SWPointers point to entirely different objects. + // -> No memory edge required. Aliasing impossible. + // + // - Equal: Synonymous to "overlap, or point to different memory objects". + // The two SWPointers either overlap on the same memory object, or point to two different + // memory objects. + // -> Memory edge required. Aliasing likely. + // + // In a future refactoring, we can simplify to two states: + // - NeverAlias: instead of Less / Greater + // - MayAlias: instead of Equal / NotComparable + // + // Two SWPointer are "comparable" (Less / Greater / Equal), iff all of these conditions apply: + // 1) Both are valid, i.e. expressible in the compound-long-int or simple form. + // 2) The adr are identical, or both are array bases of different arrays. + // 3) They have identical scale. + // 4) They have identical invar. + // 5) The difference in offsets is limited: abs(offset0 - offset1) < 2^31. int cmp(SWPointer& q) { if (valid() && q.valid() && (_adr == q._adr || (_base == _adr && q._base == q._adr)) && _scale == q._scale && invar_equals(q)) { + jlong difference = abs(java_subtract((jlong)_offset, (jlong)q._offset)); + jlong max_diff = (jlong)1 << 31; + if (difference >= max_diff) { + return NotComparable; + } bool overlap = q._offset < _offset + memory_size() && _offset < q._offset + q.memory_size(); return overlap ? Equal : (_offset < q._offset ? Less : Greater); @@ -729,6 +809,13 @@ } _tracer;//TRacer; #endif + + static bool try_AddI_no_overflow(int offset1, int offset2, int& result); + static bool try_SubI_no_overflow(int offset1, int offset2, int& result); + static bool try_AddSubI_no_overflow(int offset1, int offset2, bool is_sub, int& result); + static bool try_LShiftI_no_overflow(int offset1, int offset2, int& result); + static bool try_MulI_no_overflow(int offset1, int offset2, int& result); + }; #endif // SHARE_OPTO_SUPERWORD_HPP diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/opto/type.cpp openjdk-17-17.0.13+11/src/hotspot/share/opto/type.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/opto/type.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/opto/type.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -1624,17 +1624,17 @@ //------------------------------dump2------------------------------------------ // Dump TypeInt #ifndef PRODUCT -static const char* intname(char* buf, jint n) { +static const char* intname(char* buf, size_t buf_size, jint n) { if (n == min_jint) return "min"; else if (n < min_jint + 10000) - sprintf(buf, "min+" INT32_FORMAT, n - min_jint); + os::snprintf_checked(buf, buf_size, "min+" INT32_FORMAT, n - min_jint); else if (n == max_jint) return "max"; else if (n > max_jint - 10000) - sprintf(buf, "max-" INT32_FORMAT, max_jint - n); + os::snprintf_checked(buf, buf_size, "max-" INT32_FORMAT, max_jint - n); else - sprintf(buf, INT32_FORMAT, n); + os::snprintf_checked(buf, buf_size, INT32_FORMAT, n); return buf; } @@ -1643,7 +1643,7 @@ if (_lo == min_jint && _hi == max_jint) st->print("int"); else if (is_con()) - st->print("int:%s", intname(buf, get_con())); + st->print("int:%s", intname(buf, sizeof(buf), get_con())); else if (_lo == BOOL->_lo && _hi == BOOL->_hi) st->print("bool"); else if (_lo == BYTE->_lo && _hi == BYTE->_hi) @@ -1653,11 +1653,11 @@ else if (_lo == SHORT->_lo && _hi == SHORT->_hi) st->print("short"); else if (_hi == max_jint) - st->print("int:>=%s", intname(buf, _lo)); + st->print("int:>=%s", intname(buf, sizeof(buf), _lo)); else if (_lo == min_jint) - st->print("int:<=%s", intname(buf, _hi)); + st->print("int:<=%s", intname(buf, sizeof(buf), _hi)); else - st->print("int:%s..%s", intname(buf, _lo), intname(buf2, _hi)); + st->print("int:%s..%s", intname(buf, sizeof(buf), _lo), intname(buf2, sizeof(buf2), _hi)); if (_widen != 0 && this != TypeInt::INT) st->print(":%.*s", _widen, "wwww"); @@ -1888,37 +1888,37 @@ //------------------------------dump2------------------------------------------ // Dump TypeLong #ifndef PRODUCT -static const char* longnamenear(jlong x, const char* xname, char* buf, jlong n) { +static const char* longnamenear(jlong x, const char* xname, char* buf, size_t buf_size, jlong n) { if (n > x) { if (n >= x + 10000) return nullptr; - sprintf(buf, "%s+" JLONG_FORMAT, xname, n - x); + os::snprintf_checked(buf, buf_size, "%s+" JLONG_FORMAT, xname, n - x); } else if (n < x) { if (n <= x - 10000) return nullptr; - sprintf(buf, "%s-" JLONG_FORMAT, xname, x - n); + os::snprintf_checked(buf, buf_size, "%s-" JLONG_FORMAT, xname, x - n); } else { return xname; } return buf; } -static const char* longname(char* buf, jlong n) { +static const char* longname(char* buf, size_t buf_size, jlong n) { const char* str; if (n == min_jlong) return "min"; else if (n < min_jlong + 10000) - sprintf(buf, "min+" JLONG_FORMAT, n - min_jlong); + os::snprintf_checked(buf, buf_size, "min+" JLONG_FORMAT, n - min_jlong); else if (n == max_jlong) return "max"; else if (n > max_jlong - 10000) - sprintf(buf, "max-" JLONG_FORMAT, max_jlong - n); - else if ((str = longnamenear(max_juint, "maxuint", buf, n)) != nullptr) + os::snprintf_checked(buf, buf_size, "max-" JLONG_FORMAT, max_jlong - n); + else if ((str = longnamenear(max_juint, "maxuint", buf, buf_size, n)) != nullptr) return str; - else if ((str = longnamenear(max_jint, "maxint", buf, n)) != nullptr) + else if ((str = longnamenear(max_jint, "maxint", buf, buf_size, n)) != nullptr) return str; - else if ((str = longnamenear(min_jint, "minint", buf, n)) != nullptr) + else if ((str = longnamenear(min_jint, "minint", buf, buf_size, n)) != nullptr) return str; else - sprintf(buf, JLONG_FORMAT, n); + os::snprintf_checked(buf, buf_size, JLONG_FORMAT, n); return buf; } @@ -1927,13 +1927,13 @@ if (_lo == min_jlong && _hi == max_jlong) st->print("long"); else if (is_con()) - st->print("long:%s", longname(buf, get_con())); + st->print("long:%s", longname(buf, sizeof(buf), get_con())); else if (_hi == max_jlong) - st->print("long:>=%s", longname(buf, _lo)); + st->print("long:>=%s", longname(buf, sizeof(buf), _lo)); else if (_lo == min_jlong) - st->print("long:<=%s", longname(buf, _hi)); + st->print("long:<=%s", longname(buf, sizeof(buf), _hi)); else - st->print("long:%s..%s", longname(buf, _lo), longname(buf2, _hi)); + st->print("long:%s..%s", longname(buf, sizeof(buf), _lo), longname(buf2,sizeof(buf2), _hi)); if (_widen != 0 && this != TypeLong::LONG) st->print(":%.*s", _widen, "wwww"); @@ -3720,24 +3720,24 @@ // assert(loaded->ptr() != TypePtr::Null, "insanity check"); // - if( loaded->ptr() == TypePtr::TopPTR ) { return unloaded; } + if( loaded->ptr() == TypePtr::TopPTR ) { return unloaded->with_speculative(speculative); } else if (loaded->ptr() == TypePtr::AnyNull) { return TypeInstPtr::make(ptr, unloaded->klass(), false, nullptr, off, instance_id, speculative, depth); } - else if (loaded->ptr() == TypePtr::BotPTR ) { return TypeInstPtr::BOTTOM; } + else if (loaded->ptr() == TypePtr::BotPTR ) { return TypeInstPtr::BOTTOM->with_speculative(speculative); } else if (loaded->ptr() == TypePtr::Constant || loaded->ptr() == TypePtr::NotNull) { - if (unloaded->ptr() == TypePtr::BotPTR ) { return TypeInstPtr::BOTTOM; } - else { return TypeInstPtr::NOTNULL; } + if (unloaded->ptr() == TypePtr::BotPTR ) { return TypeInstPtr::BOTTOM->with_speculative(speculative); } + else { return TypeInstPtr::NOTNULL->with_speculative(speculative); } } - else if( unloaded->ptr() == TypePtr::TopPTR ) { return unloaded; } + else if( unloaded->ptr() == TypePtr::TopPTR ) { return unloaded->with_speculative(speculative); } - return unloaded->cast_to_ptr_type(TypePtr::AnyNull)->is_instptr(); + return unloaded->cast_to_ptr_type(TypePtr::AnyNull)->is_instptr()->with_speculative(speculative); } // Both are unloaded, not the same class, not Object // Or meet unloaded with a different loaded class, not java/lang/Object if( ptr != TypePtr::BotPTR ) { - return TypeInstPtr::NOTNULL; + return TypeInstPtr::NOTNULL->with_speculative(speculative); } - return TypeInstPtr::BOTTOM; + return TypeInstPtr::BOTTOM->with_speculative(speculative); } @@ -4124,6 +4124,10 @@ _instance_id, nullptr, _inline_depth); } +const TypeInstPtr* TypeInstPtr::with_speculative(const TypePtr* speculative) const { + return make(_ptr, klass(), klass_is_exact(), const_oop(), _offset, _instance_id, speculative, _inline_depth); +} + const TypePtr *TypeInstPtr::with_inline_depth(int depth) const { if (!UseInlineDepthForSpeculativeTypes) { return this; diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/opto/type.hpp openjdk-17-17.0.13+11/src/hotspot/share/opto/type.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/opto/type.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/opto/type.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -1191,6 +1191,7 @@ // Speculative type helper methods. virtual const Type* remove_speculative() const; + const TypeInstPtr* with_speculative(const TypePtr* speculative) const; virtual const TypePtr* with_inline_depth(int depth) const; virtual const TypePtr* with_instance_id(int instance_id) const; diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/prims/jvm.cpp openjdk-17-17.0.13+11/src/hotspot/share/prims/jvm.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/prims/jvm.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/prims/jvm.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -2823,7 +2823,7 @@ jio_fprintf(defaultStream::output_stream(), "%.*s", (int)len, s); } else { // Make an unused local variable to avoid warning from gcc compiler. - size_t count = ::write(defaultStream::output_fd(), s, (int)len); + bool dummy = os::write(defaultStream::output_fd(), s, len); } } diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/prims/wbtestmethods/parserTests.cpp openjdk-17-17.0.13+11/src/hotspot/share/prims/wbtestmethods/parserTests.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/prims/wbtestmethods/parserTests.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/prims/wbtestmethods/parserTests.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -174,7 +174,7 @@ if (arg) { arg->value_as_str(buf, sizeof(buf)); } else { - sprintf(buf, ""); + os::snprintf_checked(buf, sizeof(buf), ""); } oop parsedValue = java_lang_String::create_oop_from_str(buf, CHECK_NULL); returnvalue_array_ah->obj_at_put(i*2+1, parsedValue); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/runtime/atomic.hpp openjdk-17-17.0.13+11/src/hotspot/share/runtime/atomic.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/runtime/atomic.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/runtime/atomic.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -26,18 +26,13 @@ #define SHARE_RUNTIME_ATOMIC_HPP #include "memory/allocation.hpp" -#include "metaprogramming/conditional.hpp" #include "metaprogramming/enableIf.hpp" -#include "metaprogramming/isIntegral.hpp" -#include "metaprogramming/isPointer.hpp" -#include "metaprogramming/isSame.hpp" #include "metaprogramming/primitiveConversions.hpp" -#include "metaprogramming/removeCV.hpp" -#include "metaprogramming/removePointer.hpp" #include "runtime/orderAccess.hpp" #include "utilities/align.hpp" #include "utilities/bytes.hpp" #include "utilities/macros.hpp" + #include enum atomic_memory_order { @@ -508,7 +503,7 @@ struct Atomic::LoadImpl< T, PlatformOp, - typename EnableIf::value || IsPointer::value>::type> + typename EnableIf::value || std::is_pointer::value>::type> { T operator()(T const volatile* dest) const { // Forward to the platform handler for the size of T. @@ -560,7 +555,7 @@ struct Atomic::StoreImpl< T, T, PlatformOp, - typename EnableIf::value>::type> + typename EnableIf::value>::type> { void operator()(T volatile* dest, T new_value) const { // Forward to the platform handler for the size of T. @@ -625,15 +620,15 @@ template inline void Atomic::inc(D volatile* dest, atomic_memory_order order) { - STATIC_ASSERT(IsPointer::value || IsIntegral::value); - typedef typename Conditional::value, ptrdiff_t, D>::type I; + STATIC_ASSERT(std::is_pointer::value || std::is_integral::value); + using I = std::conditional_t::value, ptrdiff_t, D>; Atomic::add(dest, I(1), order); } template inline void Atomic::dec(D volatile* dest, atomic_memory_order order) { - STATIC_ASSERT(IsPointer::value || IsIntegral::value); - typedef typename Conditional::value, ptrdiff_t, D>::type I; + STATIC_ASSERT(std::is_pointer::value || std::is_integral::value); + using I = std::conditional_t::value, ptrdiff_t, D>; // Assumes two's complement integer representation. #pragma warning(suppress: 4146) Atomic::add(dest, I(-1), order); @@ -641,14 +636,14 @@ template inline D Atomic::sub(D volatile* dest, I sub_value, atomic_memory_order order) { - STATIC_ASSERT(IsPointer::value || IsIntegral::value); - STATIC_ASSERT(IsIntegral::value); + STATIC_ASSERT(std::is_pointer::value || std::is_integral::value); + STATIC_ASSERT(std::is_integral::value); // If D is a pointer type, use [u]intptr_t as the addend type, // matching signedness of I. Otherwise, use D as the addend type. - typedef typename Conditional::value, intptr_t, uintptr_t>::type PI; - typedef typename Conditional::value, PI, D>::type AddendType; + using PI = std::conditional_t::value, intptr_t, uintptr_t>; + using AddendType = std::conditional_t::value, PI, D>; // Only allow conversions that can't change the value. - STATIC_ASSERT(IsSigned::value == IsSigned::value); + STATIC_ASSERT(std::is_signed::value == std::is_signed::value); STATIC_ASSERT(sizeof(I) <= sizeof(AddendType)); AddendType addend = sub_value; // Assumes two's complement integer representation. @@ -884,10 +879,10 @@ template struct Atomic::AddImpl< D, I, - typename EnableIf::value && - IsIntegral::value && + typename EnableIf::value && + std::is_integral::value && (sizeof(I) <= sizeof(D)) && - (IsSigned::value == IsSigned::value)>::type> + (std::is_signed::value == std::is_signed::value)>::type> { static D add_and_fetch(D volatile* dest, I add_value, atomic_memory_order order) { D addend = add_value; @@ -902,14 +897,14 @@ template struct Atomic::AddImpl< P*, I, - typename EnableIf::value && (sizeof(I) <= sizeof(P*))>::type> + typename EnableIf::value && (sizeof(I) <= sizeof(P*))>::type> { STATIC_ASSERT(sizeof(intptr_t) == sizeof(P*)); STATIC_ASSERT(sizeof(uintptr_t) == sizeof(P*)); // Type of the scaled addend. An integral type of the same size as a // pointer, and the same signedness as I. - using SI = typename Conditional::value, intptr_t, uintptr_t>::type; + using SI = std::conditional_t::value, intptr_t, uintptr_t>; // Type of the unscaled destination. A pointer type with pointee size == 1. using UP = const char*; @@ -977,7 +972,7 @@ template struct Atomic::CmpxchgImpl< T, T, T, - typename EnableIf::value>::type> + typename EnableIf::value>::type> { T operator()(T volatile* dest, T compare_value, T exchange_value, atomic_memory_order order) const { @@ -1002,8 +997,8 @@ struct Atomic::CmpxchgImpl< D*, U*, T*, typename EnableIf::value && - IsSame::type, - typename RemoveCV::type>::value>::type> + std::is_same, + std::remove_cv_t>::value>::type> { D* operator()(D* volatile* dest, U* compare_value, T* exchange_value, atomic_memory_order order) const { @@ -1112,7 +1107,7 @@ template struct Atomic::XchgImpl< T, T, - typename EnableIf::value>::type> + typename EnableIf::value>::type> { T operator()(T volatile* dest, T exchange_value, atomic_memory_order order) const { // Forward to the platform handler for the size of T. diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/runtime/deoptimization.cpp openjdk-17-17.0.13+11/src/hotspot/share/runtime/deoptimization.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/runtime/deoptimization.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/runtime/deoptimization.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -2657,7 +2657,7 @@ if ((uint)reason < Reason_LIMIT) return _trap_reason_name[reason]; static char buf[20]; - sprintf(buf, "reason%d", reason); + os::snprintf_checked(buf, sizeof(buf), "reason%d", reason); return buf; } const char* Deoptimization::trap_action_name(int action) { @@ -2667,7 +2667,7 @@ if ((uint)action < Action_LIMIT) return _trap_action_name[action]; static char buf[20]; - sprintf(buf, "action%d", action); + os::snprintf_checked(buf, sizeof(buf), "action%d", action); return buf; } @@ -2766,7 +2766,7 @@ Bytecodes::Code bc = (Bytecodes::Code)(counter & LSB_MASK); if (bc_case == BC_CASE_LIMIT && (int)bc == 0) bc = Bytecodes::_illegal; - sprintf(name, "%s/%s/%s", + os::snprintf_checked(name, sizeof(name), "%s/%s/%s", trap_reason_name(reason), trap_action_name(action), Bytecodes::is_defined(bc)? Bytecodes::name(bc): "other"); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/runtime/globals.hpp openjdk-17-17.0.13+11/src/hotspot/share/runtime/globals.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/runtime/globals.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/runtime/globals.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -477,6 +477,9 @@ develop(bool, ZapFillerObjects, trueInDebug, \ "Zap filler objects") \ \ + develop(bool, ZapTLAB, trueInDebug, \ + "Zap allocated TLABs") \ + \ product(bool, ExecutingUnitTests, false, \ "Whether the JVM is running unit tests or not") \ \ diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/runtime/os.cpp openjdk-17-17.0.13+11/src/hotspot/share/runtime/os.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/runtime/os.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/runtime/os.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -94,6 +94,16 @@ return result; } +int os::snprintf_checked(char* buf, size_t len, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + int result = os::vsnprintf(buf, len, fmt, args); + va_end(args); + assert(result >= 0, "os::snprintf error"); + assert(static_cast(result) < len, "os::snprintf truncated"); + return result; +} + // Fill in buffer with current local time as an ISO-8601 string. // E.g., YYYY-MM-DDThh:mm:ss.mmm+zzzz. // Returns buffer, or NULL if it failed. @@ -1294,7 +1304,7 @@ FILE* os::fopen(const char* path, const char* mode) { char modified_mode[20]; assert(strlen(mode) + 1 < sizeof(modified_mode), "mode chars plus one extra must fit in buffer"); - sprintf(modified_mode, "%s" LINUX_ONLY("e") BSD_ONLY("e") WINDOWS_ONLY("N"), mode); + os::snprintf_checked(modified_mode, sizeof(modified_mode), "%s" LINUX_ONLY("e") BSD_ONLY("e") WINDOWS_ONLY("N"), mode); FILE* file = ::fopen(path, modified_mode); #if !(defined LINUX || defined BSD || defined _WINDOWS) @@ -1356,6 +1366,22 @@ return os::stat(filename, &statbuf) == 0; } +bool os::write(int fd, const void *buf, size_t nBytes) { + ssize_t res; + + while (nBytes > 0) { + res = pd_write(fd, buf, nBytes); + if (res == OS_ERR) { + return false; + } + buf = (void *)((char *)buf + res); + nBytes -= res; + } + + return true; +} + + // Splits a path, based on its separator, the number of // elements is returned back in "elements". // file_name_length is used as a modifier for each path's diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/runtime/os.hpp openjdk-17-17.0.13+11/src/hotspot/share/runtime/os.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/runtime/os.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/runtime/os.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -26,7 +26,6 @@ #define SHARE_RUNTIME_OS_HPP #include "jvm_md.h" -#include "metaprogramming/integralConstant.hpp" #include "utilities/exceptions.hpp" #include "utilities/ostream.hpp" #include "utilities/macros.hpp" @@ -169,6 +168,8 @@ // Get summary strings for system information in buffer provided static void get_summary_cpu_info(char* buf, size_t buflen); static void get_summary_os_info(char* buf, size_t buflen); + // Returns number of bytes written on success, OS_ERR on failure. + static ssize_t pd_write(int fd, const void *buf, size_t nBytes); static void initialize_initial_active_processor_count(); @@ -580,7 +581,8 @@ static ssize_t read(int fd, void *buf, unsigned int nBytes); static ssize_t read_at(int fd, void *buf, unsigned int nBytes, jlong offset); - static size_t write(int fd, const void *buf, unsigned int nBytes); + // Writes the bytes completely. Returns true on success, false otherwise. + static bool write(int fd, const void *buf, size_t nBytes); // Reading directories. static DIR* opendir(const char* dirname); @@ -680,6 +682,10 @@ static int vsnprintf(char* buf, size_t len, const char* fmt, va_list args) ATTRIBUTE_PRINTF(3, 0); static int snprintf(char* buf, size_t len, const char* fmt, ...) ATTRIBUTE_PRINTF(3, 4); + // Performs snprintf and asserts the result is non-negative (so there was not + // an encoding error) and that the output was not truncated. + static int snprintf_checked(char* buf, size_t len, const char* fmt, ...) ATTRIBUTE_PRINTF(3, 4); + // Get host name in buffer provided static bool get_host_name(char* buf, size_t buflen); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/runtime/perfData.cpp openjdk-17-17.0.13+11/src/hotspot/share/runtime/perfData.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/runtime/perfData.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/runtime/perfData.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -84,7 +84,8 @@ const char* prefix = PerfDataManager::ns_to_string(ns); - _name = NEW_C_HEAP_ARRAY(char, strlen(name) + strlen(prefix) + 2, mtInternal); + const size_t _name_size = strlen(name) + strlen(prefix) + 2; + _name = NEW_C_HEAP_ARRAY(char, _name_size, mtInternal); assert(strlen(name) != 0, "invalid name"); if (ns == NULL_NS) { @@ -100,7 +101,7 @@ } } else { - sprintf(_name, "%s.%s", prefix, name); + os::snprintf_checked(_name, _name_size, "%s.%s", prefix, name); // set the F_Supported flag based on the given namespace. if (PerfDataManager::is_stable_supported(ns) || PerfDataManager::is_unstable_supported(ns)) { @@ -363,7 +364,7 @@ size_t len = strlen(ns) + strlen(name) + 2; char* result = NEW_RESOURCE_ARRAY(char, len); - sprintf(result, "%s.%s", ns, name); + os::snprintf_checked(result, len, "%s.%s", ns, name); return result; } diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/runtime/thread.cpp openjdk-17-17.0.13+11/src/hotspot/share/runtime/thread.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/runtime/thread.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/runtime/thread.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -3577,7 +3577,7 @@ ObjectSynchronizer::inc_in_use_list_ceiling(); // Possible GC point. - Events::log(p, "Thread added: " INTPTR_FORMAT, p2i(p)); + Events::log(Thread::current(), "Thread added: " INTPTR_FORMAT, p2i(p)); // Make new thread known to active EscapeBarrier EscapeBarrier::thread_added(p); @@ -3625,7 +3625,7 @@ ObjectSynchronizer::dec_in_use_list_ceiling(); // Since Events::log uses a lock, we grab it outside the Threads_lock - Events::log(p, "Thread exited: " INTPTR_FORMAT, p2i(p)); + Events::log(Thread::current(), "Thread exited: " INTPTR_FORMAT, p2i(p)); } // Operations on the Threads list for GC. These are not explicitly locked, @@ -3828,14 +3828,7 @@ } PrintOnClosure cl(st); - cl.do_thread(VMThread::vm_thread()); - Universe::heap()->gc_threads_do(&cl); - if (StringDedup::is_enabled()) { - StringDedup::threads_do(&cl); - } - cl.do_thread(WatcherThread::watcher_thread()); - cl.do_thread(AsyncLogWriter::instance()); - + non_java_threads_do(&cl); st->flush(); } diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/runtime/thread.hpp openjdk-17-17.0.13+11/src/hotspot/share/runtime/thread.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/runtime/thread.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/runtime/thread.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -668,15 +668,17 @@ class ThreadInAsgct { private: Thread* _thread; + bool _saved_in_asgct; public: ThreadInAsgct(Thread* thread) : _thread(thread) { assert(thread != nullptr, "invariant"); - assert(!thread->in_asgct(), "invariant"); + // Allow AsyncGetCallTrace to be reentrant - save the previous state. + _saved_in_asgct = thread->in_asgct(); thread->set_in_asgct(true); } ~ThreadInAsgct() { assert(_thread->in_asgct(), "invariant"); - _thread->set_in_asgct(false); + _thread->set_in_asgct(_saved_in_asgct); } }; diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/services/classLoadingService.cpp openjdk-17-17.0.13+11/src/hotspot/share/services/classLoadingService.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/services/classLoadingService.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/services/classLoadingService.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, 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 @@ -36,6 +36,7 @@ #include "utilities/defaultStream.hpp" #include "logging/log.hpp" #include "logging/logConfiguration.hpp" +#include "logging/logFileStreamOutput.hpp" #ifdef DTRACE_ENABLED @@ -186,6 +187,22 @@ return verbose; } +bool ClassLoadingService::get_verbose() { + for (LogTagSet* ts = LogTagSet::first(); ts != nullptr; ts = ts->next()) { + // set_verbose looks for a non-exact match for class+load, + // so look for all tag sets that match class+load* + if (ts->contains(LogTag::_class) && + ts->contains(LogTag::_load)) { + LogLevelType l = ts->level_for(&StdoutLog); + if (l != LogLevel::Info && l != LogLevel::Debug && l != LogLevel::Trace) { + return false; + } + } + } + + return true; +} + // Caller to this function must own Management_lock void ClassLoadingService::reset_trace_class_unloading() { assert(Management_lock->owned_by_self(), "Must own the Management_lock"); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/services/classLoadingService.hpp openjdk-17-17.0.13+11/src/hotspot/share/services/classLoadingService.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/services/classLoadingService.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/services/classLoadingService.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, 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 @@ -55,8 +55,8 @@ public: static void init(); - static bool get_verbose() { return log_is_enabled(Info, class, load); } static bool set_verbose(bool verbose); + static bool get_verbose() NOT_MANAGEMENT_RETURN_(false); static void reset_trace_class_unloading() NOT_MANAGEMENT_RETURN; static jlong loaded_class_count() { diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/services/heapDumperCompression.cpp openjdk-17-17.0.13+11/src/hotspot/share/services/heapDumperCompression.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/services/heapDumperCompression.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/services/heapDumperCompression.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -1,4 +1,5 @@ /* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -54,14 +55,8 @@ assert(_fd >= 0, "Must be open"); assert(size > 0, "Must write at least one byte"); - while (size > 0) { - ssize_t n = os::write(_fd, buf, (uint) size); - if (n <= 0) { - return os::strerror(errno); - } - - buf += n; - size -= n; + if (!os::write(_fd, buf, (size_t)size)) { + return os::strerror(errno); } return NULL; diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/services/mallocTracker.hpp openjdk-17-17.0.13+11/src/hotspot/share/services/mallocTracker.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/services/mallocTracker.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/services/mallocTracker.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -166,11 +166,6 @@ // Total malloc'd memory used by arenas size_t total_arena() const; - inline size_t thread_count() const { - MallocMemorySnapshot* s = const_cast(this); - return s->by_type(mtThreadStack)->malloc_count(); - } - void copy_to(MallocMemorySnapshot* s) { // Need to make sure that mtChunks don't get deallocated while the // copy is going on, because their size is adjusted using this diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/services/memBaseline.cpp openjdk-17-17.0.13+11/src/hotspot/share/services/memBaseline.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/services/memBaseline.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/services/memBaseline.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -145,11 +145,10 @@ }; -bool MemBaseline::baseline_summary() { +void MemBaseline::baseline_summary() { MallocMemorySummary::snapshot(&_malloc_memory_snapshot); VirtualMemorySummary::snapshot(&_virtual_memory_snapshot); _metaspace_stats = MetaspaceUtils::get_combined_statistics(); - return true; } bool MemBaseline::baseline_allocation_sites() { @@ -186,15 +185,13 @@ return true; } -bool MemBaseline::baseline(bool summaryOnly) { +void MemBaseline::baseline(bool summaryOnly) { reset(); _instance_class_count = ClassLoaderDataGraph::num_instance_classes(); _array_class_count = ClassLoaderDataGraph::num_array_classes(); - - if (!baseline_summary()) { - return false; - } + _thread_count = ThreadStackTracker::thread_count(); + baseline_summary(); _baseline_type = Summary_baselined; @@ -205,7 +202,6 @@ _baseline_type = Detail_baselined; } - return true; } int compare_allocation_site(const VirtualMemoryAllocationSite& s1, diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/services/memBaseline.hpp openjdk-17-17.0.13+11/src/hotspot/share/services/memBaseline.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/services/memBaseline.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/services/memBaseline.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -66,6 +66,7 @@ size_t _instance_class_count; size_t _array_class_count; + size_t _thread_count; // Allocation sites information // Malloc allocation sites @@ -86,11 +87,11 @@ public: // create a memory baseline MemBaseline(): - _instance_class_count(0), _array_class_count(0), + _instance_class_count(0), _array_class_count(0), _thread_count(0), _baseline_type(Not_baselined) { } - bool baseline(bool summaryOnly = true); + void baseline(bool summaryOnly = true); BaselineType baseline_type() const { return _baseline_type; } @@ -173,7 +174,7 @@ size_t thread_count() const { assert(baseline_type() != Not_baselined, "Not yet baselined"); - return _malloc_memory_snapshot.thread_count(); + return _thread_count; } // reset the baseline for reuse @@ -182,6 +183,7 @@ // _malloc_memory_snapshot and _virtual_memory_snapshot are copied over. _instance_class_count = 0; _array_class_count = 0; + _thread_count = 0; _malloc_sites.clear(); _virtual_memory_sites.clear(); @@ -190,7 +192,7 @@ private: // Baseline summary information - bool baseline_summary(); + void baseline_summary(); // Baseline allocation sites (detail tracking only) bool baseline_allocation_sites(); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/services/memReporter.cpp openjdk-17-17.0.13+11/src/hotspot/share/services/memReporter.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/services/memReporter.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/services/memReporter.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -225,7 +225,6 @@ MallocMemory* thread_stack_memory = _malloc_snapshot->by_type(mtThreadStack); const char* scale = current_scale(); // report thread count - assert(ThreadStackTracker::thread_count() == 0, "Not used"); out->print_cr("%27s (thread #" SIZE_FORMAT ")", " ", thread_stack_memory->malloc_count()); out->print("%27s (Stack: " SIZE_FORMAT "%s", " ", amount_in_current_scale(thread_stack_memory->malloc_size()), scale); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/services/memTracker.cpp openjdk-17-17.0.13+11/src/hotspot/share/services/memTracker.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/services/memTracker.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/services/memTracker.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -129,18 +129,17 @@ void MemTracker::report(bool summary_only, outputStream* output, size_t scale) { assert(output != NULL, "No output stream"); MemBaseline baseline; - if (baseline.baseline(summary_only)) { - if (summary_only) { - MemSummaryReporter rpt(baseline, output, scale); - rpt.report(); - } else { - MemDetailReporter rpt(baseline, output, scale); - rpt.report(); - output->print("Metaspace:"); - // The basic metaspace report avoids any locking and should be safe to - // be called at any time. - MetaspaceUtils::print_basic_report(output, scale); - } + baseline.baseline(summary_only); + if (summary_only) { + MemSummaryReporter rpt(baseline, output, scale); + rpt.report(); + } else { + MemDetailReporter rpt(baseline, output, scale); + rpt.report(); + output->print("Metaspace:"); + // The basic metaspace report avoids any locking and should be safe to + // be called at any time. + MetaspaceUtils::print_basic_report(output, scale); } } diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/services/memoryService.cpp openjdk-17-17.0.13+11/src/hotspot/share/services/memoryService.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/services/memoryService.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/services/memoryService.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, 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 @@ -26,6 +26,7 @@ #include "classfile/vmSymbols.hpp" #include "gc/shared/collectedHeap.hpp" #include "logging/logConfiguration.hpp" +#include "logging/logFileStreamOutput.hpp" #include "memory/heap.hpp" #include "memory/memRegion.hpp" #include "memory/resourceArea.hpp" @@ -201,6 +202,21 @@ return verbose; } +bool MemoryService::get_verbose() { + for (LogTagSet* ts = LogTagSet::first(); ts != nullptr; ts = ts->next()) { + // set_verbose only sets gc and not gc*, so check for an exact match + const bool is_gc_exact_match = ts->contains(LogTag::_gc) && ts->ntags() == 1; + if (is_gc_exact_match) { + LogLevelType l = ts->level_for(&StdoutLog); + if (l == LogLevel::Info || l == LogLevel::Debug || l == LogLevel::Trace) { + return true; + } + } + } + + return false; +} + Handle MemoryService::create_MemoryUsage_obj(MemoryUsage usage, TRAPS) { InstanceKlass* ik = Management::java_lang_management_MemoryUsage_klass(CHECK_NH); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/services/memoryService.hpp openjdk-17-17.0.13+11/src/hotspot/share/services/memoryService.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/services/memoryService.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/services/memoryService.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, 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 @@ -106,8 +106,8 @@ GCCause::Cause cause, bool allMemoryPoolsAffected, const char* notificationMessage = nullptr); - static bool get_verbose() { return log_is_enabled(Info, gc); } static bool set_verbose(bool verbose); + static bool get_verbose(); // Create an instance of java/lang/management/MemoryUsage static Handle create_MemoryUsage_obj(MemoryUsage usage, TRAPS); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/services/nmtDCmd.cpp openjdk-17-17.0.13+11/src/hotspot/share/services/nmtDCmd.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/services/nmtDCmd.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/services/nmtDCmd.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -121,11 +121,8 @@ report(false, scale_unit); } else if (_baseline.value()) { MemBaseline& baseline = MemTracker::get_baseline(); - if (!baseline.baseline(MemTracker::tracking_level() != NMT_detail)) { - output()->print_cr("Baseline failed"); - } else { - output()->print_cr("Baseline succeeded"); - } + baseline.baseline(MemTracker::tracking_level() != NMT_detail); + output()->print_cr("Baseline taken"); } else if (_summary_diff.value()) { MemBaseline& baseline = MemTracker::get_baseline(); if (baseline.baseline_type() >= MemBaseline::Summary_baselined) { @@ -157,14 +154,13 @@ void NMTDCmd::report(bool summaryOnly, size_t scale_unit) { MemBaseline baseline; - if (baseline.baseline(summaryOnly)) { - if (summaryOnly) { - MemSummaryReporter rpt(baseline, output(), scale_unit); - rpt.report(); - } else { - MemDetailReporter rpt(baseline, output(), scale_unit); - rpt.report(); - } + baseline.baseline(summaryOnly); + if (summaryOnly) { + MemSummaryReporter rpt(baseline, output(), scale_unit); + rpt.report(); + } else { + MemDetailReporter rpt(baseline, output(), scale_unit); + rpt.report(); } } @@ -176,14 +172,13 @@ "Not a detail baseline"); MemBaseline baseline; - if (baseline.baseline(summaryOnly)) { - if (summaryOnly) { - MemSummaryDiffReporter rpt(early_baseline, baseline, output(), scale_unit); - rpt.report_diff(); - } else { - MemDetailDiffReporter rpt(early_baseline, baseline, output(), scale_unit); - rpt.report_diff(); - } + baseline.baseline(summaryOnly); + if (summaryOnly) { + MemSummaryDiffReporter rpt(early_baseline, baseline, output(), scale_unit); + rpt.report_diff(); + } else { + MemDetailDiffReporter rpt(early_baseline, baseline, output(), scale_unit); + rpt.report_diff(); } } diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/services/threadStackTracker.cpp openjdk-17-17.0.13+11/src/hotspot/share/services/threadStackTracker.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/services/threadStackTracker.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/services/threadStackTracker.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -49,40 +49,38 @@ void ThreadStackTracker::new_thread_stack(void* base, size_t size, const NativeCallStack& stack) { assert(MemTracker::tracking_level() >= NMT_summary, "Must be"); assert(base != NULL, "Should have been filtered"); + ThreadCritical tc; if (track_as_vm()) { - ThreadCritical tc; VirtualMemoryTracker::add_reserved_region((address)base, size, stack, mtThreadStack); - _thread_count ++; } else { // Use a slot in mallocMemorySummary for thread stack bookkeeping MallocMemorySummary::record_malloc(size, mtThreadStack); if (MemTracker::tracking_level() == NMT_detail) { - ThreadCritical tc; assert(_simple_thread_stacks != NULL, "Must be initialized"); SimpleThreadStackSite site((address)base, size, stack); _simple_thread_stacks->add(site); } } + _thread_count++; } void ThreadStackTracker::delete_thread_stack(void* base, size_t size) { assert(MemTracker::tracking_level() >= NMT_summary, "Must be"); assert(base != NULL, "Should have been filtered"); + ThreadCritical tc; if(track_as_vm()) { - ThreadCritical tc; VirtualMemoryTracker::remove_released_region((address)base, size); - _thread_count--; } else { // Use a slot in mallocMemorySummary for thread stack bookkeeping MallocMemorySummary::record_free(size, mtThreadStack); if (MemTracker::tracking_level() == NMT_detail) { - ThreadCritical tc; assert(_simple_thread_stacks != NULL, "Must be initialized"); SimpleThreadStackSite site((address)base, size, NativeCallStack::empty_stack()); // Fake object just to serve as compare target for delete bool removed = _simple_thread_stacks->remove(site); assert(removed, "Must exist"); } } + _thread_count--; } bool ThreadStackTracker::walk_simple_thread_stack_site(MallocSiteWalker* walker) { diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/utilities/concurrentHashTable.inline.hpp openjdk-17-17.0.13+11/src/hotspot/share/utilities/concurrentHashTable.inline.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/utilities/concurrentHashTable.inline.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/utilities/concurrentHashTable.inline.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -35,6 +35,8 @@ #include "utilities/numberSeq.hpp" #include "utilities/spinYield.hpp" +#include + // 2^30 = 1G buckets #define SIZE_BIG_LOG2 30 // 2^5 = 32 buckets @@ -499,7 +501,7 @@ Bucket* prefetch_bucket = (bucket_it+1) < stop_idx ? table->get_bucket(bucket_it+1) : NULL; - if (!HaveDeletables::value, EVALUATE_FUNC>:: + if (!HaveDeletables::value, EVALUATE_FUNC>:: have_deletable(bucket, eval_f, prefetch_bucket)) { // Nothing to remove in this bucket. continue; @@ -1197,23 +1199,30 @@ inline TableStatistics ConcurrentHashTable:: statistics_calculate(Thread* thread, VALUE_SIZE_FUNC& vs_f) { + constexpr size_t batch_size = 128; NumberSeq summary; size_t literal_bytes = 0; InternalTable* table = get_table(); - for (size_t bucket_it = 0; bucket_it < table->_size; bucket_it++) { + size_t num_batches = table->_size / batch_size; + for (size_t batch_start = 0; batch_start < _table->_size; batch_start += batch_size) { + // We batch the use of ScopedCS here as it has been found to be quite expensive to + // invoke it for every single bucket. + size_t batch_end = MIN2(batch_start + batch_size, _table->_size); ScopedCS cs(thread, this); - size_t count = 0; - Bucket* bucket = table->get_bucket(bucket_it); - if (bucket->have_redirect() || bucket->is_locked()) { - continue; - } - Node* current_node = bucket->first(); - while (current_node != NULL) { - ++count; - literal_bytes += vs_f(current_node->value()); - current_node = current_node->next(); + for (size_t bucket_it = batch_start; bucket_it < batch_end; bucket_it++) { + size_t count = 0; + Bucket* bucket = table->get_bucket(bucket_it); + if (bucket->have_redirect() || bucket->is_locked()) { + continue; + } + Node* current_node = bucket->first(); + while (current_node != nullptr) { + ++count; + literal_bytes += vs_f(current_node->value()); + current_node = current_node->next(); + } + summary.add((double)count); } - summary.add((double)count); } return TableStatistics(_stats_rate, summary, literal_bytes, sizeof(Bucket), sizeof(Node)); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/utilities/debug.cpp openjdk-17-17.0.13+11/src/hotspot/share/utilities/debug.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/utilities/debug.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/utilities/debug.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -440,7 +440,7 @@ extern "C" JNIEXPORT void printnm(intptr_t p) { char buffer[256]; - sprintf(buffer, "printnm: " INTPTR_FORMAT, p); + os::snprintf_checked(buffer, sizeof(buffer), "printnm: " INTPTR_FORMAT, p); Command c(buffer); CodeBlob* cb = CodeCache::find_blob((address) p); if (cb->is_nmethod()) { diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/utilities/events.cpp openjdk-17-17.0.13+11/src/hotspot/share/utilities/events.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/utilities/events.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/utilities/events.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -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 @@ -35,6 +35,8 @@ EventLog* Events::_logs = NULL; StringEventLog* Events::_messages = NULL; +StringEventLog* Events::_memprotect_messages = NULL; +StringEventLog* Events::_nmethod_flush_messages = NULL; StringEventLog* Events::_vm_operations = NULL; ExceptionsEventLog* Events::_exceptions = NULL; StringEventLog* Events::_redefinitions = NULL; @@ -94,6 +96,8 @@ void Events::init() { if (LogEvents) { _messages = new StringEventLog("Events", "events"); + _nmethod_flush_messages = new StringEventLog("Nmethod flushes", "nmethodflushes"); + _memprotect_messages = new StringEventLog("Memory protections", "memprotects"); _vm_operations = new StringEventLog("VM Operations", "vmops"); _exceptions = new ExceptionsEventLog("Internal exceptions", "exc"); _redefinitions = new StringEventLog("Classes redefined", "redef"); diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/utilities/events.hpp openjdk-17-17.0.13+11/src/hotspot/share/utilities/events.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/utilities/events.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/utilities/events.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2020, 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 @@ -220,6 +220,12 @@ // A log for generic messages that aren't well categorized. static StringEventLog* _messages; + // A log for memory protection related messages + static StringEventLog* _memprotect_messages; + + // A log for nmethod flush operations + static StringEventLog* _nmethod_flush_messages; + // A log for VM Operations static StringEventLog* _vm_operations; @@ -256,6 +262,10 @@ // Logs a generic message with timestamp and format as printf. static void log(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + static void log_memprotect(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + + static void log_nmethod_flush(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + static void log_vm_operation(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(2, 3); // Log exception related message @@ -284,6 +294,24 @@ va_end(ap); } } + +inline void Events::log_memprotect(Thread* thread, const char* format, ...) { + if (LogEvents && _memprotect_messages != nullptr) { + va_list ap; + va_start(ap, format); + _memprotect_messages->logv(thread, format, ap); + va_end(ap); + } +} + +inline void Events::log_nmethod_flush(Thread* thread, const char* format, ...) { + if (LogEvents && _nmethod_flush_messages != nullptr) { + va_list ap; + va_start(ap, format); + _nmethod_flush_messages->logv(thread, format, ap); + va_end(ap); + } +} inline void Events::log_vm_operation(Thread* thread, const char* format, ...) { if (LogEvents && _vm_operations != NULL) { diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/utilities/ostream.cpp openjdk-17-17.0.13+11/src/hotspot/share/utilities/ostream.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/utilities/ostream.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/utilities/ostream.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -614,7 +614,7 @@ void fdStream::write(const char* s, size_t len) { if (_fd != -1) { // Make an unused local variable to avoid warning from gcc compiler. - size_t count = ::write(_fd, s, (int)len); + ssize_t count = ::write(_fd, s, (int)len); update_position(s, len); } } diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/utilities/population_count.hpp openjdk-17-17.0.13+11/src/hotspot/share/utilities/population_count.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/utilities/population_count.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/utilities/population_count.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -25,13 +25,12 @@ #ifndef SHARE_UTILITIES_POPULATION_COUNT_HPP #define SHARE_UTILITIES_POPULATION_COUNT_HPP -#include "metaprogramming/conditional.hpp" #include "metaprogramming/enableIf.hpp" -#include "metaprogramming/isIntegral.hpp" -#include "metaprogramming/isSigned.hpp" #include "utilities/debug.hpp" #include "utilities/globalDefinitions.hpp" +#include + // Returns the population count of x, i.e., the number of bits set in x. // // Adapted from Hacker's Delight, 2nd Edition, Figure 5-2 and the text that @@ -47,12 +46,12 @@ inline unsigned population_count(T x) { STATIC_ASSERT(BitsPerWord <= 128); STATIC_ASSERT(BitsPerByte == 8); - STATIC_ASSERT(IsIntegral::value); - STATIC_ASSERT(!IsSigned::value); + STATIC_ASSERT(std::is_integral::value); + STATIC_ASSERT(!std::is_signed::value); // We need to take care with implicit integer promotion when dealing with // integers < 32-bit. We chose to do this by explicitly widening constants // to unsigned - typedef typename Conditional<(sizeof(T) < sizeof(unsigned)), unsigned, T>::type P; + using P = std::conditional_t<(sizeof(T) < sizeof(unsigned)), unsigned, T>; const T all = ~T(0); // 0xFF..FF const P fives = all/3; // 0x55..55 const P threes = (all/15) * 3; // 0x33..33 diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/utilities/utf8.cpp openjdk-17-17.0.13+11/src/hotspot/share/utilities/utf8.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/utilities/utf8.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/utilities/utf8.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "utilities/utf8.hpp" +#include "runtime/os.hpp" // Assume the utf8 string is in legal form and has been // checked in the class file parser/format checker. @@ -220,7 +221,7 @@ *p++ = (char)c; } else { if (p + 6 >= end) break; // string is truncated - sprintf(p, "\\u%04x", c); + os::snprintf_checked(p, 7, "\\u%04x", c); // counting terminating zero in p += 6; } } @@ -518,7 +519,7 @@ *p++ = (char)c; } else { if (p + 6 >= end) break; // string is truncated - sprintf(p, "\\u%04x", c); + os::snprintf_checked(p, 7, "\\u%04x", c); p += 6; } } diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/utilities/vmassert_reinstall.hpp openjdk-17-17.0.13+11/src/hotspot/share/utilities/vmassert_reinstall.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/utilities/vmassert_reinstall.hpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/utilities/vmassert_reinstall.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -0,0 +1,36 @@ +/* + * 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. + * + */ + +// Intentionally no #include guard. May be included multiple times for effect. + +// See vmassert_uninstall.hpp for usage. + +// Remove possible stdlib assert macro (or any others, for that matter). +#undef assert + +// Reinstall HotSpot's assert macro, if previously defined. +#ifdef vmassert +#define assert(p, ...) vmassert(p, __VA_ARGS__) +#endif + diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/utilities/vmassert_uninstall.hpp openjdk-17-17.0.13+11/src/hotspot/share/utilities/vmassert_uninstall.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/utilities/vmassert_uninstall.hpp 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/utilities/vmassert_uninstall.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -0,0 +1,45 @@ +/* + * 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. + * + */ + +// Intentionally no #include guard. May be included multiple times for effect. + +// The files vmassert_uninstall.hpp and vmassert_reinstall.hpp provide a +// workaround for the name collision between HotSpot's assert macro and the +// Standard Library's assert macro. When including a 3rd-party header that +// uses (and so includes) the standard assert macro, wrap that inclusion with +// includes of these two files, e.g. +// +// #include "utilities/vmassert_uninstall.hpp" +// #include

+// #include "utilities/vmassert_reinstall.hpp" +// +// This removes the HotSpot macro definition while pre-processing the +// 3rd-party header, then reinstates the HotSpot macro (if previously defined) +// for following code. + +// Remove HotSpot's assert macro, if present. +#ifdef vmassert +#undef assert +#endif // vmassert + diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/utilities/waitBarrier_generic.cpp openjdk-17-17.0.13+11/src/hotspot/share/utilities/waitBarrier_generic.cpp --- openjdk-17-17.0.12+7/src/hotspot/share/utilities/waitBarrier_generic.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/utilities/waitBarrier_generic.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,6 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. * 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,66 +30,228 @@ #include "utilities/waitBarrier_generic.hpp" #include "utilities/spinYield.hpp" +// Implements the striped semaphore wait barrier. +// +// To guarantee progress and safety, we need to make sure that new barrier tag +// starts with the completely empty set of waiters and free semaphore. This +// requires either waiting for all threads to leave wait() for current barrier +// tag on disarm(), or waiting for all threads to leave the previous tag before +// reusing the semaphore in arm(). +// +// When there are multiple threads, it is normal for some threads to take +// significant time to leave the barrier. Waiting for these threads introduces +// stalls on barrier reuse. +// +// If we wait on disarm(), this stall is nearly guaranteed to happen if some threads +// are de-scheduled by prior wait(). It would be especially bad if there are more +// waiting threads than CPUs: every thread would need to wake up and register itself +// as leaving, before we can unblock from disarm(). +// +// If we wait on arm(), we can get lucky that most threads would be able to catch up, +// exit wait(), and so we arrive to arm() with semaphore ready for reuse. However, +// that is still insufficient in practice. +// +// Therefore, this implementation goes a step further and implements the _striped_ +// semaphores. We maintain several semaphores in cells. The barrier tags are assigned +// to cells in some simple manner. Most of the current uses have sequential barrier +// tags, so simple modulo works well. We then operate on a cell like we would operate +// on a single semaphore: we wait at arm() for all threads to catch up before reusing +// the cell. For the cost of maintaining just a few cells, we have enough window for +// threads to catch up. +// +// The correctness is guaranteed by using a single atomic state variable per cell, +// with updates always done with CASes: +// +// [.......... barrier tag ..........][.......... waiters ..........] +// 63 31 0 +// +// Cell starts with zero tag and zero waiters. Arming the cell swings barrier tag from +// zero to some tag, while checking that no waiters have appeared. Disarming swings +// the barrier tag back from tag to zero. Every waiter registers itself by incrementing +// the "waiters", while checking that barrier tag is still the same. Every completing waiter +// decrements the "waiters". When all waiters complete, a cell ends up in initial state, +// ready to be armed again. This allows accurate tracking of how many signals +// to issue and does not race with disarm. +// +// The implementation uses the strongest (default) barriers for extra safety, even +// when not strictly required to do so for correctness. Extra barrier overhead is +// dominated by the actual wait/notify latency anyway. +// + void GenericWaitBarrier::arm(int barrier_tag) { - assert(_barrier_tag == 0, "Already armed"); - assert(_waiters == 0, "We left a thread hanging"); - _barrier_tag = barrier_tag; - _waiters = 0; + assert(barrier_tag != 0, "Pre arm: Should be arming with armed value"); + assert(Atomic::load(&_barrier_tag) == 0, + "Pre arm: Should not be already armed. Tag: %d", + Atomic::load(&_barrier_tag)); + Atomic::release_store(&_barrier_tag, barrier_tag); + + Cell &cell = tag_to_cell(barrier_tag); + cell.arm(barrier_tag); + + // API specifies arm() must provide a trailing fence. OrderAccess::fence(); } -int GenericWaitBarrier::wake_if_needed() { - assert(_barrier_tag == 0, "Not disarmed"); - int w = _waiters; - if (w == 0) { - // Load of _barrier_threads in caller must not pass the load of _waiters. - OrderAccess::loadload(); - return 0; - } - assert(w > 0, "Bad counting"); - // We need an exact count which never goes below zero, - // otherwise the semaphore may be signalled too many times. - if (Atomic::cmpxchg(&_waiters, w, w - 1) == w) { - _sem_barrier.signal(); - return w - 1; - } - return w; +void GenericWaitBarrier::disarm() { + int barrier_tag = Atomic::load_acquire(&_barrier_tag); + assert(barrier_tag != 0, "Pre disarm: Should be armed. Tag: %d", barrier_tag); + Atomic::release_store(&_barrier_tag, 0); + + Cell &cell = tag_to_cell(barrier_tag); + cell.disarm(barrier_tag); + + // API specifies disarm() must provide a trailing fence. + OrderAccess::fence(); } -void GenericWaitBarrier::disarm() { - assert(_barrier_tag != 0, "Not armed"); - _barrier_tag = 0; - // Loads of _barrier_threads/_waiters must not float above disarm store and - // disarm store must not sink below. +void GenericWaitBarrier::wait(int barrier_tag) { + assert(barrier_tag != 0, "Pre wait: Should be waiting on armed value"); + + Cell &cell = tag_to_cell(barrier_tag); + cell.wait(barrier_tag); + + // API specifies wait() must provide a trailing fence. OrderAccess::fence(); - int left; +} + +void GenericWaitBarrier::Cell::arm(int32_t requested_tag) { + // Before we continue to arm, we need to make sure that all threads + // have left the previous cell. + + int64_t state; + SpinYield sp; - do { - left = GenericWaitBarrier::wake_if_needed(); - if (left == 0 && _barrier_threads > 0) { - // There is no thread to wake but we still have barrier threads. + while (true) { + state = Atomic::load_acquire(&_state); + assert(decode_tag(state) == 0, + "Pre arm: Should not be armed. " + "Tag: " INT32_FORMAT "; Waiters: " INT32_FORMAT, + decode_tag(state), decode_waiters(state)); + if (decode_waiters(state) == 0) { + break; + } + sp.wait(); + } + + // Try to swing cell to armed. This should always succeed after the check above. + int64_t new_state = encode(requested_tag, 0); + int64_t prev_state = Atomic::cmpxchg(&_state, state, new_state); + if (prev_state != state) { + fatal("Cannot arm the wait barrier. " + "Tag: " INT32_FORMAT "; Waiters: " INT32_FORMAT, + decode_tag(prev_state), decode_waiters(prev_state)); + } +} + +int GenericWaitBarrier::Cell::signal_if_needed(int max) { + int signals = 0; + while (true) { + int cur = Atomic::load_acquire(&_outstanding_wakeups); + if (cur == 0) { + // All done, no more waiters. + return 0; + } + assert(cur > 0, "Sanity"); + + int prev = Atomic::cmpxchg(&_outstanding_wakeups, cur, cur - 1); + if (prev != cur) { + // Contention, return to caller for early return or backoff. + return prev; + } + + // Signal! + _sem.signal(); + + if (++signals >= max) { + // Signalled requested number of times, break out. + return prev; + } + } +} + +void GenericWaitBarrier::Cell::disarm(int32_t expected_tag) { + int32_t waiters; + + while (true) { + int64_t state = Atomic::load_acquire(&_state); + int32_t tag = decode_tag(state); + waiters = decode_waiters(state); + + assert((tag == expected_tag) && (waiters >= 0), + "Mid disarm: Should be armed with expected tag and have sane waiters. " + "Tag: " INT32_FORMAT "; Waiters: " INT32_FORMAT, + tag, waiters); + + int64_t new_state = encode(0, waiters); + if (Atomic::cmpxchg(&_state, state, new_state) == state) { + // Successfully disarmed. + break; + } + } + + // Wake up waiters, if we have at least one. + // Allow other threads to assist with wakeups, if possible. + if (waiters > 0) { + Atomic::release_store(&_outstanding_wakeups, waiters); + SpinYield sp; + while (signal_if_needed(INT_MAX) > 0) { sp.wait(); } - // We must loop here until there are no waiters or potential waiters. - } while (left > 0 || _barrier_threads > 0); - // API specifies disarm() must provide a trailing fence. - OrderAccess::fence(); + } + assert(Atomic::load(&_outstanding_wakeups) == 0, "Post disarm: Should not have outstanding wakeups"); } -void GenericWaitBarrier::wait(int barrier_tag) { - assert(barrier_tag != 0, "Trying to wait on disarmed value"); - if (barrier_tag != _barrier_tag) { - // API specifies wait() must provide a trailing fence. - OrderAccess::fence(); - return; - } - Atomic::add(&_barrier_threads, 1); - if (barrier_tag != 0 && barrier_tag == _barrier_tag) { - Atomic::add(&_waiters, 1); - _sem_barrier.wait(); - // We help out with posting, but we need to do so before we decrement the - // _barrier_threads otherwise we might wake threads up in next wait. - GenericWaitBarrier::wake_if_needed(); +void GenericWaitBarrier::Cell::wait(int32_t expected_tag) { + // Try to register ourselves as pending waiter. + while (true) { + int64_t state = Atomic::load_acquire(&_state); + int32_t tag = decode_tag(state); + if (tag != expected_tag) { + // Cell tag had changed while waiting here. This means either the cell had + // been disarmed, or we are late and the cell was armed with a new tag. + // Exit without touching anything else. + return; + } + int32_t waiters = decode_waiters(state); + + assert((tag == expected_tag) && (waiters >= 0 && waiters < INT32_MAX), + "Before wait: Should be armed with expected tag and waiters are in range. " + "Tag: " INT32_FORMAT "; Waiters: " INT32_FORMAT, + tag, waiters); + + int64_t new_state = encode(tag, waiters + 1); + if (Atomic::cmpxchg(&_state, state, new_state) == state) { + // Success! Proceed to wait. + break; + } + } + + // Wait for notification. + _sem.wait(); + + // Unblocked! We help out with waking up two siblings. This allows to avalanche + // the wakeups for many threads, even if some threads are lagging behind. + // Note that we can only do this *before* reporting back as completed waiter, + // otherwise we might prematurely wake up threads for another barrier tag. + // Current arm() sequence protects us from this trouble by waiting until all waiters + // leave. + signal_if_needed(2); + + // Register ourselves as completed waiter before leaving. + while (true) { + int64_t state = Atomic::load_acquire(&_state); + int32_t tag = decode_tag(state); + int32_t waiters = decode_waiters(state); + + assert((tag == 0) && (waiters > 0), + "After wait: Should be not armed and have non-complete waiters. " + "Tag: " INT32_FORMAT "; Waiters: " INT32_FORMAT, + tag, waiters); + + int64_t new_state = encode(tag, waiters - 1); + if (Atomic::cmpxchg(&_state, state, new_state) == state) { + // Success! + break; + } } - Atomic::add(&_barrier_threads, -1); } diff -Nru openjdk-17-17.0.12+7/src/hotspot/share/utilities/waitBarrier_generic.hpp openjdk-17-17.0.13+11/src/hotspot/share/utilities/waitBarrier_generic.hpp --- openjdk-17-17.0.12+7/src/hotspot/share/utilities/waitBarrier_generic.hpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/hotspot/share/utilities/waitBarrier_generic.hpp 2024-10-10 14:01:59.000000000 +0000 @@ -26,29 +26,79 @@ #define SHARE_UTILITIES_WAITBARRIER_GENERIC_HPP #include "memory/allocation.hpp" +#include "memory/padded.hpp" #include "runtime/semaphore.hpp" #include "utilities/globalDefinitions.hpp" -// In addition to the barrier tag, it uses two counters to keep the semaphore -// count correct and not leave any late thread waiting. class GenericWaitBarrier : public CHeapObj { +private: + class Cell : public CHeapObj { + private: + // Pad out the cells to avoid interference between the cells. + // This would insulate from stalls when adjacent cells have returning + // workers and contend over the cache line for current latency-critical + // cell. + DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0); + + Semaphore _sem; + + // Cell state, tracks the arming + waiters status + volatile int64_t _state; + + // Wakeups to deliver for current waiters + volatile int _outstanding_wakeups; + + int signal_if_needed(int max); + + static int64_t encode(int32_t barrier_tag, int32_t waiters) { + int64_t val = (((int64_t) barrier_tag) << 32) | + (((int64_t) waiters) & 0xFFFFFFFF); + assert(decode_tag(val) == barrier_tag, "Encoding is reversible"); + assert(decode_waiters(val) == waiters, "Encoding is reversible"); + return val; + } + + static int32_t decode_tag(int64_t value) { + return (int32_t)(value >> 32); + } + + static int32_t decode_waiters(int64_t value) { + return (int32_t)(value & 0xFFFFFFFF); + } + + public: + Cell() : _sem(0), _state(encode(0, 0)), _outstanding_wakeups(0) {} + NONCOPYABLE(Cell); + + void arm(int32_t requested_tag); + void disarm(int32_t expected_tag); + void wait(int32_t expected_tag); + }; + + // Should be enough for most uses without exploding the footprint. + static constexpr int CELLS_COUNT = 16; + + Cell _cells[CELLS_COUNT]; + + // Trailing padding to protect the last cell. + DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0); + volatile int _barrier_tag; - // The number of threads waiting on or about to wait on the semaphore. - volatile int _waiters; - // The number of threads in the wait path, before or after the tag check. - // These threads can become waiters. - volatile int _barrier_threads; - Semaphore _sem_barrier; + + // Trailing padding to insulate the rest of the barrier from adjacent + // data structures. The leading padding is not needed, as cell padding + // handles this for us. + DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, 0); NONCOPYABLE(GenericWaitBarrier); - int wake_if_needed(); + Cell& tag_to_cell(int tag) { return _cells[tag & (CELLS_COUNT - 1)]; } - public: - GenericWaitBarrier() : _barrier_tag(0), _waiters(0), _barrier_threads(0), _sem_barrier(0) {} +public: + GenericWaitBarrier() : _cells(), _barrier_tag(0) {} ~GenericWaitBarrier() {} - const char* description() { return "semaphore"; } + const char* description() { return "striped semaphore"; } void arm(int barrier_tag); void disarm(); diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/java/lang/System.java openjdk-17-17.0.13+11/src/java.base/share/classes/java/lang/System.java --- openjdk-17-17.0.12+7/src/java.base/share/classes/java/lang/System.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/java/lang/System.java 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 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 @@ -726,6 +726,9 @@ * Java Runtime Environment specification version, whose value is * the {@linkplain Runtime.Version#feature feature} element of the * {@linkplain Runtime#version() runtime version} + * {@systemProperty java.specification.maintenance.version} + * Java Runtime Environment specification maintenance version, + * may be interpreted as a positive integer (optional, see below) * {@systemProperty java.specification.vendor} * Java Runtime Environment specification vendor * {@systemProperty java.specification.name} @@ -765,6 +768,16 @@ * * *

+ * The {@code java.specification.maintenance.version} property is + * defined if the specification implemented by this runtime at the + * time of its construction had undergone a maintenance + * release. When defined, its value identifies that + * maintenance release. To indicate the first maintenance release + * this property will have the value {@code "1"}, to indicate the + * second maintenance release this property will have the value + * {@code "2"}, and so on. + *

* Multiple paths in a system property value are separated by the path * separator character of the platform. *

diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/java/lang/VersionProps.java.template openjdk-17-17.0.13+11/src/java.base/share/classes/java/lang/VersionProps.java.template --- openjdk-17-17.0.12+7/src/java.base/share/classes/java/lang/VersionProps.java.template 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/java/lang/VersionProps.java.template 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2020, 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 @@ -109,6 +109,7 @@ props.put("java.class.version", CLASSFILE_MAJOR_MINOR); props.put("java.specification.version", VERSION_SPECIFICATION); + props.put("java.specification.maintenance.version", "1"); props.put("java.specification.name", "Java Platform API Specification"); props.put("java.specification.vendor", "Oracle Corporation"); diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/java/net/doc-files/net-properties.html openjdk-17-17.0.13+11/src/java.base/share/classes/java/net/doc-files/net-properties.html --- openjdk-17-17.0.12+7/src/java.base/share/classes/java/net/doc-files/net-properties.html 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/java/net/doc-files/net-properties.html 2024-10-10 14:01:59.000000000 +0000 @@ -240,6 +240,15 @@

The channel binding tokens generated are of the type "tls-server-end-point" as defined in RFC 5929.

+ +
  • {@systemProperty jdk.http.maxHeaderSize} (default: 393216 or 384kB)
    + This is the maximum header field section size that a client is prepared to accept. + This is computed as the sum of the size of the uncompressed header name, plus + the size of the uncompressed header value, plus an overhead of 32 bytes for + each field section line. If a peer sends a field section that exceeds this + size a {@link java.net.ProtocolException ProtocolException} will be raised. + This applies to all versions of the HTTP protocol. A value of zero or a negative + value means no limit. If left unspecified, the default value is 393216 bytes.

    All these properties are checked only once at startup.

    diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/java/security/Provider.java openjdk-17-17.0.13+11/src/java.base/share/classes/java/security/Provider.java --- openjdk-17-17.0.12+7/src/java.base/share/classes/java/security/Provider.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/java/security/Provider.java 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, 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 @@ -27,7 +27,9 @@ import jdk.internal.event.SecurityProviderServiceEvent; +import javax.security.auth.login.Configuration; import java.io.*; +import java.security.cert.CertStoreParameters; import java.util.*; import static java.util.Locale.ENGLISH; import java.lang.ref.*; @@ -193,6 +195,8 @@ this.versionStr = Double.toString(version); this.info = info; this.serviceMap = new ConcurrentHashMap<>(); + this.legacyMap = new ConcurrentHashMap<>(); + this.prngAlgos = new LinkedHashSet(6); putId(); initialized = true; } @@ -231,6 +235,8 @@ this.version = parseVersionStr(versionStr); this.info = info; this.serviceMap = new ConcurrentHashMap<>(); + this.legacyMap = new ConcurrentHashMap<>(); + this.prngAlgos = new LinkedHashSet(6); putId(); initialized = true; } @@ -574,7 +580,6 @@ public synchronized boolean replace(Object key, Object oldValue, Object newValue) { check("putProviderProperty." + name); - if (debug != null) { debug.println("Replace " + name + " provider property " + key); } @@ -600,7 +605,6 @@ @Override public synchronized Object replace(Object key, Object value) { check("putProviderProperty." + name); - if (debug != null) { debug.println("Replace " + name + " provider property " + key); } @@ -629,7 +633,6 @@ public synchronized void replaceAll(BiFunction function) { check("putProviderProperty." + name); - if (debug != null) { debug.println("ReplaceAll " + name + " provider property "); } @@ -659,7 +662,6 @@ ? super Object, ? extends Object> remappingFunction) { check("putProviderProperty." + name); check("removeProviderProperty." + name); - if (debug != null) { debug.println("Compute " + name + " provider property " + key); } @@ -686,11 +688,10 @@ * @since 1.8 */ @Override - public synchronized Object computeIfAbsent(Object key, Function mappingFunction) { + public synchronized Object computeIfAbsent(Object key, + Function mappingFunction) { check("putProviderProperty." + name); check("removeProviderProperty." + name); - if (debug != null) { debug.println("ComputeIfAbsent " + name + " provider property " + key); @@ -716,11 +717,11 @@ * @since 1.8 */ @Override - public synchronized Object computeIfPresent(Object key, BiFunction remappingFunction) { + public synchronized Object computeIfPresent(Object key, + BiFunction + remappingFunction) { check("putProviderProperty." + name); check("removeProviderProperty." + name); - if (debug != null) { debug.println("ComputeIfPresent " + name + " provider property " + key); @@ -749,11 +750,11 @@ * @since 1.8 */ @Override - public synchronized Object merge(Object key, Object value, BiFunction remappingFunction) { + public synchronized Object merge(Object key, Object value, + BiFunction + remappingFunction) { check("putProviderProperty." + name); check("removeProviderProperty." + name); - if (debug != null) { debug.println("Merge " + name + " provider property " + key); } @@ -779,7 +780,8 @@ * @since 1.8 */ @Override - public synchronized void forEach(BiConsumer action) { + public synchronized void forEach(BiConsumer + action) { checkInitialized(); super.forEach(action); } @@ -819,14 +821,11 @@ } } - // legacy properties changed since last call to any services method? - private transient boolean legacyChanged; + // legacyMap changed since last call to getServices() + private transient volatile boolean legacyChanged; // serviceMap changed since last call to getServices() private volatile transient boolean servicesChanged; - // Map used to keep track of legacy registration - private transient Map legacyStrings; - // Map // used for services added via putService(), initialized on demand private transient Map serviceMap; @@ -834,6 +833,9 @@ // For backward compatibility, the registration ordering of // SecureRandom (RNG) algorithms needs to be preserved for // "new SecureRandom()" calls when this provider is used + // NOTE: may need extra mechanism for providers to indicate their + // preferred ordering of SecureRandom algorithms since registration + // ordering info is lost once serialized private transient Set prngAlgos; // Map @@ -842,7 +844,7 @@ // Set // Unmodifiable set of all services. Initialized on demand. - private transient Set serviceSet; + private transient volatile Set serviceSet; // register the id attributes for this provider // this is to ensure that equals() and hashCode() do not incorrectly @@ -874,6 +876,7 @@ for (Map.Entry entry : super.entrySet()) { copy.put(entry.getKey(), entry.getValue()); } + defaults = null; in.defaultReadObject(); if (this.versionStr == null) { @@ -884,23 +887,22 @@ this.version = parseVersionStr(this.versionStr); } this.serviceMap = new ConcurrentHashMap<>(); + this.legacyMap = new ConcurrentHashMap<>(); + this.prngAlgos = new LinkedHashSet(6); implClear(); initialized = true; putAll(copy); } - // check whether to update 'legacyString' with the specified key - private boolean checkLegacy(Object key) { - String keyString = (String)key; - if (keyString.startsWith("Provider.")) { + // returns false if no update necessary, i.e. key isn't String or + // is String but it's provider-related (name/version/info/className) + private static boolean checkLegacy(Object key) { + if (key instanceof String && ((String)key).startsWith("Provider.")) { + // ignore provider related updates return false; + } else { + return true; } - - legacyChanged = true; - if (legacyStrings == null) { - legacyStrings = new LinkedHashMap<>(); - } - return true; } /** @@ -915,149 +917,161 @@ } private Object implRemove(Object key) { - if (key instanceof String) { - if (!checkLegacy(key)) { - return null; - } - legacyStrings.remove((String)key); + if (!checkLegacy(key)) return null; + + Object o = super.remove(key); + if (o instanceof String so && key instanceof String sk) { + parseLegacy(sk, so, OPType.REMOVE); } - return super.remove(key); + return o; } private boolean implRemove(Object key, Object value) { - if (key instanceof String && value instanceof String) { - if (!checkLegacy(key)) { - return false; - } - legacyStrings.remove((String)key, (String)value); + if (!checkLegacy(key)) return false; + + boolean result = super.remove(key, value); + if (result && key instanceof String sk && value instanceof String sv) { + parseLegacy(sk, sv, OPType.REMOVE); } - return super.remove(key, value); + return result; } private boolean implReplace(Object key, Object oldValue, Object newValue) { - if ((key instanceof String) && (oldValue instanceof String) && - (newValue instanceof String)) { - if (!checkLegacy(key)) { - return false; + if (!checkLegacy(key)) return false; + + boolean result = super.replace(key, oldValue, newValue); + if (result && key instanceof String sk) { + if (newValue instanceof String sv) { + parseLegacy(sk, sv, OPType.ADD); + } else if (oldValue instanceof String sv) { + parseLegacy(sk, sv, OPType.REMOVE); } - legacyStrings.replace((String)key, (String)oldValue, - (String)newValue); } - return super.replace(key, oldValue, newValue); + return result; } private Object implReplace(Object key, Object value) { - if ((key instanceof String) && (value instanceof String)) { - if (!checkLegacy(key)) { - return null; + if (!checkLegacy(key)) return null; + + Object o = super.replace(key, value); + if (key instanceof String sk) { + if (o instanceof String so) { + if (value instanceof String sv) { + parseLegacy(sk, sv, OPType.ADD); + } else { + parseLegacy(sk, so, OPType.REMOVE); + } } - legacyStrings.replace((String)key, (String)value); } - return super.replace(key, value); + return o; } @SuppressWarnings("unchecked") // Function must actually operate over strings private void implReplaceAll(BiFunction function) { + + super.replaceAll(function); + // clear out all existing mappings and start fresh + legacyMap.clear(); legacyChanged = true; - if (legacyStrings == null) { - legacyStrings = new LinkedHashMap<>(); - } else { - legacyStrings.replaceAll((BiFunction) function); + for (Map.Entry entry : super.entrySet()) { + Object key = entry.getKey(); + Object value = entry.getValue(); + if ((key instanceof String sk) && (value instanceof String sv)) { + if (!checkLegacy(sk)) { + continue; + } + parseLegacy(sk, sv, OPType.ADD); + } } - super.replaceAll(function); } @SuppressWarnings("unchecked") // Function must actually operate over strings private Object implMerge(Object key, Object value, BiFunction remappingFunction) { - if ((key instanceof String) && (value instanceof String)) { - if (!checkLegacy(key)) { - return null; - } - legacyStrings.merge((String)key, (String)value, - (BiFunction) remappingFunction); + if (!checkLegacy(key)) return null; + + Object o = super.merge(key, value, remappingFunction); + if (key instanceof String sk) { + if (o == null) { + parseLegacy(sk, null, OPType.REMOVE); + } else if (o instanceof String so) { + parseLegacy(sk, so, OPType.ADD); + } } - return super.merge(key, value, remappingFunction); + return o; } @SuppressWarnings("unchecked") // Function must actually operate over strings private Object implCompute(Object key, BiFunction remappingFunction) { - if (key instanceof String) { - if (!checkLegacy(key)) { - return null; - } - legacyStrings.compute((String) key, - (BiFunction) remappingFunction); + + if (!checkLegacy(key)) return null; + + Object o = super.compute(key, remappingFunction); + if (key instanceof String sk) { + if (o == null) { + parseLegacy(sk, null, OPType.REMOVE); + } else if (o instanceof String so) { + parseLegacy(sk, so, OPType.ADD); + } } - return super.compute(key, remappingFunction); + return o; } @SuppressWarnings("unchecked") // Function must actually operate over strings private Object implComputeIfAbsent(Object key, Function mappingFunction) { - if (key instanceof String) { - if (!checkLegacy(key)) { - return null; - } - legacyStrings.computeIfAbsent((String) key, - (Function) - mappingFunction); + if (!checkLegacy(key)) return null; + + Object o = super.computeIfAbsent(key, mappingFunction); + if (o instanceof String so && key instanceof String sk) { + parseLegacy(sk, so, OPType.ADD); } - return super.computeIfAbsent(key, mappingFunction); + return o; } @SuppressWarnings("unchecked") // Function must actually operate over strings private Object implComputeIfPresent(Object key, BiFunction remappingFunction) { - if (key instanceof String) { - if (!checkLegacy(key)) { - return null; - } - legacyStrings.computeIfPresent((String) key, - (BiFunction) remappingFunction); + if (!checkLegacy(key)) return null; + + Object o = super.computeIfPresent(key, remappingFunction); + if (o instanceof String so && key instanceof String sk) { + parseLegacy(sk, so, OPType.ADD); } - return super.computeIfPresent(key, remappingFunction); + return o; } private Object implPut(Object key, Object value) { - if ((key instanceof String) && (value instanceof String)) { - if (!checkLegacy(key)) { - return null; - } - legacyStrings.put((String)key, (String)value); + if (!checkLegacy(key)) return null; + + Object o = super.put(key, value); + if (key instanceof String sk && value instanceof String sv) { + parseLegacy(sk, sv, OPType.ADD); } - return super.put(key, value); + return o; } private Object implPutIfAbsent(Object key, Object value) { - if ((key instanceof String) && (value instanceof String)) { - if (!checkLegacy(key)) { - return null; - } - legacyStrings.putIfAbsent((String)key, (String)value); + if (!checkLegacy(key)) return null; + + Object o = super.putIfAbsent(key, value); + if (o == null && key instanceof String sk && + value instanceof String sv) { + parseLegacy(sk, sv, OPType.ADD); } - return super.putIfAbsent(key, value); + return o; } private void implClear() { - if (legacyStrings != null) { - legacyStrings.clear(); - } - if (legacyMap != null) { - legacyMap.clear(); - } + legacyMap.clear(); serviceMap.clear(); legacyChanged = false; servicesChanged = false; serviceSet = null; - prngAlgos = null; + prngAlgos.clear(); super.clear(); putId(); } @@ -1087,40 +1101,8 @@ boolean matches(String type, String algorithm) { return (this.type == type) && (this.originalAlgorithm == algorithm); } - } - - /** - * Ensure all the legacy String properties are fully parsed into - * service objects. - */ - private void ensureLegacyParsed() { - if (legacyChanged == false || (legacyStrings == null)) { - return; - } - serviceSet = null; - if (legacyMap == null) { - legacyMap = new ConcurrentHashMap<>(); - } else { - legacyMap.clear(); - } - for (Map.Entry entry : legacyStrings.entrySet()) { - parseLegacyPut(entry.getKey(), entry.getValue()); - } - removeInvalidServices(legacyMap); - legacyChanged = false; - } - - /** - * Remove all invalid services from the Map. Invalid services can only - * occur if the legacy properties are inconsistent or incomplete. - */ - private void removeInvalidServices(Map map) { - for (Iterator> t = - map.entrySet().iterator(); t.hasNext(); ) { - Service s = t.next().getValue(); - if (s.isValid() == false) { - t.remove(); - } + public String toString() { + return type + "." + algorithm; } } @@ -1138,71 +1120,136 @@ return new String[] {type, alg}; } + // utility method for getting a String with service type and algorithm + private static String getKey(Service s) { + return s.getType() + "." + s.getAlgorithm(); + } + private static final String ALIAS_PREFIX = "Alg.Alias."; private static final String ALIAS_PREFIX_LOWER = "alg.alias."; private static final int ALIAS_LENGTH = ALIAS_PREFIX.length(); - private void parseLegacyPut(String name, String value) { + private static enum OPType { + ADD, REMOVE; + } + + private void parseLegacy(String name, String value, OPType opType) { + // alias if (name.toLowerCase(ENGLISH).startsWith(ALIAS_PREFIX_LOWER)) { // e.g. put("Alg.Alias.MessageDigest.SHA", "SHA-1"); // aliasKey ~ MessageDigest.SHA - String stdAlg = value; - String aliasKey = name.substring(ALIAS_LENGTH); - String[] typeAndAlg = getTypeAndAlgorithm(aliasKey); + String aliasKeyStr = name.substring(ALIAS_LENGTH); + String[] typeAndAlg = getTypeAndAlgorithm(aliasKeyStr); if (typeAndAlg == null) { return; } + legacyChanged = true; + Objects.requireNonNull(value, "alias value should map to an alg"); String type = getEngineName(typeAndAlg[0]); String aliasAlg = typeAndAlg[1].intern(); - ServiceKey key = new ServiceKey(type, stdAlg, true); - Service s = legacyMap.get(key); - if (s == null) { - s = new Service(this, type, stdAlg); - legacyMap.put(key, s); + ServiceKey stdKey = new ServiceKey(type, value, true); + Service stdService = legacyMap.get(stdKey); + ServiceKey aliasKey = new ServiceKey(type, aliasAlg, true); + switch (opType) { + case ADD: + // clean up old alias if present + Service prevAliasService = legacyMap.get(aliasKey); + if (prevAliasService != null) { + prevAliasService.removeAlias(aliasAlg); + } + if (stdService == null) { + // add standard mapping in order to add alias + stdService = new Service(this, type, value); + legacyMap.put(stdKey, stdService); + } + stdService.addAlias(aliasAlg); + legacyMap.put(aliasKey, stdService); + break; + case REMOVE: + if (stdService != null) { + stdService.removeAlias(aliasAlg); + } + legacyMap.remove(aliasKey); + break; + default: + throw new AssertionError(); } - legacyMap.put(new ServiceKey(type, aliasAlg, true), s); - s.addAlias(aliasAlg); } else { String[] typeAndAlg = getTypeAndAlgorithm(name); if (typeAndAlg == null) { return; } + legacyChanged = true; int i = typeAndAlg[1].indexOf(' '); + // regular registration if (i == -1) { // e.g. put("MessageDigest.SHA-1", "sun.security.provider.SHA"); String type = getEngineName(typeAndAlg[0]); String stdAlg = typeAndAlg[1].intern(); - String className = value; - ServiceKey key = new ServiceKey(type, stdAlg, true); - Service s = legacyMap.get(key); - if (s == null) { - s = new Service(this, type, stdAlg); - legacyMap.put(key, s); - } - s.className = className; - - if (type.equals("SecureRandom")) { - updateSecureRandomEntries(true, s.algorithm); + ServiceKey stdKey = new ServiceKey(type, stdAlg, true); + Service stdService = legacyMap.get(stdKey); + switch (opType) { + case ADD: + Objects.requireNonNull(value, + "className can't be null"); + if (stdService == null) { + stdService = new Service(this, type, stdAlg); + legacyMap.put(stdKey, stdService); + } + stdService.className = value; + break; + case REMOVE: + // only remove if value also matches when non-null + if (stdService != null) { + if (value == null) { + legacyMap.remove(stdKey); + } else if (stdService.className.equals(value)) { + legacyMap.remove(stdKey, stdService); + } + // remove all corresponding alias mappings + for (String alias : stdService.getAliases()) { + legacyMap.remove(new ServiceKey(type, alias, + true), stdService); + } + } + break; + default: + throw new AssertionError(); } + checkAndUpdateSecureRandom(type, stdAlg, + (opType != OPType.REMOVE)); } else { // attribute // e.g. put("MessageDigest.SHA-1 ImplementedIn", "Software"); - String attributeValue = value; String type = getEngineName(typeAndAlg[0]); - String attributeString = typeAndAlg[1]; - String stdAlg = attributeString.substring(0, i).intern(); - String attributeName = attributeString.substring(i + 1); + String attrString = typeAndAlg[1]; + String stdAlg = attrString.substring(0, i).intern(); + String attrName = attrString.substring(i + 1); // kill additional spaces - while (attributeName.startsWith(" ")) { - attributeName = attributeName.substring(1); + while (attrName.startsWith(" ")) { + attrName = attrName.substring(1); } - attributeName = attributeName.intern(); - ServiceKey key = new ServiceKey(type, stdAlg, true); - Service s = legacyMap.get(key); - if (s == null) { - s = new Service(this, type, stdAlg); - legacyMap.put(key, s); + attrName = attrName.intern(); + ServiceKey stdKey = new ServiceKey(type, stdAlg, true); + Service stdService = legacyMap.get(stdKey); + switch (opType) { + case ADD: + Objects.requireNonNull(value, + "attribute value should not be null"); + + if (stdService == null) { + stdService = new Service(this, type, stdAlg); + legacyMap.put(stdKey, stdService); + } + stdService.addAttribute(attrName, value); + break; + case REMOVE: + if (stdService != null) { + stdService.removeAttribute(attrName, value); + } + break; + default: + throw new AssertionError(); } - s.addAttribute(attributeName, attributeValue); } } } @@ -1229,23 +1276,18 @@ */ public Service getService(String type, String algorithm) { checkInitialized(); - // avoid allocating a new ServiceKey object if possible ServiceKey key = previousKey; if (key.matches(type, algorithm) == false) { key = new ServiceKey(type, algorithm, false); previousKey = key; } - Service s = null; - if (!serviceMap.isEmpty()) { - s = serviceMap.get(key); - } + + Service s = serviceMap.get(key); if (s == null) { - synchronized (this) { - ensureLegacyParsed(); - if (legacyMap != null && !legacyMap.isEmpty()) { - s = legacyMap.get(key); - } + s = legacyMap.get(key); + if (s != null && !s.isValid()) { + legacyMap.remove(key, s); } } @@ -1278,22 +1320,25 @@ * * @since 1.5 */ - public synchronized Set getServices() { + public Set getServices() { checkInitialized(); - if (legacyChanged || servicesChanged) { - serviceSet = null; - } - if (serviceSet == null) { - ensureLegacyParsed(); + if (serviceSet == null || legacyChanged || servicesChanged) { Set set = new LinkedHashSet<>(); if (!serviceMap.isEmpty()) { set.addAll(serviceMap.values()); } - if (legacyMap != null && !legacyMap.isEmpty()) { - set.addAll(legacyMap.values()); + if (!legacyMap.isEmpty()) { + legacyMap.entrySet().forEach(entry -> { + if (!entry.getValue().isValid()) { + legacyMap.remove(entry.getKey(), entry.getValue()); + } else { + set.add(entry.getValue()); + } + }); } serviceSet = Collections.unmodifiableSet(set); servicesChanged = false; + legacyChanged = false; } return serviceSet; } @@ -1350,44 +1395,36 @@ servicesChanged = true; synchronized (this) { putPropertyStrings(s); - if (type.equals("SecureRandom")) { - updateSecureRandomEntries(true, s.algorithm); - } + checkAndUpdateSecureRandom(type, algorithm, true); } } - // keep tracks of the registered secure random algos and store them in order - private void updateSecureRandomEntries(boolean doAdd, String s) { - Objects.requireNonNull(s); - if (doAdd) { - if (prngAlgos == null) { - prngAlgos = new LinkedHashSet(); + private void checkAndUpdateSecureRandom(String type, String algo, + boolean doAdd) { + if (type.equalsIgnoreCase("SecureRandom")) { + if (doAdd) { + prngAlgos.add(algo); + } else { + prngAlgos.remove(algo); + } + if (debug != null) { + debug.println((doAdd? "Add":"Remove") + + " SecureRandom algo " + algo); } - prngAlgos.add(s); - } else { - prngAlgos.remove(s); - } - - if (debug != null) { - debug.println((doAdd? "Add":"Remove") + " SecureRandom algo " + s); } } // used by new SecureRandom() to find out the default SecureRandom // service for this provider - synchronized Service getDefaultSecureRandomService() { + Service getDefaultSecureRandomService() { checkInitialized(); - if (legacyChanged) { - prngAlgos = null; - ensureLegacyParsed(); - } - - if (prngAlgos != null && !prngAlgos.isEmpty()) { + if (!prngAlgos.isEmpty()) { + String algo = prngAlgos.iterator().next(); // IMPORTANT: use the Service obj returned by getService(...) call // as providers may override putService(...)/getService(...) and // return their own Service objects - return getService("SecureRandom", prngAlgos.iterator().next()); + return getService("SecureRandom", algo); } return null; @@ -1484,12 +1521,9 @@ for (String alias : s.getAliases()) { serviceMap.remove(new ServiceKey(type, alias, false)); } - synchronized (this) { - removePropertyStrings(s); - if (type.equals("SecureRandom")) { - updateSecureRandomEntries(false, s.algorithm); - } - } + + removePropertyStrings(s); + checkAndUpdateSecureRandom(type, algorithm, false); } // Wrapped String that behaves in a case insensitive way for equals/hashCode @@ -1523,29 +1557,20 @@ private static class EngineDescription { final String name; final boolean supportsParameter; - final String constructorParameterClassName; - private volatile Class constructorParameterClass; + final Class constructorParameterClass; - EngineDescription(String name, boolean sp, String paramName) { + EngineDescription(String name, boolean sp, Class constructorParameterClass) { this.name = name; this.supportsParameter = sp; - this.constructorParameterClassName = paramName; - } - Class getConstructorParameterClass() throws ClassNotFoundException { - Class clazz = constructorParameterClass; - if (clazz == null) { - clazz = Class.forName(constructorParameterClassName); - constructorParameterClass = clazz; - } - return clazz; + this.constructorParameterClass = constructorParameterClass; } } // built in knowledge of the engine types shipped as part of the JDK private static final Map knownEngines; - private static void addEngine(String name, boolean sp, String paramName) { - EngineDescription ed = new EngineDescription(name, sp, paramName); + private static void addEngine(String name, boolean sp, Class constructorParameterClass) { + EngineDescription ed = new EngineDescription(name, sp, constructorParameterClass); // also index by canonical name to avoid toLowerCase() for some lookups knownEngines.put(name.toLowerCase(ENGLISH), ed); knownEngines.put(name, ed); @@ -1561,13 +1586,13 @@ addEngine("KeyStore", false, null); addEngine("MessageDigest", false, null); addEngine("SecureRandom", false, - "java.security.SecureRandomParameters"); + SecureRandomParameters.class); addEngine("Signature", true, null); addEngine("CertificateFactory", false, null); addEngine("CertPathBuilder", false, null); addEngine("CertPathValidator", false, null); addEngine("CertStore", false, - "java.security.cert.CertStoreParameters"); + CertStoreParameters.class); // JCE addEngine("Cipher", true, null); addEngine("ExemptionMechanism", false, null); @@ -1575,6 +1600,7 @@ addEngine("KeyAgreement", true, null); addEngine("KeyGenerator", false, null); addEngine("SecretKeyFactory", false, null); + addEngine("KEM", true, null); // JSSE addEngine("KeyManagerFactory", false, null); addEngine("SSLContext", false, null); @@ -1585,18 +1611,20 @@ addEngine("SaslClientFactory", false, null); addEngine("SaslServerFactory", false, null); // POLICY + @SuppressWarnings("removal") + Class policyParams = Policy.Parameters.class; addEngine("Policy", false, - "java.security.Policy$Parameters"); + policyParams); // CONFIGURATION addEngine("Configuration", false, - "javax.security.auth.login.Configuration$Parameters"); + Configuration.Parameters.class); // XML DSig addEngine("XMLSignatureFactory", false, null); addEngine("KeyInfoFactory", false, null); addEngine("TransformService", false, null); // Smart Card I/O addEngine("TerminalFactory", false, - "java.lang.Object"); + Object.class); } // get the "standard" (mixed-case) engine name for arbitary case engine name @@ -1697,6 +1725,13 @@ aliases.add(alias); } + private void removeAlias(String alias) { + if (aliases.isEmpty()) { + return; + } + aliases.remove(alias); + } + void addAttribute(String type, String value) { if (attributes.isEmpty()) { attributes = new HashMap<>(8); @@ -1704,6 +1739,17 @@ attributes.put(new UString(type), value); } + void removeAttribute(String type, String value) { + if (attributes.isEmpty()) { + return; + } + if (value == null) { + attributes.remove(new UString(type)); + } else { + attributes.remove(new UString(type), value); + } + } + /** * Construct a new service. * @@ -1850,8 +1896,7 @@ ctrParamClz = constructorParameter == null? null : constructorParameter.getClass(); } else { - ctrParamClz = cap.constructorParameterClassName == null? - null : Class.forName(cap.constructorParameterClassName); + ctrParamClz = cap.constructorParameterClass; if (constructorParameter != null) { if (ctrParamClz == null) { throw new InvalidParameterException @@ -1862,7 +1907,7 @@ if (ctrParamClz.isAssignableFrom(argClass) == false) { throw new InvalidParameterException ("constructorParameter must be instanceof " - + cap.constructorParameterClassName.replace('$', '.') + + cap.constructorParameterClass.getName().replace('$', '.') + " for engine type " + type); } } diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/java/text/MessageFormat.java openjdk-17-17.0.13+11/src/java.base/share/classes/java/text/MessageFormat.java --- openjdk-17-17.0.12+7/src/java.base/share/classes/java/text/MessageFormat.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/java/text/MessageFormat.java 2024-10-10 14:01:59.000000000 +0000 @@ -41,6 +41,7 @@ import java.io.InvalidObjectException; import java.io.IOException; import java.io.ObjectInputStream; +import java.io.ObjectStreamException; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Arrays; @@ -983,6 +984,8 @@ maximumArgumentNumber = argumentNumbers[i]; } } + + // Constructors/applyPattern ensure that resultArray.length < MAX_ARGUMENT_INDEX Object[] resultArray = new Object[maximumArgumentNumber + 1]; int patternOffset = 0; @@ -1235,6 +1238,9 @@ * @serial */ private int[] argumentNumbers = new int[INITIAL_FORMATS]; + // Implementation limit for ArgumentIndex pattern element. Valid indices must + // be less than this value + private static final int MAX_ARGUMENT_INDEX = 10000; /** * One less than the number of entries in {@code offsets}. Can also be thought of @@ -1459,6 +1465,11 @@ + argumentNumber); } + if (argumentNumber >= MAX_ARGUMENT_INDEX) { + throw new IllegalArgumentException( + argumentNumber + " exceeds the ArgumentIndex implementation limit"); + } + // resize format information arrays if necessary if (offsetNumber >= formats.length) { int newLength = formats.length * 2; @@ -1606,24 +1617,53 @@ */ @java.io.Serial private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - in.defaultReadObject(); - boolean isValid = maxOffset >= -1 - && formats.length > maxOffset - && offsets.length > maxOffset - && argumentNumbers.length > maxOffset; + ObjectInputStream.GetField fields = in.readFields(); + if (fields.defaulted("argumentNumbers") || fields.defaulted("offsets") + || fields.defaulted("formats") || fields.defaulted("locale") + || fields.defaulted("pattern") || fields.defaulted("maxOffset")){ + throw new InvalidObjectException("Stream has missing data"); + } + + locale = (Locale) fields.get("locale", null); + String patt = (String) fields.get("pattern", null); + int maxOff = fields.get("maxOffset", -2); + int[] argNums = ((int[]) fields.get("argumentNumbers", null)).clone(); + int[] offs = ((int[]) fields.get("offsets", null)).clone(); + Format[] fmts = ((Format[]) fields.get("formats", null)).clone(); + + // Check arrays/maxOffset have correct value/length + boolean isValid = maxOff >= -1 && argNums.length > maxOff + && offs.length > maxOff && fmts.length > maxOff; + + // Check the correctness of arguments and offsets if (isValid) { - int lastOffset = pattern.length() + 1; - for (int i = maxOffset; i >= 0; --i) { - if ((offsets[i] < 0) || (offsets[i] > lastOffset)) { + int lastOffset = patt.length() + 1; + for (int i = maxOff; i >= 0; --i) { + if (argNums[i] < 0 || argNums[i] >= MAX_ARGUMENT_INDEX + || offs[i] < 0 || offs[i] > lastOffset) { isValid = false; break; } else { - lastOffset = offsets[i]; + lastOffset = offs[i]; } } } + if (!isValid) { - throw new InvalidObjectException("Could not reconstruct MessageFormat from corrupt stream."); + throw new InvalidObjectException("Stream has invalid data"); } + maxOffset = maxOff; + pattern = patt; + offsets = offs; + formats = fmts; + argumentNumbers = argNums; + } + + /** + * Serialization without data not supported for this class. + */ + @java.io.Serial + private void readObjectNoData() throws ObjectStreamException { + throw new InvalidObjectException("Deserialized MessageFormat objects need data"); } } diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java openjdk-17-17.0.13+11/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java --- openjdk-17-17.0.12+7/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java 2024-10-10 14:01:59.000000000 +0000 @@ -1080,13 +1080,18 @@ private void doSignal(ConditionNode first, boolean all) { while (first != null) { ConditionNode next = first.nextWaiter; + if ((firstWaiter = next) == null) lastWaiter = null; + else + first.nextWaiter = null; // GC assistance + if ((first.getAndUnsetStatus(COND) & COND) != 0) { enqueue(first); if (!all) break; } + first = next; } } diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java openjdk-17-17.0.13+11/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java --- openjdk-17-17.0.12+7/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java 2024-10-10 14:01:59.000000000 +0000 @@ -1448,13 +1448,18 @@ private void doSignal(ConditionNode first, boolean all) { while (first != null) { ConditionNode next = first.nextWaiter; + if ((firstWaiter = next) == null) lastWaiter = null; + else + first.nextWaiter = null; // GC assistance + if ((first.getAndUnsetStatus(COND) & COND) != 0) { enqueue(first); if (!all) break; } + first = next; } } diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/java/util/regex/Grapheme.java openjdk-17-17.0.13+11/src/java.base/share/classes/java/util/regex/Grapheme.java --- openjdk-17-17.0.12+7/src/java.base/share/classes/java/util/regex/Grapheme.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/java/util/regex/Grapheme.java 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -151,10 +151,10 @@ // #tr29: SpacingMark exceptions: The following (which have // General_Category = Spacing_Mark and would otherwise be included) // are specifically excluded - private static boolean isExcludedSpacingMark(int cp) { + static boolean isExcludedSpacingMark(int cp) { return cp == 0x102B || cp == 0x102C || cp == 0x1038 || cp >= 0x1062 && cp <= 0x1064 || - cp >= 0x1062 && cp <= 0x106D || + cp >= 0x1067 && cp <= 0x106D || cp == 0x1083 || cp >= 0x1087 && cp <= 0x108C || cp == 0x108F || @@ -164,7 +164,7 @@ } @SuppressWarnings("fallthrough") - private static int getType(int cp) { + static int getType(int cp) { if (cp < 0x007F) { // ASCII if (cp < 32) { // Control characters if (cp == 0x000D) diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/javax/crypto/DecapsulateException.java openjdk-17-17.0.13+11/src/java.base/share/classes/javax/crypto/DecapsulateException.java --- openjdk-17-17.0.12+7/src/java.base/share/classes/javax/crypto/DecapsulateException.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/javax/crypto/DecapsulateException.java 2024-10-10 14:01:59.000000000 +0000 @@ -0,0 +1,66 @@ +/* + * 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 + * 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 javax.crypto; + +import java.security.GeneralSecurityException; + +/** + * An exception that is thrown by the + * {@link javax.crypto.KEM.Decapsulator#decapsulate} method to denote an + * error during decapsulation. + * + * @apiNote This class is defined in Java SE 17 Maintenance Release 1. + * @since 17 + */ +public class DecapsulateException extends GeneralSecurityException { + + @java.io.Serial + private static final long serialVersionUID = 21L; + + /** + * Creates a {@code DecapsulateException} with the specified + * detail message. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + */ + public DecapsulateException(String message) { + super(message); + } + + /** + * Creates a {@code DecapsulateException} with the specified + * detail message and cause. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + */ + public DecapsulateException(String message, Throwable cause) { + super(message, cause); + } +} diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/javax/crypto/KEM.java openjdk-17-17.0.13+11/src/java.base/share/classes/javax/crypto/KEM.java --- openjdk-17-17.0.12+7/src/java.base/share/classes/javax/crypto/KEM.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/javax/crypto/KEM.java 2024-10-10 14:01:59.000000000 +0000 @@ -0,0 +1,751 @@ +/* + * 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 + * 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 javax.crypto; + +import sun.security.jca.GetInstance; + +import java.security.*; +import java.security.InvalidAlgorithmParameterException; +import java.security.spec.AlgorithmParameterSpec; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * This class provides the functionality of a Key Encapsulation Mechanism (KEM). + * A KEM can be used to secure symmetric keys using asymmetric or public key + * cryptography between two parties. The sender calls the encapsulate method + * to generate a secret key and a key encapsulation message, and the receiver + * calls the decapsulate method to recover the same secret key from + * the key encapsulation message. + *

    + * The {@code getInstance} method creates a new {@code KEM} object that + * implements the specified algorithm. + *

    + * A {@code KEM} object is immutable. It is safe to call multiple + * {@code newEncapsulator} and {@code newDecapsulator} methods on the + * same {@code KEM} object at the same time. + *

    + * If a provider is not specified in the {@code getInstance} method when + * instantiating a {@code KEM} object, the {@code newEncapsulator} and + * {@code newDecapsulator} methods may return encapsulators or decapsulators + * from different providers. The provider selected is based on the parameters + * passed to the {@code newEncapsulator} or {@code newDecapsulator} methods: + * the private or public key and the optional {@code AlgorithmParameterSpec}. + * The {@link Encapsulator#providerName} and {@link Decapsulator#providerName} + * methods return the name of the selected provider. + *

    + * {@code Encapsulator} and {@code Decapsulator} objects are also immutable. + * It is safe to invoke multiple {@code encapsulate} and {@code decapsulate} + * methods on the same {@code Encapsulator} or {@code Decapsulator} object + * at the same time. Each invocation of {@code encapsulate} will generate a + * new shared secret and key encapsulation message. + *

    + * + * Example: + *

    {@code
    + *    // Receiver side
    + *    var kpg = KeyPairGenerator.getInstance("X25519");
    + *    var kp = kpg.generateKeyPair();
    + *
    + *    // Sender side
    + *    var kem1 = KEM.getInstance("DHKEM");
    + *    var sender = kem1.newEncapsulator(kp.getPublic());
    + *    var encapsulated = sender.encapsulate();
    + *    var k1 = encapsulated.key();
    + *
    + *    // Receiver side
    + *    var kem2 = KEM.getInstance("DHKEM");
    + *    var receiver = kem2.newDecapsulator(kp.getPrivate());
    + *    var k2 = receiver.decapsulate(encapsulated.encapsulation());
    + *
    + *    assert Arrays.equals(k1.getEncoded(), k2.getEncoded());
    + * }
    + * + * @apiNote This class is defined in Java SE 17 Maintenance Release 1. + * @since 17 + */ +public final class KEM { + + /** + * This class specifies the return value of the encapsulate method of + * a Key Encapsulation Mechanism (KEM), which includes the shared secret + * (as a {@code SecretKey}), the key encapsulation message, + * and optional parameters. + *

    + * Note: the key encapsulation message can be also referred to as ciphertext. + * + * @see #newEncapsulator(PublicKey, AlgorithmParameterSpec, SecureRandom) + * @see Encapsulator#encapsulate(int, int, String) + * + * @apiNote This class is defined in Java SE 17 Maintenance Release 1. + * @since 17 + */ + public static final class Encapsulated { + private final SecretKey key; + private final byte[] encapsulation; + private final byte[] params; + + /** + * Constructs an {@code Encapsulated} object. + * + * @param key the shared secret as a key, must not be {@code null}. + * @param encapsulation the key encapsulation message, must not + * be {@code null}. The contents of the array are copied + * to protect against subsequent modification. + * @param params optional parameters, can be {@code null}. + * The contents of the array are copied to protect + * against subsequent modification. + * @throws NullPointerException if {@code key} or {@code encapsulation} + * is {@code null} + */ + public Encapsulated(SecretKey key, byte[] encapsulation, byte[] params) { + Objects.requireNonNull(key); + Objects.requireNonNull(encapsulation); + this.key = key; + this.encapsulation = encapsulation.clone(); + this.params = params == null ? null : params.clone(); + } + + /** + * Returns the {@code SecretKey}. + * + * @return the secret key + */ + public SecretKey key() { + return key; + } + + /** + * Returns the key encapsulation message. + * + * @return the key encapsulation message. A new copy of the byte array + * is returned. + */ + public byte[] encapsulation() { + return encapsulation.clone(); + } + + /** + * Returns the optional parameters in a byte array. + * + * @return the optional parameters in a byte array or {@code null} + * if not specified. A new copy of the byte array is returned. + */ + public byte[] params() { + return params == null ? null : params.clone(); + } + } + + /** + * An encapsulator, generated by {@link #newEncapsulator} on the KEM + * sender side. + *

    + * This class represents the key encapsulation function of a KEM. + * Each invocation of the {@code encapsulate} method generates a + * new secret key and key encapsulation message that is returned + * in an {@link Encapsulated} object. + * + * @apiNote This class is defined in Java SE 17 Maintenance Release 1. + * @since 17 + */ + public static final class Encapsulator { + + private final KEMSpi.EncapsulatorSpi e; + private final Provider p; + + private Encapsulator(KEMSpi.EncapsulatorSpi e, Provider p) { + assert e != null; + assert p != null; + this.e = e; + this.p = p; + } + + /** + * Returns the name of the provider. + * + * @return the name of the provider + */ + public String providerName() { + return p.getName(); + } + + /** + * The key encapsulation function. + *

    + * This method is equivalent to + * {@code encapsulate(0, secretSize(), "Generic")}. This combination + * of arguments must be supported by every implementation. + *

    + * The generated secret key is usually passed to a key derivation + * function (KDF) as the input keying material. + * + * @return a {@link Encapsulated} object containing the shared + * secret, key encapsulation message, and optional parameters. + * The shared secret is a {@code SecretKey} containing all of + * the bytes of the secret, and an algorithm name of "Generic". + */ + public Encapsulated encapsulate() { + return encapsulate(0, secretSize(), "Generic"); + } + + /** + * The key encapsulation function. + *

    + * Each invocation of this method generates a new secret key and key + * encapsulation message that is returned in an {@link Encapsulated} object. + *

    + * An implementation may choose to not support arbitrary combinations + * of {@code from}, {@code to}, and {@code algorithm}. + * + * @param from the initial index of the shared secret byte array + * to be returned, inclusive + * @param to the final index of the shared secret byte array + * to be returned, exclusive + * @param algorithm the algorithm name for the secret key that is returned + * @return a {@link Encapsulated} object containing a portion of + * the shared secret, key encapsulation message, and optional + * parameters. The portion of the shared secret is a + * {@code SecretKey} containing the bytes of the secret + * ranging from {@code from} to {@code to}, exclusive, + * and an algorithm name as specified. For example, + * {@code encapsulate(0, 16, "AES")} uses the first 16 bytes + * of the shared secret as a 128-bit AES key. + * @throws IndexOutOfBoundsException if {@code from < 0}, + * {@code from > to}, or {@code to > secretSize()} + * @throws NullPointerException if {@code algorithm} is {@code null} + * @throws UnsupportedOperationException if the combination of + * {@code from}, {@code to}, and {@code algorithm} + * is not supported by the encapsulator + */ + public Encapsulated encapsulate(int from, int to, String algorithm) { + return e.engineEncapsulate(from, to, algorithm); + } + + /** + * Returns the size of the shared secret. + *

    + * This method can be called to find out the length of the shared secret + * before {@code encapsulate} is called or if the obtained + * {@code SecretKey} is not extractable. + * + * @return the size of the shared secret + */ + public int secretSize() { + int result = e.engineSecretSize(); + assert result >= 0 && result != Integer.MAX_VALUE + : "invalid engineSecretSize result"; + return result; + } + + /** + * Returns the size of the key encapsulation message. + *

    + * This method can be called to find out the length of the encapsulation + * message before {@code encapsulate} is called. + * + * @return the size of the key encapsulation message + */ + public int encapsulationSize() { + int result = e.engineEncapsulationSize(); + assert result >= 0 && result != Integer.MAX_VALUE + : "invalid engineEncapsulationSize result"; + return result; + } + } + + /** + * A decapsulator, generated by {@link #newDecapsulator} on the KEM + * receiver side. + *

    + * This class represents the key decapsulation function of a KEM. + * An invocation of the {@code decapsulate} method recovers the + * secret key from the key encapsulation message. + * + * @apiNote This class is defined in Java SE 17 Maintenance Release 1. + * @since 17 + */ + public static final class Decapsulator { + private final KEMSpi.DecapsulatorSpi d; + private final Provider p; + + private Decapsulator(KEMSpi.DecapsulatorSpi d, Provider p) { + assert d != null; + assert p != null; + this.d = d; + this.p = p; + } + + /** + * Returns the name of the provider. + * + * @return the name of the provider + */ + public String providerName() { + return p.getName(); + } + + /** + * The key decapsulation function. + *

    + * This method is equivalent to + * {@code decapsulate(encapsulation, 0, secretSize(), "Generic")}. This + * combination of arguments must be supported by every implementation. + *

    + * The generated secret key is usually passed to a key derivation + * function (KDF) as the input keying material. + * + * @param encapsulation the key encapsulation message from the sender. + * The size must be equal to the value returned by + * {@link #encapsulationSize()}, or a {@code DecapsulateException} + * will be thrown. + * @return the shared secret as a {@code SecretKey} with + * an algorithm name of "Generic" + * @throws DecapsulateException if an error occurs during the + * decapsulation process + * @throws NullPointerException if {@code encapsulation} is {@code null} + */ + public SecretKey decapsulate(byte[] encapsulation) throws DecapsulateException { + return decapsulate(encapsulation, 0, secretSize(), "Generic"); + } + + /** + * The key decapsulation function. + *

    + * An invocation of this method recovers the secret key from the key + * encapsulation message. + *

    + * An implementation may choose to not support arbitrary combinations + * of {@code from}, {@code to}, and {@code algorithm}. + * + * @param encapsulation the key encapsulation message from the sender. + * The size must be equal to the value returned by + * {@link #encapsulationSize()}, or a {@code DecapsulateException} + * will be thrown. + * @param from the initial index of the shared secret byte array + * to be returned, inclusive + * @param to the final index of the shared secret byte array + * to be returned, exclusive + * @param algorithm the algorithm name for the secret key that is returned + * @return a portion of the shared secret as a {@code SecretKey} + * containing the bytes of the secret ranging from {@code from} + * to {@code to}, exclusive, and an algorithm name as specified. + * For example, {@code decapsulate(encapsulation, secretSize() + * - 16, secretSize(), "AES")} uses the last 16 bytes + * of the shared secret as a 128-bit AES key. + * @throws DecapsulateException if an error occurs during the + * decapsulation process + * @throws IndexOutOfBoundsException if {@code from < 0}, + * {@code from > to}, or {@code to > secretSize()} + * @throws NullPointerException if {@code encapsulation} or + * {@code algorithm} is {@code null} + * @throws UnsupportedOperationException if the combination of + * {@code from}, {@code to}, and {@code algorithm} + * is not supported by the decapsulator + */ + public SecretKey decapsulate(byte[] encapsulation, + int from, int to, String algorithm) + throws DecapsulateException { + return d.engineDecapsulate( + encapsulation, + from, to, + algorithm); + } + + /** + * Returns the size of the shared secret. + *

    + * This method can be called to find out the length of the shared secret + * before {@code decapsulate} is called or if the obtained + * {@code SecretKey} is not extractable. + * + * @return the size of the shared secret + */ + public int secretSize() { + int result = d.engineSecretSize(); + assert result >= 0 && result != Integer.MAX_VALUE + : "invalid engineSecretSize result"; + return result; + } + + /** + * Returns the size of the key encapsulation message. + *

    + * This method can be used to extract the encapsulation message + * from a longer byte array if no length information is provided + * by a higher level protocol. + * + * @return the size of the key encapsulation message + */ + public int encapsulationSize() { + int result = d.engineEncapsulationSize(); + assert result >= 0 && result != Integer.MAX_VALUE + : "invalid engineEncapsulationSize result"; + return result; + } + } + + private static final class DelayedKEM { + + private final Provider.Service[] list; // non empty array + + private DelayedKEM(Provider.Service[] list) { + this.list = list; + } + + private Encapsulator newEncapsulator(PublicKey publicKey, + AlgorithmParameterSpec spec, SecureRandom secureRandom) + throws InvalidAlgorithmParameterException, InvalidKeyException { + if (publicKey == null) { + throw new InvalidKeyException("input key is null"); + } + RuntimeException re = null; + InvalidAlgorithmParameterException iape = null; + InvalidKeyException ike = null; + NoSuchAlgorithmException nsae = null; + for (Provider.Service service : list) { + if (!service.supportsParameter(publicKey)) { + continue; + } + try { + KEMSpi spi = (KEMSpi) service.newInstance(null); + return new Encapsulator( + spi.engineNewEncapsulator(publicKey, spec, secureRandom), + service.getProvider()); + } catch (NoSuchAlgorithmException e) { + nsae = merge(nsae, e); + } catch (InvalidAlgorithmParameterException e) { + iape = merge(iape, e); + } catch (InvalidKeyException e) { + ike = merge(ike, e); + } catch (RuntimeException e) { + re = merge(re, e); + } + } + if (iape != null) throw iape; + if (ike != null) throw ike; + if (nsae != null) { + throw new InvalidKeyException("No installed provider found", nsae); + } + throw new InvalidKeyException("No installed provider supports this key: " + + publicKey.getClass().getName(), re); + } + + private static T merge(T e1, T e2) { + if (e1 == null) { + return e2; + } else { + e1.addSuppressed(e2); + return e1; + } + } + + private Decapsulator newDecapsulator(PrivateKey privateKey, AlgorithmParameterSpec spec) + throws InvalidAlgorithmParameterException, InvalidKeyException { + if (privateKey == null) { + throw new InvalidKeyException("input key is null"); + } + RuntimeException re = null; + InvalidAlgorithmParameterException iape = null; + InvalidKeyException ike = null; + NoSuchAlgorithmException nsae = null; + for (Provider.Service service : list) { + if (!service.supportsParameter(privateKey)) { + continue; + } + try { + KEMSpi spi = (KEMSpi) service.newInstance(null); + return new Decapsulator( + spi.engineNewDecapsulator(privateKey, spec), + service.getProvider()); + } catch (NoSuchAlgorithmException e) { + nsae = merge(nsae, e); + } catch (InvalidAlgorithmParameterException e) { + iape = merge(iape, e); + } catch (InvalidKeyException e) { + ike = merge(ike, e); + } catch (RuntimeException e) { + re = merge(re, e); + } + } + if (iape != null) throw iape; + if (ike != null) throw ike; + if (nsae != null) { + throw new InvalidKeyException("No installed provider found", nsae); + } + throw new InvalidKeyException("No installed provider supports this key: " + + privateKey.getClass().getName(), re); + } + } + + // If delayed provider selection is needed + private final DelayedKEM delayed; + + // otherwise + private final KEMSpi spi; + private final Provider provider; + + private final String algorithm; + + private KEM(String algorithm, KEMSpi spi, Provider provider) { + assert spi != null; + assert provider != null; + this.delayed = null; + this.spi = spi; + this.provider = provider; + this.algorithm = algorithm; + } + + private KEM(String algorithm, DelayedKEM delayed) { + assert delayed != null; + this.delayed = delayed; + this.spi = null; + this.provider = null; + this.algorithm = algorithm; + } + + /** + * Returns a {@code KEM} object that implements the specified algorithm. + * + * @param algorithm the name of the KEM algorithm. + * See the {@code KEM} section in the + * Java Security Standard Algorithm Names Specification + * for information about standard KEM algorithm names. + * @return the new {@code KEM} object + * @throws NoSuchAlgorithmException if no {@code Provider} supports a + * {@code KEM} implementation for the specified algorithm + * @throws NullPointerException if {@code algorithm} is {@code null} + */ + public static KEM getInstance(String algorithm) + throws NoSuchAlgorithmException { + List list = GetInstance.getServices( + "KEM", + Objects.requireNonNull(algorithm, "null algorithm name")); + List allowed = new ArrayList<>(); + for (Provider.Service s : list) { + if (!JceSecurity.canUseProvider(s.getProvider())) { + continue; + } + allowed.add(s); + } + if (allowed.isEmpty()) { + throw new NoSuchAlgorithmException + (algorithm + " KEM not available"); + } + + return new KEM(algorithm, new DelayedKEM(allowed.toArray(new Provider.Service[0]))); + } + + /** + * Returns a {@code KEM} object that implements the specified algorithm + * from the specified security provider. + * + * @param algorithm the name of the KEM algorithm. + * See the {@code KEM} section in the + * Java Security Standard Algorithm Names Specification + * for information about standard KEM algorithm names. + * @param provider the provider. If {@code null}, this method is equivalent + * to {@link #getInstance(String)}. + * @return the new {@code KEM} object + * @throws NoSuchAlgorithmException if a {@code provider} is specified and + * it does not support the specified KEM algorithm, + * or if {@code provider} is {@code null} and there is no provider + * that supports a KEM implementation of the specified algorithm + * @throws NullPointerException if {@code algorithm} is {@code null} + */ + public static KEM getInstance(String algorithm, Provider provider) + throws NoSuchAlgorithmException { + if (provider == null) { + return getInstance(algorithm); + } + GetInstance.Instance instance = JceSecurity.getInstance( + "KEM", + KEMSpi.class, + Objects.requireNonNull(algorithm, "null algorithm name"), + provider); + return new KEM(algorithm, (KEMSpi) instance.impl, instance.provider); + } + + /** + * Returns a {@code KEM} object that implements the specified algorithm + * from the specified security provider. + * + * @param algorithm the name of the KEM algorithm. + * See the {@code KEM} section in the + * Java Security Standard Algorithm Names Specification + * for information about standard KEM algorithm names. + * @param provider the provider. If {@code null}, this method is equivalent + * to {@link #getInstance(String)}. + * @return the new {@code KEM} object + * @throws NoSuchAlgorithmException if a {@code provider} is specified and + * it does not support the specified KEM algorithm, + * or if {@code provider} is {@code null} and there is no provider + * that supports a KEM implementation of the specified algorithm + * @throws NoSuchProviderException if the specified provider is not + * registered in the security provider list + * @throws NullPointerException if {@code algorithm} is {@code null} + */ + public static KEM getInstance(String algorithm, String provider) + throws NoSuchAlgorithmException, NoSuchProviderException { + if (provider == null) { + return getInstance(algorithm); + } + GetInstance.Instance instance = JceSecurity.getInstance( + "KEM", + KEMSpi.class, + Objects.requireNonNull(algorithm, "null algorithm name"), + provider); + return new KEM(algorithm, (KEMSpi) instance.impl, instance.provider); + } + + /** + * Creates a KEM encapsulator on the KEM sender side. + *

    + * This method is equivalent to {@code newEncapsulator(publicKey, null, null)}. + * + * @param publicKey the receiver's public key, must not be {@code null} + * @return the encapsulator for this key + * @throws InvalidKeyException if {@code publicKey} is {@code null} or invalid + * @throws UnsupportedOperationException if this method is not supported + * because an {@code AlgorithmParameterSpec} must be provided + */ + public Encapsulator newEncapsulator(PublicKey publicKey) + throws InvalidKeyException { + try { + return newEncapsulator(publicKey, null, null); + } catch (InvalidAlgorithmParameterException e) { + throw new UnsupportedOperationException( + "AlgorithmParameterSpec must be provided", e); + } + } + + /** + * Creates a KEM encapsulator on the KEM sender side. + *

    + * This method is equivalent to {@code newEncapsulator(publicKey, null, secureRandom)}. + * + * @param publicKey the receiver's public key, must not be {@code null} + * @param secureRandom the source of randomness for encapsulation. + * If {@code} null, a default one from the + * implementation will be used. + * @return the encapsulator for this key + * @throws InvalidKeyException if {@code publicKey} is {@code null} or invalid + * @throws UnsupportedOperationException if this method is not supported + * because an {@code AlgorithmParameterSpec} must be provided + */ + public Encapsulator newEncapsulator(PublicKey publicKey, SecureRandom secureRandom) + throws InvalidKeyException { + try { + return newEncapsulator(publicKey, null, secureRandom); + } catch (InvalidAlgorithmParameterException e) { + throw new UnsupportedOperationException( + "AlgorithmParameterSpec must be provided", e); + } + } + + /** + * Creates a KEM encapsulator on the KEM sender side. + *

    + * An algorithm can define an {@code AlgorithmParameterSpec} child class to + * provide extra information in this method. This is especially useful if + * the same key can be used to derive shared secrets in different ways. + * If any extra information inside this object needs to be transmitted along + * with the key encapsulation message so that the receiver is able to create + * a matching decapsulator, it will be included as a byte array in the + * {@link Encapsulated#params} field inside the encapsulation output. + * In this case, the security provider should provide an + * {@code AlgorithmParameters} implementation using the same algorithm name + * as the KEM. The receiver can initiate such an {@code AlgorithmParameters} + * instance with the {@code params} byte array received and recover + * an {@code AlgorithmParameterSpec} object to be used in its + * {@link #newDecapsulator(PrivateKey, AlgorithmParameterSpec)} call. + * + * @param publicKey the receiver's public key, must not be {@code null} + * @param spec the optional parameter, can be {@code null} + * @param secureRandom the source of randomness for encapsulation. + * If {@code} null, a default one from the + * implementation will be used. + * @return the encapsulator for this key + * @throws InvalidAlgorithmParameterException if {@code spec} is invalid + * or one is required but {@code spec} is {@code null} + * @throws InvalidKeyException if {@code publicKey} is {@code null} or invalid + */ + public Encapsulator newEncapsulator(PublicKey publicKey, + AlgorithmParameterSpec spec, SecureRandom secureRandom) + throws InvalidAlgorithmParameterException, InvalidKeyException { + return delayed != null + ? delayed.newEncapsulator(publicKey, spec, secureRandom) + : new Encapsulator(spi.engineNewEncapsulator(publicKey, spec, secureRandom), provider); + } + + /** + * Creates a KEM decapsulator on the KEM receiver side. + *

    + * This method is equivalent to {@code newDecapsulator(privateKey, null)}. + * + * @param privateKey the receiver's private key, must not be {@code null} + * @return the decapsulator for this key + * @throws InvalidKeyException if {@code privateKey} is {@code null} or invalid + * @throws UnsupportedOperationException if this method is not supported + * because an {@code AlgorithmParameterSpec} must be provided + */ + public Decapsulator newDecapsulator(PrivateKey privateKey) + throws InvalidKeyException { + try { + return newDecapsulator(privateKey, null); + } catch (InvalidAlgorithmParameterException e) { + throw new UnsupportedOperationException(e); + } + } + + /** + * Creates a KEM decapsulator on the KEM receiver side. + * + * @param privateKey the receiver's private key, must not be {@code null} + * @param spec the parameter, can be {@code null} + * @return the decapsulator for this key + * @throws InvalidAlgorithmParameterException if {@code spec} is invalid + * or one is required but {@code spec} is {@code null} + * @throws InvalidKeyException if {@code privateKey} is {@code null} or invalid + */ + public Decapsulator newDecapsulator(PrivateKey privateKey, AlgorithmParameterSpec spec) + throws InvalidAlgorithmParameterException, InvalidKeyException { + return delayed != null + ? delayed.newDecapsulator(privateKey, spec) + : new Decapsulator(spi.engineNewDecapsulator(privateKey, spec), provider); + } + + /** + * Returns the name of the algorithm for this {@code KEM} object. + * + * @return the name of the algorithm for this {@code KEM} object. + */ + public String getAlgorithm() { + return this.algorithm; + } +} diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/javax/crypto/KEMSpi.java openjdk-17-17.0.13+11/src/java.base/share/classes/javax/crypto/KEMSpi.java --- openjdk-17-17.0.12+7/src/java.base/share/classes/javax/crypto/KEMSpi.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/javax/crypto/KEMSpi.java 2024-10-10 14:01:59.000000000 +0000 @@ -0,0 +1,259 @@ +/* + * 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 + * 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 javax.crypto; + +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; + +/** + * This class defines the Service Provider Interface (SPI) for the {@link KEM} + * class. A security provider implements this interface to provide an + * implementation of a Key Encapsulation Mechanism (KEM) algorithm. + *

    + * A KEM algorithm may support a family of configurations. Each configuration + * may accept different types of keys, cryptographic primitives, and sizes of + * shared secrets and key encapsulation messages. A configuration is defined + * by the KEM algorithm name, the key it uses, and an optional + * {@code AlgorithmParameterSpec} argument that is specified when creating + * an encapsulator or decapsulator. The result of calling + * {@link #engineNewEncapsulator} or {@link #engineNewDecapsulator} must return + * an encapsulator or decapsulator that maps to a single configuration, + * where its {@code engineSecretSize()} and {@code engineEncapsulationSize()} + * methods return constant values. + *

    + * A {@code KEMSpi} implementation must be immutable. It must be safe to + * call multiple {@code engineNewEncapsulator} and {@code engineNewDecapsulator} + * methods at the same time. + *

    + * {@code EncapsulatorSpi} and {@code DecapsulatorSpi} implementations must also + * be immutable. It must be safe to invoke multiple {@code encapsulate} and + * {@code decapsulate} methods at the same time. Each invocation of + * {@code encapsulate} should generate a new shared secret and key + * encapsulation message. + *

    + * For example, + *

    {@code
    + * public static class MyKEMImpl implements KEMSpi {
    + *
    + *     @Override
    + *     public KEMSpi.EncapsulatorSpi engineNewEncapsulator(PublicKey publicKey,
    + *             AlgorithmParameterSpec spec, SecureRandom secureRandom)
    + *             throws InvalidAlgorithmParameterException, InvalidKeyException {
    + *         if (!checkPublicKey(publicKey)) {
    + *             throw new InvalidKeyException("unsupported key");
    + *         }
    + *         if (!checkParameters(spec)) {
    + *             throw new InvalidAlgorithmParameterException("unsupported params");
    + *         }
    + *         return new MyEncapsulator(publicKey, spec, secureRandom);
    + *     }
    + *
    + *     class MyEncapsulator implements KEMSpi.EncapsulatorSpi {
    + *         MyEncapsulator(PublicKey publicKey, AlgorithmParameterSpec spec,
    + *                 SecureRandom secureRandom){
    + *             this.spec = spec != null ? spec : getDefaultParameters();
    + *             this.secureRandom = secureRandom != null
    + *                     ? secureRandom
    + *                     : getDefaultSecureRandom();
    + *             this.publicKey = publicKey;
    + *         }
    + *
    + *         @Override
    + *         public KEM.Encapsulated encapsulate(int from, int to, String algorithm) {
    + *             byte[] encapsulation;
    + *             byte[] secret;
    + *             // calculating...
    + *             return new KEM.Encapsulated(
    + *                     new SecretKeySpec(secret, from, to - from, algorithm),
    + *                     encapsulation, null);
    + *         }
    + *
    + *         // ...
    + *     }
    + *
    + *     // ...
    + * }
    + * }
    + * + * @see KEM + * @apiNote This interface is defined in Java SE 17 Maintenance Release 1. + * @since 17 + */ +public interface KEMSpi { + + /** + * The KEM encapsulator implementation, generated by + * {@link #engineNewEncapsulator} on the KEM sender side. + * + * @see KEM.Encapsulator + * + * @apiNote This interface is defined in Java SE 17 Maintenance Release 1. + * @since 17 + */ + interface EncapsulatorSpi { + /** + * The key encapsulation function. + *

    + * Each invocation of this method must generate a new secret key and key + * encapsulation message that is returned in an {@link KEM.Encapsulated} object. + *

    + * An implementation must support the case where {@code from} is 0, + * {@code to} is the same as the return value of {@code secretSize()}, + * and {@code algorithm} is "Generic". + * + * @param from the initial index of the shared secret byte array + * to be returned, inclusive + * @param to the final index of the shared secret byte array + * to be returned, exclusive + * @param algorithm the algorithm name for the secret key that is returned + * @return an {@link KEM.Encapsulated} object containing a portion of + * the shared secret as a key with the specified algorithm, + * key encapsulation message, and optional parameters. + * @throws IndexOutOfBoundsException if {@code from < 0}, + * {@code from > to}, or {@code to > secretSize()} + * @throws NullPointerException if {@code algorithm} is {@code null} + * @throws UnsupportedOperationException if the combination of + * {@code from}, {@code to}, and {@code algorithm} + * is not supported by the encapsulator + * @see KEM.Encapsulated + * @see KEM.Encapsulator#encapsulate(int, int, String) + */ + KEM.Encapsulated engineEncapsulate(int from, int to, String algorithm); + + /** + * Returns the size of the shared secret. + * + * @return the size of the shared secret as a finite non-negative integer + * @see KEM.Encapsulator#secretSize() + */ + int engineSecretSize(); + + /** + * Returns the size of the key encapsulation message. + * + * @return the size of the key encapsulation message as a finite non-negative integer + * @see KEM.Encapsulator#encapsulationSize() + */ + int engineEncapsulationSize(); + } + + /** + * The KEM decapsulator implementation, generated by + * {@link #engineNewDecapsulator} on the KEM receiver side. + * + * @see KEM.Decapsulator + * + * @apiNote This interface is defined in Java SE 17 Maintenance Release 1. + * @since 17 + */ + interface DecapsulatorSpi { + /** + * The key decapsulation function. + *

    + * An invocation of this method recovers the secret key from the key + * encapsulation message. + *

    + * An implementation must support the case where {@code from} is 0, + * {@code to} is the same as the return value of {@code secretSize()}, + * and {@code algorithm} is "Generic". + * + * @param encapsulation the key encapsulation message from the sender. + * The size must be equal to the value returned by + * {@link #engineEncapsulationSize()} ()}, or a + * {@code DecapsulateException} must be thrown. + * @param from the initial index of the shared secret byte array + * to be returned, inclusive + * @param to the final index of the shared secret byte array + * to be returned, exclusive + * @param algorithm the algorithm name for the secret key that is returned + * @return a portion of the shared secret as a {@code SecretKey} with + * the specified algorithm + * @throws DecapsulateException if an error occurs during the + * decapsulation process + * @throws IndexOutOfBoundsException if {@code from < 0}, + * {@code from > to}, or {@code to > secretSize()} + * @throws NullPointerException if {@code encapsulation} or + * {@code algorithm} is {@code null} + * @throws UnsupportedOperationException if the combination of + * {@code from}, {@code to}, and {@code algorithm} + * is not supported by the decapsulator + * @see KEM.Decapsulator#decapsulate(byte[], int, int, String) + */ + SecretKey engineDecapsulate(byte[] encapsulation, int from, int to, String algorithm) + throws DecapsulateException; + + /** + * Returns the size of the shared secret. + * + * @return the size of the shared secret as a finite non-negative integer + * @see KEM.Decapsulator#secretSize() + */ + int engineSecretSize(); + + /** + * Returns the size of the key encapsulation message. + * + * @return the size of the key encapsulation message as a finite non-negative integer + * @see KEM.Decapsulator#encapsulationSize() + */ + int engineEncapsulationSize(); + } + + /** + * Creates a KEM encapsulator on the KEM sender side. + * + * @param publicKey the receiver's public key, must not be {@code null} + * @param spec the optional parameter, can be {@code null} + * @param secureRandom the source of randomness for encapsulation. + * If {@code null}, the implementation must provide + * a default one. + * @return the encapsulator for this key + * @throws InvalidAlgorithmParameterException if {@code spec} is invalid + * or one is required but {@code spec} is {@code null} + * @throws InvalidKeyException if {@code publicKey} is {@code null} or invalid + * @see KEM#newEncapsulator(PublicKey, AlgorithmParameterSpec, SecureRandom) + */ + EncapsulatorSpi engineNewEncapsulator(PublicKey publicKey, + AlgorithmParameterSpec spec, SecureRandom secureRandom) + throws InvalidAlgorithmParameterException, InvalidKeyException; + + /** + * Creates a KEM decapsulator on the KEM receiver side. + * + * @param privateKey the receiver's private key, must not be {@code null} + * @param spec the optional parameter, can be {@code null} + * @return the decapsulator for this key + * @throws InvalidAlgorithmParameterException if {@code spec} is invalid + * or one is required but {@code spec} is {@code null} + * @throws InvalidKeyException if {@code privateKey} is {@code null} or invalid + * @see KEM#newDecapsulator(PrivateKey, AlgorithmParameterSpec) + */ + DecapsulatorSpi engineNewDecapsulator(PrivateKey privateKey, AlgorithmParameterSpec spec) + throws InvalidAlgorithmParameterException, InvalidKeyException; +} diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java openjdk-17-17.0.13+11/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java --- openjdk-17-17.0.12+7/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java 2024-10-10 14:01:59.000000000 +0000 @@ -212,7 +212,9 @@ this.unopenedUrls = unopenedUrls; this.path = path; - this.jarHandler = null; + // the application class loader uses the built-in protocol handler to avoid protocol + // handler lookup when opening JAR files on the class path. + this.jarHandler = new sun.net.www.protocol.jar.Handler(); this.acc = null; } diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/jdk/internal/ref/CleanerImpl.java openjdk-17-17.0.13+11/src/java.base/share/classes/jdk/internal/ref/CleanerImpl.java --- openjdk-17-17.0.12+7/src/java.base/share/classes/jdk/internal/ref/CleanerImpl.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/jdk/internal/ref/CleanerImpl.java 2024-10-10 14:01:59.000000000 +0000 @@ -214,7 +214,7 @@ public Thread newThread(Runnable r) { return InnocuousThread.newThread("Cleaner-" + cleanerThreadNumber.getAndIncrement(), - r, Thread.MIN_PRIORITY - 2); + r, Thread.MAX_PRIORITY - 2); } } diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/sun/launcher/LauncherHelper.java openjdk-17-17.0.13+11/src/java.base/share/classes/sun/launcher/LauncherHelper.java --- openjdk-17-17.0.12+7/src/java.base/share/classes/sun/launcher/LauncherHelper.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/sun/launcher/LauncherHelper.java 2024-10-10 14:01:59.000000000 +0000 @@ -167,7 +167,7 @@ printProperties(); break; case "locale": - printLocale(); + printLocale(false); break; case "security": var opt = opts.length > 2 ? opts[2].trim() : "all"; @@ -181,7 +181,7 @@ default: printVmSettings(initialHeapSize, maxHeapSize, stackSize); printProperties(); - printLocale(); + printLocale(true); SecuritySettings.printSecuritySummarySettings(ostream); if (System.getProperty("os.name").contains("Linux")) { printSystemMetrics(); @@ -277,9 +277,15 @@ /* * prints the locale subopt/section */ - private static void printLocale() { + private static void printLocale(boolean summaryMode) { Locale locale = Locale.getDefault(); - ostream.println(LOCALE_SETTINGS); + if (!summaryMode) { + ostream.println(LOCALE_SETTINGS); + } else { + ostream.println("Locale settings summary:"); + ostream.println(INDENT + "Use \"-XshowSettings:locale\" " + + "option for verbose locale settings options"); + } ostream.println(INDENT + "default locale = " + locale.getDisplayName()); ostream.println(INDENT + "default display locale = " + @@ -288,7 +294,9 @@ Locale.getDefault(Category.FORMAT).getDisplayName()); ostream.println(INDENT + "tzdata version = " + ZoneInfoFile.getVersion()); - printLocales(); + if (!summaryMode) { + printLocales(); + } ostream.println(); } diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/sun/net/www/MessageHeader.java openjdk-17-17.0.13+11/src/java.base/share/classes/sun/net/www/MessageHeader.java --- openjdk-17-17.0.12+7/src/java.base/share/classes/sun/net/www/MessageHeader.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/sun/net/www/MessageHeader.java 2024-10-10 14:01:59.000000000 +0000 @@ -30,6 +30,8 @@ package sun.net.www; import java.io.*; +import java.lang.reflect.Array; +import java.net.ProtocolException; import java.util.Collections; import java.util.*; @@ -46,11 +48,32 @@ private String values[]; private int nkeys; + // max number of bytes for headers, <=0 means unlimited; + // this corresponds to the length of the names, plus the length + // of the values, plus an overhead of 32 bytes per name: value + // pair. + // Note: we use the same definition as HTTP/2 SETTINGS_MAX_HEADER_LIST_SIZE + // see RFC 9113, section 6.5.2. + // https://www.rfc-editor.org/rfc/rfc9113.html#SETTINGS_MAX_HEADER_LIST_SIZE + private final int maxHeaderSize; + + // Aggregate size of the field lines (name + value + 32) x N + // that have been parsed and accepted so far. + // This is defined as a long to force promotion to long + // and avoid overflows; see checkNewSize; + private long size; + public MessageHeader () { + this(0); + } + + public MessageHeader (int maxHeaderSize) { + this.maxHeaderSize = maxHeaderSize; grow(); } public MessageHeader (InputStream is) throws java.io.IOException { + maxHeaderSize = 0; parseHeader(is); } @@ -477,10 +500,28 @@ public void parseHeader(InputStream is) throws java.io.IOException { synchronized (this) { nkeys = 0; + size = 0; } mergeHeader(is); } + private void checkMaxHeaderSize(int sz) throws ProtocolException { + if (maxHeaderSize > 0) checkNewSize(size, sz, 0); + } + + private long checkNewSize(long size, int name, int value) throws ProtocolException { + // See SETTINGS_MAX_HEADER_LIST_SIZE, RFC 9113, section 6.5.2. + long newSize = size + name + value + 32; + if (maxHeaderSize > 0 && newSize > maxHeaderSize) { + Arrays.fill(keys, 0, nkeys, null); + Arrays.fill(values,0, nkeys, null); + nkeys = 0; + throw new ProtocolException(String.format("Header size too big: %s > %s", + newSize, maxHeaderSize)); + } + return newSize; + } + /** Parse and merge a MIME header from an input stream. */ @SuppressWarnings("fallthrough") public void mergeHeader(InputStream is) throws java.io.IOException { @@ -494,7 +535,15 @@ int c; boolean inKey = firstc > ' '; s[len++] = (char) firstc; + checkMaxHeaderSize(len); parseloop:{ + // We start parsing for a new name value pair here. + // The max header size includes an overhead of 32 bytes per + // name value pair. + // See SETTINGS_MAX_HEADER_LIST_SIZE, RFC 9113, section 6.5.2. + long maxRemaining = maxHeaderSize > 0 + ? maxHeaderSize - size - 32 + : Long.MAX_VALUE; while ((c = is.read()) >= 0) { switch (c) { case ':': @@ -528,6 +577,9 @@ s = ns; } s[len++] = (char) c; + if (maxHeaderSize > 0 && len > maxRemaining) { + checkMaxHeaderSize(len); + } } firstc = -1; } @@ -549,6 +601,9 @@ v = new String(); else v = String.copyValueOf(s, keyend, len - keyend); + int klen = k == null ? 0 : k.length(); + + size = checkNewSize(size, klen, v.length()); add(k, v); } } diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java openjdk-17-17.0.13+11/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java --- openjdk-17-17.0.12+7/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java 2024-10-10 14:01:59.000000000 +0000 @@ -171,6 +171,8 @@ */ private static int bufSize4ES = 0; + private static final int maxHeaderSize; + /* * Restrict setting of request headers through the public api * consistent with JavaScript XMLHttpRequest2 with a few @@ -285,6 +287,19 @@ } else { restrictedHeaderSet = null; } + + int defMaxHeaderSize = 384 * 1024; + String maxHeaderSizeStr = getNetProperty("jdk.http.maxHeaderSize"); + int maxHeaderSizeVal = defMaxHeaderSize; + if (maxHeaderSizeStr != null) { + try { + maxHeaderSizeVal = Integer.parseInt(maxHeaderSizeStr); + } catch (NumberFormatException n) { + maxHeaderSizeVal = defMaxHeaderSize; + } + } + if (maxHeaderSizeVal < 0) maxHeaderSizeVal = 0; + maxHeaderSize = maxHeaderSizeVal; } static final String httpVersion = "HTTP/1.1"; @@ -759,7 +774,7 @@ } ps = (PrintStream) http.getOutputStream(); connected=true; - responses = new MessageHeader(); + responses = new MessageHeader(maxHeaderSize); setRequests=false; writeRequests(); } @@ -917,7 +932,7 @@ throws IOException { super(checkURL(u)); requests = new MessageHeader(); - responses = new MessageHeader(); + responses = new MessageHeader(maxHeaderSize); userHeaders = new MessageHeader(); this.handler = handler; instProxy = p; @@ -2872,7 +2887,7 @@ } // clear out old response headers!!!! - responses = new MessageHeader(); + responses = new MessageHeader(maxHeaderSize); if (stat == HTTP_USE_PROXY) { /* This means we must re-request the resource through the * proxy denoted in the "Location:" field of the response. @@ -3062,7 +3077,7 @@ } catch (IOException e) { } } responseCode = -1; - responses = new MessageHeader(); + responses = new MessageHeader(maxHeaderSize); connected = false; } diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/sun/security/provider/PolicyFile.java openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/provider/PolicyFile.java --- openjdk-17-17.0.12+7/src/java.base/share/classes/sun/security/provider/PolicyFile.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/provider/PolicyFile.java 2024-10-10 14:01:59.000000000 +0000 @@ -615,6 +615,9 @@ ("java.specification.version", SecurityConstants.PROPERTY_READ_ACTION)); pe.add(new PropertyPermission + ("java.specification.maintenance.version", + SecurityConstants.PROPERTY_READ_ACTION)); + pe.add(new PropertyPermission ("java.specification.vendor", SecurityConstants.PROPERTY_READ_ACTION)); pe.add(new PropertyPermission diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/sun/security/ssl/CertificateMessage.java openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/CertificateMessage.java --- openjdk-17-17.0.12+7/src/java.base/share/classes/sun/security/ssl/CertificateMessage.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/CertificateMessage.java 2024-10-10 14:01:59.000000000 +0000 @@ -388,7 +388,7 @@ ClientAuthType.CLIENT_AUTH_REQUESTED) { // unexpected or require client authentication throw shc.conContext.fatal(Alert.BAD_CERTIFICATE, - "Empty server certificate chain"); + "Empty client certificate chain"); } else { return; } @@ -405,7 +405,7 @@ } } catch (CertificateException ce) { throw shc.conContext.fatal(Alert.BAD_CERTIFICATE, - "Failed to parse server certificates", ce); + "Failed to parse client certificates", ce); } checkClientCerts(shc, x509Certs); @@ -1247,7 +1247,7 @@ } } catch (CertificateException ce) { throw shc.conContext.fatal(Alert.BAD_CERTIFICATE, - "Failed to parse server certificates", ce); + "Failed to parse client certificates", ce); } // find out the types of client authentication used diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/sun/security/ssl/ClientHello.java openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/ClientHello.java --- openjdk-17-17.0.12+7/src/java.base/share/classes/sun/security/ssl/ClientHello.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/ClientHello.java 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, 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 @@ -217,8 +217,6 @@ // ignore cookie hos.putBytes16(getEncodedCipherSuites()); hos.putBytes8(compressionMethod); - extensions.send(hos); // In TLS 1.3, use of certain - // extensions is mandatory. } catch (IOException ioe) { // unlikely } @@ -904,8 +902,8 @@ throw context.conContext.fatal(Alert.PROTOCOL_VERSION, "The client supported protocol versions " + Arrays.toString( ProtocolVersion.toStringArray(clientSupportedVersions)) + - " are not accepted by server preferences " + - context.activeProtocols); + " are not accepted by server preferences " + Arrays.toString( + ProtocolVersion.toStringArray(context.activeProtocols))); } } @@ -1427,6 +1425,9 @@ shc.handshakeProducers.put(SSLHandshake.SERVER_HELLO.id, SSLHandshake.SERVER_HELLO); + // Reset the ClientHello non-zero offset fragment allowance + shc.acceptCliHelloFragments = false; + // // produce // diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/sun/security/ssl/DTLSInputRecord.java openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/DTLSInputRecord.java --- openjdk-17-17.0.12+7/src/java.base/share/classes/sun/security/ssl/DTLSInputRecord.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/DTLSInputRecord.java 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, 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 @@ -28,13 +28,7 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.security.GeneralSecurityException; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; -import java.util.TreeSet; +import java.util.*; import javax.crypto.BadPaddingException; import javax.net.ssl.SSLException; import javax.net.ssl.SSLProtocolException; @@ -46,12 +40,23 @@ final class DTLSInputRecord extends InputRecord implements DTLSRecord { private DTLSReassembler reassembler = null; private int readEpoch; + private SSLContextImpl sslContext; DTLSInputRecord(HandshakeHash handshakeHash) { super(handshakeHash, SSLReadCipher.nullDTlsReadCipher()); this.readEpoch = 0; } + // Method to set TransportContext + public void setTransportContext(TransportContext tc) { + this.tc = tc; + } + + // Method to set SSLContext + public void setSSLContext(SSLContextImpl sslContext) { + this.sslContext = sslContext; + } + @Override void changeReadCiphers(SSLReadCipher readCipher) { this.readCipher = readCipher; @@ -544,6 +549,27 @@ } } + /** + * Turn a sufficiently-large initial ClientHello fragment into one that + * stops immediately after the compression methods. This is only used + * for the initial CH message fragment at offset 0. + * + * @param srcFrag the fragment actually received by the DTLSReassembler + * @param limit the size of the new, cloned/truncated handshake fragment + * + * @return a truncated handshake fragment that is sized to look like a + * complete message, but actually contains only up to the compression + * methods (no extensions) + */ + private static HandshakeFragment truncateChFragment(HandshakeFragment srcFrag, + int limit) { + return new HandshakeFragment(Arrays.copyOf(srcFrag.fragment, limit), + srcFrag.contentType, srcFrag.majorVersion, + srcFrag.minorVersion, srcFrag.recordEnS, srcFrag.recordEpoch, + srcFrag.recordSeq, srcFrag.handshakeType, limit, + srcFrag.messageSeq, srcFrag.fragmentOffset, limit); + } + private static final class HoleDescriptor { int offset; // fragment_offset int limit; // fragment_offset + fragment_length @@ -647,10 +673,17 @@ // Queue up a handshake message. void queueUpHandshake(HandshakeFragment hsf) throws SSLProtocolException { if (!isDesirable(hsf)) { - // Not a dedired record, discard it. + // Not a desired record, discard it. return; } + if (hsf.handshakeType == SSLHandshake.CLIENT_HELLO.id) { + // validate the first or subsequent ClientHello message + if ((hsf = valHello(hsf, hsf.messageSeq == 0)) == null) { + return; + } + } + // Clean up the retransmission messages if necessary. cleanUpRetransmit(hsf); @@ -783,6 +816,100 @@ } } + private HandshakeFragment valHello(HandshakeFragment hsf, + boolean firstHello) { + ServerHandshakeContext shc = + (ServerHandshakeContext) tc.handshakeContext; + // Drop any fragment that is not a zero offset until we've received + // a second (or possibly later) CH message that passes the cookie + // check. + if (shc == null || !shc.acceptCliHelloFragments) { + if (hsf.fragmentOffset != 0) { + return null; + } + } else { + // Let this fragment through to the DTLSReassembler as-is + return hsf; + } + + try { + ByteBuffer fragmentData = ByteBuffer.wrap(hsf.fragment); + + ProtocolVersion pv = ProtocolVersion.valueOf( + Record.getInt16(fragmentData)); + if (!pv.isDTLS) { + return null; + } + // Read the random (32 bytes) + if (fragmentData.remaining() < 32) { + if (SSLLogger.isOn && SSLLogger.isOn("verbose")) { + SSLLogger.fine("Rejected client hello fragment (bad random len) " + + "fo=" + hsf.fragmentOffset + " fl=" + hsf.fragmentLength); + } + return null; + } + fragmentData.position(fragmentData.position() + 32); + + // SessionID + byte[] sessId = Record.getBytes8(fragmentData); + if (sessId.length > 0 && + !SSLConfiguration.enableDtlsResumeCookie) { + // If we are in a resumption it is possible that the cookie + // exchange will be skipped. This is a server-side setting + // and it is NOT the default. If enableDtlsResumeCookie is + // false though, then we will buffer fragments since there + // is no cookie exchange to execute prior to performing + // reassembly. + return hsf; + } + + // Cookie + byte[] cookie = Record.getBytes8(fragmentData); + if (firstHello && cookie.length != 0) { + if (SSLLogger.isOn && SSLLogger.isOn("verbose")) { + SSLLogger.fine("Rejected initial client hello fragment (bad cookie len) " + + "fo=" + hsf.fragmentOffset + " fl=" + hsf.fragmentLength); + } + return null; + } + // CipherSuites + Record.getBytes16(fragmentData); + // Compression methods + Record.getBytes8(fragmentData); + + // If it's the first fragment, we'll truncate it and push it + // through the reassembler. + if (firstHello) { + return truncateChFragment(hsf, fragmentData.position()); + } else { + HelloCookieManager hcMgr = sslContext. + getHelloCookieManager(ProtocolVersion.DTLS10); + ByteBuffer msgFragBuf = ByteBuffer.wrap(hsf.fragment, 0, + fragmentData.position()); + ClientHello.ClientHelloMessage chMsg = + new ClientHello.ClientHelloMessage(shc, msgFragBuf, null); + if (!hcMgr.isCookieValid(shc, chMsg, cookie)) { + // Bad cookie check, truncate it and let the ClientHello + // consumer recheck, fail and take the appropriate action. + return truncateChFragment(hsf, fragmentData.position()); + } else { + // It's a good cookie, return the original handshake + // fragment and let it go into the DTLSReassembler like + // any other fragment so we can wait for the rest of + // the CH message. + shc.acceptCliHelloFragments = true; + return hsf; + } + } + } catch (IOException ioe) { + if (SSLLogger.isOn && SSLLogger.isOn("verbose")) { + SSLLogger.fine("Rejected client hello fragment " + + "fo=" + hsf.fragmentOffset + " fl=" + hsf.fragmentLength); + } + return null; + } + } + // Queue up a ChangeCipherSpec message void queueUpChangeCipherSpec(RecordFragment rf) throws SSLProtocolException { diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java --- openjdk-17-17.0.12+7/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, 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 @@ -71,9 +71,6 @@ private volatile StatusResponseManager statusResponseManager; private final ReentrantLock contextLock = new ReentrantLock(); - final HashMap keyHashMap = new HashMap<>(); - SSLContextImpl() { ephemeralKeyManager = new EphemeralKeyManager(); diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/sun/security/ssl/SSLSessionContextImpl.java openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/SSLSessionContextImpl.java --- openjdk-17-17.0.12+7/src/java.base/share/classes/sun/security/ssl/SSLSessionContextImpl.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/SSLSessionContextImpl.java 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, 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 @@ -28,7 +28,11 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; +import java.util.Iterator; import java.util.Locale; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSessionContext; @@ -69,6 +73,11 @@ private int cacheLimit; // the max cache size private int timeout; // timeout in seconds + // The current session ticket encryption key ID (only used in server context) + private int currentKeyID; + // Session ticket encryption keys and IDs map (only used in server context) + private final Map keyHashMap; + // Default setting for stateless session resumption support (RFC 5077) private boolean statelessSession = true; @@ -80,6 +89,14 @@ // use soft reference sessionCache = Cache.newSoftMemoryCache(cacheLimit, timeout); sessionHostPortCache = Cache.newSoftMemoryCache(cacheLimit, timeout); + if (server) { + keyHashMap = new ConcurrentHashMap<>(); + // Should be "randomly generated" according to RFC 5077, + // but doesn't necessarily has to be a true random number. + currentKeyID = new Random(System.nanoTime()).nextInt(); + } else { + keyHashMap = Map.of(); + } } // Stateless sessions when available, but there is a cache @@ -170,6 +187,51 @@ return cacheLimit; } + private void cleanupStatelessKeys() { + Iterator> it = + keyHashMap.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry entry = it.next(); + SessionTicketExtension.StatelessKey k = entry.getValue(); + if (k.isInvalid(this)) { + it.remove(); + try { + k.key.destroy(); + } catch (Exception e) { + // Suppress + } + } + } + } + + // Package-private, used only from SessionTicketExtension.KeyState::getCurrentKey. + SessionTicketExtension.StatelessKey getKey(HandshakeContext hc) { + SessionTicketExtension.StatelessKey ssk = keyHashMap.get(currentKeyID); + if (ssk != null && !ssk.isExpired()) { + return ssk; + } + synchronized (this) { + // If the current key is no longer expired, it was already + // updated by a concurrent request, and we can return. + ssk = keyHashMap.get(currentKeyID); + if (ssk != null && !ssk.isExpired()) { + return ssk; + } + int newID = currentKeyID + 1; + ssk = new SessionTicketExtension.StatelessKey(hc, newID); + keyHashMap.put(Integer.valueOf(newID), ssk); + currentKeyID = newID; + } + // Check for and delete invalid keys every time we create a new stateless key. + cleanupStatelessKeys(); + return ssk; + } + + // Package-private, used only from SessionTicketExtension.KeyState::getKey. + SessionTicketExtension.StatelessKey getKey(int id) { + return keyHashMap.get(id); + } + // package-private method, used ONLY by ServerHandshaker SSLSessionImpl get(byte[] id) { return (SSLSessionImpl)getSession(id); diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java --- openjdk-17-17.0.12+7/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java 2024-10-10 14:01:59.000000000 +0000 @@ -1791,21 +1791,24 @@ if (conContext.inputRecord instanceof SSLSocketInputRecord inputRecord && isConnected) { if (appInput.readLock.tryLock()) { - int soTimeout = getSoTimeout(); try { - // deplete could hang on the skip operation - // in case of infinite socket read timeout. - // Change read timeout to avoid deadlock. - // This workaround could be replaced later - // with the right synchronization - if (soTimeout == 0) - setSoTimeout(DEFAULT_SKIP_TIMEOUT); - inputRecord.deplete(false); - } catch (java.net.SocketTimeoutException stEx) { - // skip timeout exception during deplete + int soTimeout = getSoTimeout(); + try { + // deplete could hang on the skip operation + // in case of infinite socket read timeout. + // Change read timeout to avoid deadlock. + // This workaround could be replaced later + // with the right synchronization + if (soTimeout == 0) + setSoTimeout(DEFAULT_SKIP_TIMEOUT); + inputRecord.deplete(false); + } catch (java.net.SocketTimeoutException stEx) { + // skip timeout exception during deplete + } finally { + if (soTimeout == 0) + setSoTimeout(soTimeout); + } } finally { - if (soTimeout == 0) - setSoTimeout(soTimeout); appInput.readLock.unlock(); } } diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/sun/security/ssl/ServerHandshakeContext.java openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/ServerHandshakeContext.java --- openjdk-17-17.0.12+7/src/java.base/share/classes/sun/security/ssl/ServerHandshakeContext.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/ServerHandshakeContext.java 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -55,6 +55,7 @@ CertificateMessage.CertificateEntry currentCertEntry; private static final long DEFAULT_STATUS_RESP_DELAY = 5000L; final long statusRespTimeout; + boolean acceptCliHelloFragments = false; ServerHandshakeContext(SSLContextImpl sslContext, diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/sun/security/ssl/ServerNameExtension.java openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/ServerNameExtension.java --- openjdk-17-17.0.12+7/src/java.base/share/classes/sun/security/ssl/ServerNameExtension.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/ServerNameExtension.java 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -42,6 +42,7 @@ import static sun.security.ssl.SSLExtension.CH_SERVER_NAME; import static sun.security.ssl.SSLExtension.EE_SERVER_NAME; import sun.security.ssl.SSLExtension.ExtensionConsumer; +import static sun.security.ssl.SSLExtension.SH_PRE_SHARED_KEY; import static sun.security.ssl.SSLExtension.SH_SERVER_NAME; import sun.security.ssl.SSLExtension.SSLExtensionSpec; import sun.security.ssl.SSLHandshake.HandshakeMessage; @@ -344,6 +345,10 @@ sni, shc.resumingSession.serverNameIndication)) { shc.isResumption = false; shc.resumingSession = null; + // this server is disallowing this session resumption, + // so don't include the pre-shared key in the + // ServerHello handshake message + shc.handshakeExtensions.remove(SH_PRE_SHARED_KEY); if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { SSLLogger.fine( "abort session resumption, " + diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/sun/security/ssl/SessionTicketExtension.java openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/SessionTicketExtension.java --- openjdk-17-17.0.12+7/src/java.base/share/classes/sun/security/ssl/SessionTicketExtension.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/SessionTicketExtension.java 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -37,6 +37,7 @@ import javax.crypto.SecretKey; import javax.crypto.spec.GCMParameterSpec; import javax.net.ssl.SSLProtocolException; +import javax.net.ssl.SSLSessionContext; import static sun.security.ssl.SSLExtension.CH_SESSION_TICKET; import static sun.security.ssl.SSLExtension.SH_SESSION_TICKET; @@ -76,7 +77,6 @@ // Time in milliseconds until key is changed for encrypting session state private static final int TIMEOUT_DEFAULT = 3600 * 1000; private static final int keyTimeout; - private static int currentKeyID = new SecureRandom().nextInt(); private static final int KEYLEN = 256; static { @@ -117,7 +117,8 @@ final SecretKey key; final int num; - StatelessKey(HandshakeContext hc, int newNum) { + // package-private, used only by SSLContextImpl + StatelessKey(HandshakeContext hc, int num) { SecretKey k = null; try { KeyGenerator kg = KeyGenerator.getInstance("AES"); @@ -128,8 +129,7 @@ } key = k; timeout = System.currentTimeMillis() + keyTimeout; - num = newNum; - hc.sslContext.keyHashMap.put(Integer.valueOf(num), this); + this.num = num; } // Check if key needs to be changed @@ -138,7 +138,8 @@ } // Check if this key is ready for deletion. - boolean isInvalid(long sessionTimeout) { + boolean isInvalid(SSLSessionContext sslSessionContext) { + int sessionTimeout = sslSessionContext.getSessionTimeout() * 1000; return ((System.currentTimeMillis()) > (timeout + sessionTimeout)); } } @@ -147,9 +148,11 @@ // Get a key with a specific key number static StatelessKey getKey(HandshakeContext hc, int num) { - StatelessKey ssk = hc.sslContext.keyHashMap.get(num); + SSLSessionContextImpl serverCache = + (SSLSessionContextImpl)hc.sslContext.engineGetServerSessionContext(); + StatelessKey ssk = serverCache.getKey(num); - if (ssk == null || ssk.isInvalid(getSessionTimeout(hc))) { + if (ssk == null || ssk.isInvalid(serverCache)) { return null; } return ssk; @@ -157,69 +160,9 @@ // Get the current valid key, this will generate a new key if needed static StatelessKey getCurrentKey(HandshakeContext hc) { - StatelessKey ssk = hc.sslContext.keyHashMap.get(currentKeyID); - - if (ssk != null && !ssk.isExpired()) { - return ssk; - } - return nextKey(hc); - } - - // This method locks when the first getCurrentKey() finds it to be too - // old and create a new key to replace the current key. After the new - // key established, the lock can be released so following - // operations will start using the new key. - // The first operation will take a longer code path by generating the - // next key and cleaning up old keys. - private static StatelessKey nextKey(HandshakeContext hc) { - StatelessKey ssk; - - synchronized (hc.sslContext.keyHashMap) { - // If the current key is no longer expired, it was already - // updated by a previous operation and we can return. - ssk = hc.sslContext.keyHashMap.get(currentKeyID); - if (ssk != null && !ssk.isExpired()) { - return ssk; - } - int newNum; - if (currentKeyID == Integer.MAX_VALUE) { - newNum = 0; - } else { - newNum = currentKeyID + 1; - } - // Get new key - ssk = new StatelessKey(hc, newNum); - currentKeyID = newNum; - // Release lock since the new key is ready to be used. - } - - // Clean up any old keys, then return the current key - cleanup(hc); - return ssk; - } - - // Deletes any invalid SessionStateKeys. - static void cleanup(HandshakeContext hc) { - int sessionTimeout = getSessionTimeout(hc); - - StatelessKey ks; - for (Object o : hc.sslContext.keyHashMap.keySet().toArray()) { - Integer i = (Integer)o; - ks = hc.sslContext.keyHashMap.get(i); - if (ks.isInvalid(sessionTimeout)) { - try { - ks.key.destroy(); - } catch (Exception e) { - // Suppress - } - hc.sslContext.keyHashMap.remove(i); - } - } - } - - static int getSessionTimeout(HandshakeContext hc) { - return hc.sslContext.engineGetServerSessionContext(). - getSessionTimeout() * 1000; + SSLSessionContextImpl serverCache = + (SSLSessionContextImpl)hc.sslContext.engineGetServerSessionContext(); + return serverCache.getKey(hc); } } diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/sun/security/ssl/TransportContext.java openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/TransportContext.java --- openjdk-17-17.0.12+7/src/java.base/share/classes/sun/security/ssl/TransportContext.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/ssl/TransportContext.java 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -156,6 +156,11 @@ this.acc = AccessController.getContext(); this.consumers = new HashMap<>(); + + if (inputRecord instanceof DTLSInputRecord dtlsInputRecord) { + dtlsInputRecord.setTransportContext(this); + dtlsInputRecord.setSSLContext(this.sslContext); + } } // Dispatch plaintext to a specific consumer. diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/sun/security/util/Debug.java openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/util/Debug.java --- openjdk-17-17.0.12+7/src/java.base/share/classes/sun/security/util/Debug.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/util/Debug.java 2024-10-10 14:01:59.000000000 +0000 @@ -27,6 +27,9 @@ import java.io.PrintStream; import java.math.BigInteger; +import java.time.Instant; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; import java.util.HexFormat; import java.util.regex.Pattern; import java.util.regex.Matcher; @@ -41,8 +44,14 @@ public class Debug { private String prefix; + private boolean printDateTime; + private boolean printThreadDetails; private static String args; + private static boolean threadInfoAll; + private static boolean timeStampInfoAll; + private static final String TIMESTAMP_OPTION = "+timestamp"; + private static final String THREAD_OPTION = "+thread"; static { args = GetPropertyAction.privilegedGetProperty("java.security.debug"); @@ -61,12 +70,21 @@ args = marshal(args); if (args.equals("help")) { Help(); + } else if (args.contains("all")) { + // "all" option has special handling for decorator options + // If the thread or timestamp decorator option is detected + // with the "all" option, then it impacts decorator options + // for other categories + int beginIndex = args.lastIndexOf("all") + "all".length(); + int commaIndex = args.indexOf(',', beginIndex); + if (commaIndex == -1) commaIndex = args.length(); + threadInfoAll = args.substring(beginIndex, commaIndex).contains(THREAD_OPTION); + timeStampInfoAll = args.substring(beginIndex, commaIndex).contains(TIMESTAMP_OPTION); } } } - public static void Help() - { + public static void Help() { System.err.println(); System.err.println("all turn on all debugging"); System.err.println("access print all checkPermission results"); @@ -92,6 +110,11 @@ System.err.println("securerandom SecureRandom"); System.err.println("ts timestamping"); System.err.println(); + System.err.println("+timestamp can be appended to any of above options to print"); + System.err.println(" a timestamp for that debug option"); + System.err.println("+thread can be appended to any of above options to print"); + System.err.println(" thread and caller information for that debug option"); + System.err.println(); System.err.println("The following can be used with access:"); System.err.println(); System.err.println("stack include stack trace"); @@ -132,8 +155,7 @@ * option is set. Set the prefix to be the same as option. */ - public static Debug getInstance(String option) - { + public static Debug getInstance(String option) { return getInstance(option, option); } @@ -141,23 +163,57 @@ * Get a Debug object corresponding to whether or not the given * option is set. Set the prefix to be prefix. */ - public static Debug getInstance(String option, String prefix) - { + public static Debug getInstance(String option, String prefix) { if (isOn(option)) { Debug d = new Debug(); d.prefix = prefix; + d.configureExtras(option); return d; } else { return null; } } + private static String formatCaller() { + return StackWalker.getInstance().walk(s -> + s.dropWhile(f -> + f.getClassName().startsWith("sun.security.util.Debug")) + .map(f -> f.getFileName() + ":" + f.getLineNumber()) + .findFirst().orElse("unknown caller")); + } + + // parse an option string to determine if extra details, + // like thread and timestamp, should be printed + private void configureExtras(String option) { + // treat "all" as special case, only used for java.security.debug property + this.printDateTime = timeStampInfoAll; + this.printThreadDetails = threadInfoAll; + + if (printDateTime && printThreadDetails) { + // nothing left to configure + return; + } + + // args is converted to lower case for the most part via marshal method + int optionIndex = args.lastIndexOf(option); + if (optionIndex == -1) { + // option not in args list. Only here since "all" was present + // in debug property argument. "all" option already parsed + return; + } + int beginIndex = optionIndex + option.length(); + int commaIndex = args.indexOf(',', beginIndex); + if (commaIndex == -1) commaIndex = args.length(); + String subOpt = args.substring(beginIndex, commaIndex); + printDateTime = printDateTime || subOpt.contains(TIMESTAMP_OPTION); + printThreadDetails = printThreadDetails || subOpt.contains(THREAD_OPTION); + } + /** * True if the system property "security.debug" contains the * string "option". */ - public static boolean isOn(String option) - { + public static boolean isOn(String option) { if (args == null) return false; else { @@ -180,18 +236,16 @@ * created from the call to getInstance. */ - public void println(String message) - { - System.err.println(prefix + ": "+message); + public void println(String message) { + System.err.println(prefix + extraInfo() + ": " + message); } /** * print a message to stderr that is prefixed with the prefix * created from the call to getInstance and obj. */ - public void println(Object obj, String message) - { - System.err.println(prefix + " [" + obj.getClass().getSimpleName() + + public void println(Object obj, String message) { + System.err.println(prefix + extraInfo() + " [" + obj.getClass().getSimpleName() + "@" + System.identityHashCode(obj) + "]: "+message); } @@ -199,18 +253,36 @@ * print a blank line to stderr that is prefixed with the prefix. */ - public void println() - { - System.err.println(prefix + ":"); + public void println() { + System.err.println(prefix + extraInfo() + ":"); } /** * print a message to stderr that is prefixed with the prefix. */ - public static void println(String prefix, String message) - { - System.err.println(prefix + ": "+message); + public void println(String prefix, String message) { + System.err.println(prefix + extraInfo() + ": " + message); + } + + /** + * If thread debug option enabled, include information containing + * hex value of threadId and the current thread name + * If timestamp debug option enabled, include timestamp string + * @return extra info if debug option enabled. + */ + private String extraInfo() { + String retString = ""; + if (printThreadDetails) { + retString = "0x" + Long.toHexString( + Thread.currentThread().getId()).toUpperCase(Locale.ROOT) + + "|" + Thread.currentThread().getName() + "|" + formatCaller(); + } + if (printDateTime) { + retString += (retString.isEmpty() ? "" : "|") + + FormatHolder.DATE_TIME_FORMATTER.format(Instant.now()); + } + return retString.isEmpty() ? "" : "[" + retString + "]"; } /** @@ -326,4 +398,11 @@ return HexFormat.ofDelimiter(":").formatHex(b); } + // Holder class to break cyclic dependency seen during build + private static class FormatHolder { + private static final String PATTERN = "yyyy-MM-dd kk:mm:ss.SSS"; + private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter + .ofPattern(PATTERN, Locale.ENGLISH) + .withZone(ZoneId.systemDefault()); + } } diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/sun/security/validator/CADistrustPolicy.java openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/validator/CADistrustPolicy.java --- openjdk-17-17.0.12+7/src/java.base/share/classes/sun/security/validator/CADistrustPolicy.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/validator/CADistrustPolicy.java 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -53,6 +53,22 @@ } SymantecTLSPolicy.checkDistrust(chain); } + }, + + /** + * Distrust TLS Server certificates anchored by an Entrust root CA and + * issued after November 11, 2024. If enabled, this policy is currently + * enforced by the PKIX and SunX509 TrustManager implementations + * of the SunJSSE provider implementation. + */ + ENTRUST_TLS { + void checkDistrust(String variant, X509Certificate[] chain) + throws ValidatorException { + if (!variant.equals(Validator.VAR_TLS_SERVER)) { + return; + } + EntrustTLSPolicy.checkDistrust(chain); + } }; /** diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/sun/security/validator/EntrustTLSPolicy.java openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/validator/EntrustTLSPolicy.java --- openjdk-17-17.0.12+7/src/java.base/share/classes/sun/security/validator/EntrustTLSPolicy.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/sun/security/validator/EntrustTLSPolicy.java 2024-10-10 14:01:59.000000000 +0000 @@ -0,0 +1,136 @@ +/* + * 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 sun.security.validator; + +import java.security.cert.X509Certificate; +import java.time.LocalDate; +import java.time.Month; +import java.time.ZoneOffset; +import java.util.Date; +import java.util.Map; +import java.util.Set; + +import sun.security.util.Debug; +import sun.security.x509.X509CertImpl; + +/** + * This class checks if Entrust issued TLS Server certificates should be + * restricted. + */ +final class EntrustTLSPolicy { + + private static final Debug debug = Debug.getInstance("certpath"); + + // SHA-256 certificate fingerprints of distrusted roots + private static final Set FINGERPRINTS = Set.of( + // cacerts alias: entrustevca + // DN: CN=Entrust Root Certification Authority, + // OU=(c) 2006 Entrust, Inc., + // OU=www.entrust.net/CPS is incorporated by reference, + // O=Entrust, Inc., C=US + "73C176434F1BC6D5ADF45B0E76E727287C8DE57616C1E6E6141A2B2CBC7D8E4C", + // cacerts alias: entrustrootcaec1 + // DN: CN=Entrust Root Certification Authority - EC1, + // OU=(c) 2012 Entrust, Inc. - for authorized use only, + // OU=See www.entrust.net/legal-terms, O=Entrust, Inc., C=US + "02ED0EB28C14DA45165C566791700D6451D7FB56F0B2AB1D3B8EB070E56EDFF5", + // cacerts alias: entrustrootcag2 + // DN: CN=Entrust Root Certification Authority - G2, + // OU=(c) 2009 Entrust, Inc. - for authorized use only, + // OU=See www.entrust.net/legal-terms, O=Entrust, Inc., C=US + "43DF5774B03E7FEF5FE40D931A7BEDF1BB2E6B42738C4E6D3841103D3AA7F339", + // cacerts alias: entrustrootcag4 + // DN: CN=Entrust Root Certification Authority - G4 + // OU=(c) 2015 Entrust, Inc. - for authorized use only, + // OU=See www.entrust.net/legal-terms, O=Entrust, Inc., C=US, + "DB3517D1F6732A2D5AB97C533EC70779EE3270A62FB4AC4238372460E6F01E88", + // cacerts alias: entrust2048ca + // DN: CN=Entrust.net Certification Authority (2048), + // OU=(c) 1999 Entrust.net Limited, + // OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.), + // O=Entrust.net + "6DC47172E01CBCB0BF62580D895FE2B8AC9AD4F873801E0C10B9C837D21EB177", + // cacerts alias: affirmtrustcommercialca + // DN: CN=AffirmTrust Commercial, O=AffirmTrust, C=US + "0376AB1D54C5F9803CE4B2E201A0EE7EEF7B57B636E8A93C9B8D4860C96F5FA7", + // cacerts alias: affirmtrustnetworkingca + // DN: CN=AffirmTrust Networking, O=AffirmTrust, C=US + "0A81EC5A929777F145904AF38D5D509F66B5E2C58FCDB531058B0E17F3F0B41B", + // cacerts alias: affirmtrustpremiumca + // DN: CN=AffirmTrust Premium, O=AffirmTrust, C=US + "70A73F7F376B60074248904534B11482D5BF0E698ECC498DF52577EBF2E93B9A", + // cacerts alias: affirmtrustpremiumeccca + // DN: CN=AffirmTrust Premium ECC, O=AffirmTrust, C=US + "BD71FDF6DA97E4CF62D1647ADD2581B07D79ADF8397EB4ECBA9C5E8488821423" + ); + + // Any TLS Server certificate that is anchored by one of the Entrust + // roots above and is issued after this date will be distrusted. + private static final LocalDate NOVEMBER_11_2024 = + LocalDate.of(2024, Month.NOVEMBER, 11); + + /** + * This method assumes the eeCert is a TLS Server Cert and chains back to + * the anchor. + * + * @param chain the end-entity's certificate chain. The end entity cert + * is at index 0, the trust anchor at index n-1. + * @throws ValidatorException if the certificate is distrusted + */ + static void checkDistrust(X509Certificate[] chain) + throws ValidatorException { + X509Certificate anchor = chain[chain.length-1]; + String fp = fingerprint(anchor); + if (fp == null) { + throw new ValidatorException("Cannot generate fingerprint for " + + "trust anchor of TLS server certificate"); + } + if (FINGERPRINTS.contains(fp)) { + Date notBefore = chain[0].getNotBefore(); + LocalDate ldNotBefore = LocalDate.ofInstant(notBefore.toInstant(), + ZoneOffset.UTC); + // reject if certificate is issued after November 11, 2024 + checkNotBefore(ldNotBefore, NOVEMBER_11_2024, anchor); + } + } + + private static String fingerprint(X509Certificate cert) { + return X509CertImpl.getFingerprint("SHA-256", cert, debug); + } + + private static void checkNotBefore(LocalDate notBeforeDate, + LocalDate distrustDate, X509Certificate anchor) + throws ValidatorException { + if (notBeforeDate.isAfter(distrustDate)) { + throw new ValidatorException + ("TLS Server certificate issued after " + distrustDate + + " and anchored by a distrusted legacy Entrust root CA: " + + anchor.getSubjectX500Principal(), + ValidatorException.T_UNTRUSTED_CERT, anchor); + } + } + + private EntrustTLSPolicy() {} +} diff -Nru openjdk-17-17.0.12+7/src/java.base/share/classes/sun/util/resources/CurrencyNames.properties openjdk-17-17.0.13+11/src/java.base/share/classes/sun/util/resources/CurrencyNames.properties --- openjdk-17-17.0.12+7/src/java.base/share/classes/sun/util/resources/CurrencyNames.properties 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/classes/sun/util/resources/CurrencyNames.properties 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2023, 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 @@ -284,6 +284,7 @@ ZMK=ZMK ZMW=ZMW ZWD=ZWD +ZWG=ZWG ZWL=ZWL ZWN=ZWN ZWR=ZWR @@ -509,5 +510,6 @@ zar=South African Rand zmk=Zambian Kwacha zwd=Zimbabwean Dollar (1980-2008) +zwg=Zimbabwe Gold zwl=Zimbabwean Dollar (2009) zwr=Zimbabwean Dollar (2008) diff -Nru openjdk-17-17.0.12+7/src/java.base/share/conf/net.properties openjdk-17-17.0.13+11/src/java.base/share/conf/net.properties --- openjdk-17-17.0.12+7/src/java.base/share/conf/net.properties 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/conf/net.properties 2024-10-10 14:01:59.000000000 +0000 @@ -130,3 +130,20 @@ #jdk.http.ntlm.transparentAuth=trustedHosts # jdk.http.ntlm.transparentAuth=disabled + +# +# Maximum HTTP field section size that a client is prepared to accept +# +# jdk.http.maxHeaderSize=393216 +# +# This is the maximum header field section size that a client is prepared to accept. +# This is computed as the sum of the size of the uncompressed header name, plus +# the size of the uncompressed header value, plus an overhead of 32 bytes for +# each field section line. If a peer sends a field section that exceeds this +# size a {@link java.net.ProtocolException ProtocolException} will be raised. +# This applies to all versions of the HTTP protocol. A value of zero or a negative +# value means no limit. If left unspecified, the default value is 393216 bytes +# or 384kB. +# +# Note: This property is currently used by the JDK Reference implementation. It +# is not guaranteed to be examined and used by other implementations. diff -Nru openjdk-17-17.0.12+7/src/java.base/share/conf/security/java.policy openjdk-17-17.0.13+11/src/java.base/share/conf/security/java.policy --- openjdk-17-17.0.12+7/src/java.base/share/conf/security/java.policy 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/conf/security/java.policy 2024-10-10 14:01:59.000000000 +0000 @@ -30,6 +30,8 @@ permission java.util.PropertyPermission "line.separator", "read"; permission java.util.PropertyPermission "java.specification.version", "read"; + permission java.util.PropertyPermission + "java.specification.maintenance.version", "read"; permission java.util.PropertyPermission "java.specification.vendor", "read"; permission java.util.PropertyPermission "java.specification.name", "read"; permission java.util.PropertyPermission diff -Nru openjdk-17-17.0.12+7/src/java.base/share/conf/security/java.security openjdk-17-17.0.13+11/src/java.base/share/conf/security/java.security --- openjdk-17-17.0.12+7/src/java.base/share/conf/security/java.security 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/conf/security/java.security 2024-10-10 14:01:59.000000000 +0000 @@ -737,7 +737,8 @@ # jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048, \ # rsa_pkcs1_sha1, secp224r1 jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, DTLSv1.0, RC4, DES, \ - MD5withRSA, DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL + MD5withRSA, DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \ + ECDH # # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS) @@ -1280,6 +1281,9 @@ # A4FE7C7F15155F3F0AEF7AAA83CF6E06DEB97CA3F909DF920AC1490882D488ED # Distrust after December 31, 2019. # +# ENTRUST_TLS : Distrust TLS Server certificates anchored by +# an Entrust root CA and issued after November 11, 2024. +# # Leading and trailing whitespace surrounding each value are ignored. # Unknown values are ignored. If the property is commented out or set to the # empty String, no policies are enforced. @@ -1291,7 +1295,7 @@ # jdk.certpath.disabledAlgorithms; those restrictions are still enforced even # if this property is not enabled. # -jdk.security.caDistrustPolicies=SYMANTEC_TLS +jdk.security.caDistrustPolicies=SYMANTEC_TLS,ENTRUST_TLS # # FilePermission path canonicalization diff -Nru openjdk-17-17.0.12+7/src/java.base/share/native/libjli/java.c openjdk-17-17.0.13+11/src/java.base/share/native/libjli/java.c --- openjdk-17-17.0.12+7/src/java.base/share/native/libjli/java.c 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/native/libjli/java.c 2024-10-10 14:01:59.000000000 +0000 @@ -908,10 +908,11 @@ if (sizeof(format) - 2 + JLI_StrLen(s) < JLI_StrLen(s)) // s is became corrupted after expanding wildcards return; - def = JLI_MemAlloc(sizeof(format) + size_t defSize = sizeof(format) - 2 /* strlen("%s") */ - + JLI_StrLen(s)); - sprintf(def, format, s); + + JLI_StrLen(s); + def = JLI_MemAlloc(defSize); + snprintf(def, defSize, format, s); AddOption(def, NULL); if (s != orig) JLI_MemFree((char *) s); @@ -1368,8 +1369,9 @@ JLI_StrCCmp(arg, "-oss") == 0 || JLI_StrCCmp(arg, "-ms") == 0 || JLI_StrCCmp(arg, "-mx") == 0) { - char *tmp = JLI_MemAlloc(JLI_StrLen(arg) + 6); - sprintf(tmp, "-X%s", arg + 1); /* skip '-' */ + size_t tmpSize = JLI_StrLen(arg) + 6; + char *tmp = JLI_MemAlloc(tmpSize); + snprintf(tmp, tmpSize, "-X%s", arg + 1); /* skip '-' */ AddOption(tmp, NULL); } else if (JLI_StrCmp(arg, "-checksource") == 0 || JLI_StrCmp(arg, "-cs") == 0 || @@ -1701,8 +1703,9 @@ s = (char *) JLI_WildcardExpandClasspath(s); /* 40 for -Denv.class.path= */ if (JLI_StrLen(s) + 40 > JLI_StrLen(s)) { // Safeguard from overflow - envcp = (char *)JLI_MemAlloc(JLI_StrLen(s) + 40); - sprintf(envcp, "-Denv.class.path=%s", s); + size_t envcpSize = JLI_StrLen(s) + 40; + envcp = (char *)JLI_MemAlloc(envcpSize); + snprintf(envcp, envcpSize, "-Denv.class.path=%s", s); AddOption(envcp, NULL); } } @@ -1714,8 +1717,9 @@ } /* 40 for '-Dapplication.home=' */ - apphome = (char *)JLI_MemAlloc(JLI_StrLen(home) + 40); - sprintf(apphome, "-Dapplication.home=%s", home); + size_t apphomeSize = JLI_StrLen(home) + 40; + apphome = (char *)JLI_MemAlloc(apphomeSize); + snprintf(apphome, apphomeSize, "-Dapplication.home=%s", home); AddOption(apphome, NULL); /* How big is the application's classpath? */ diff -Nru openjdk-17-17.0.12+7/src/java.base/share/native/libzip/zip_util.c openjdk-17-17.0.13+11/src/java.base/share/native/libzip/zip_util.c --- openjdk-17-17.0.12+7/src/java.base/share/native/libzip/zip_util.c 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/share/native/libzip/zip_util.c 2024-10-10 14:01:59.000000000 +0000 @@ -442,7 +442,7 @@ static unsigned int hashN(const char *s, int length) { - int h = 0; + unsigned int h = 0; while (length-- > 0) h = 31*h + *s++; return h; diff -Nru openjdk-17-17.0.12+7/src/java.base/unix/classes/sun/security/provider/NativePRNG.java openjdk-17-17.0.13+11/src/java.base/unix/classes/sun/security/provider/NativePRNG.java --- openjdk-17-17.0.12+7/src/java.base/unix/classes/sun/security/provider/NativePRNG.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/unix/classes/sun/security/provider/NativePRNG.java 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, 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 @@ -202,11 +202,13 @@ } // constructor, called by the JCA framework - public NativePRNG() { - super(); + public NativePRNG(SecureRandomParameters params) { if (INSTANCE == null) { throw new AssertionError("NativePRNG not available"); } + if (params != null) { + throw new IllegalArgumentException("Unsupported params: " + params.getClass()); + } } // set the seed @@ -250,11 +252,13 @@ } // constructor, called by the JCA framework - public Blocking() { - super(); + public Blocking(SecureRandomParameters params) { if (INSTANCE == null) { throw new AssertionError("NativePRNG$Blocking not available"); } + if (params != null) { + throw new IllegalArgumentException("Unsupported params: " + params.getClass()); + } } // set the seed @@ -299,12 +303,14 @@ } // constructor, called by the JCA framework - public NonBlocking() { - super(); + public NonBlocking(SecureRandomParameters params) { if (INSTANCE == null) { throw new AssertionError( "NativePRNG$NonBlocking not available"); } + if (params != null) { + throw new IllegalArgumentException("Unsupported params: " + params.getClass()); + } } // set the seed diff -Nru openjdk-17-17.0.12+7/src/java.base/unix/native/jspawnhelper/jspawnhelper.c openjdk-17-17.0.13+11/src/java.base/unix/native/jspawnhelper/jspawnhelper.c --- openjdk-17-17.0.12+7/src/java.base/unix/native/jspawnhelper/jspawnhelper.c 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/unix/native/jspawnhelper/jspawnhelper.c 2024-10-10 14:01:59.000000000 +0000 @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -49,6 +50,10 @@ #define ERR_PIPE 2 #define ERR_ARGS 3 +#ifndef VERSION_STRING +#error VERSION_STRING must be defined +#endif + void error (int fd, int err) { if (write (fd, &err, sizeof(err)) != sizeof(err)) { /* Not sure what to do here. I have no one to speak to. */ @@ -58,10 +63,12 @@ } void shutItDown() { + fprintf(stdout, "jspawnhelper version %s\n", VERSION_STRING); fprintf(stdout, "This command is not for general use and should "); fprintf(stdout, "only be run as the result of a call to\n"); fprintf(stdout, "ProcessBuilder.start() or Runtime.exec() in a java "); fprintf(stdout, "application\n"); + fflush(stdout); _exit(1); } @@ -145,12 +152,26 @@ #ifdef DEBUG jtregSimulateCrash(0, 4); #endif - r = sscanf (argv[1], "%d:%d:%d", &fdinr, &fdinw, &fdout); + + if (argc != 3) { + fprintf(stdout, "Incorrect number of arguments: %d\n", argc); + shutItDown(); + } + + if (strcmp(argv[1], VERSION_STRING) != 0) { + fprintf(stdout, "Incorrect Java version: %s\n", argv[1]); + shutItDown(); + } + + r = sscanf (argv[2], "%d:%d:%d", &fdinr, &fdinw, &fdout); if (r == 3 && fcntl(fdinr, F_GETFD) != -1 && fcntl(fdinw, F_GETFD) != -1) { fstat(fdinr, &buf); - if (!S_ISFIFO(buf.st_mode)) + if (!S_ISFIFO(buf.st_mode)) { + fprintf(stdout, "Incorrect input pipe\n"); shutItDown(); + } } else { + fprintf(stdout, "Incorrect FD array data: %s\n", argv[2]); shutItDown(); } // Close the writing end of the pipe we use for reading from the parent. diff -Nru openjdk-17-17.0.12+7/src/java.base/unix/native/libjava/ProcessImpl_md.c openjdk-17-17.0.13+11/src/java.base/unix/native/libjava/ProcessImpl_md.c --- openjdk-17-17.0.12+7/src/java.base/unix/native/libjava/ProcessImpl_md.c 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/unix/native/libjava/ProcessImpl_md.c 2024-10-10 14:01:59.000000000 +0000 @@ -300,6 +300,10 @@ #define WTERMSIG(status) ((status)&0x7F) #endif +#ifndef VERSION_STRING +#error VERSION_STRING must be defined +#endif + static const char * getBytes(JNIEnv *env, jbyteArray arr) { @@ -491,7 +495,7 @@ jboolean isCopy; int i, offset, rval, bufsize, magic; char *buf, buf1[(3 * 11) + 3]; // "%d:%d:%d\0" - char *hlpargs[3]; + char *hlpargs[4]; SpawnInfo sp; /* need to tell helper which fd is for receiving the childstuff @@ -500,11 +504,13 @@ snprintf(buf1, sizeof(buf1), "%d:%d:%d", c->childenv[0], c->childenv[1], c->fail[1]); /* NULL-terminated argv array. * argv[0] contains path to jspawnhelper, to follow conventions. - * argv[1] contains the fd string as argument to jspawnhelper + * argv[1] contains the version string as argument to jspawnhelper + * argv[2] contains the fd string as argument to jspawnhelper */ hlpargs[0] = (char*)helperpath; - hlpargs[1] = buf1; - hlpargs[2] = NULL; + hlpargs[1] = VERSION_STRING; + hlpargs[2] = buf1; + hlpargs[3] = NULL; /* Following items are sent down the pipe to the helper * after it is spawned. diff -Nru openjdk-17-17.0.12+7/src/java.base/unix/native/libjava/TimeZone_md.c openjdk-17-17.0.13+11/src/java.base/unix/native/libjava/TimeZone_md.c --- openjdk-17-17.0.12+7/src/java.base/unix/native/libjava/TimeZone_md.c 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/unix/native/libjava/TimeZone_md.c 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2020, 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 @@ -559,14 +559,14 @@ // Ignore daylight saving settings to calculate current time difference localtm.tm_isdst = 0; int gmt_off = (int)(difftime(mktime(&localtm), mktime(&gmt)) / 60.0); - sprintf(buf, (const char *)"GMT%c%02.2d:%02.2d", + snprintf(buf, sizeof(buf), (const char *)"GMT%c%02.2d:%02.2d", gmt_off < 0 ? '-' : '+' , abs(gmt_off / 60), gmt_off % 60); #else if (strftime(offset, 6, "%z", &localtm) != 5) { return strdup("GMT"); } - sprintf(buf, (const char *)"GMT%c%c%c:%c%c", offset[0], offset[1], offset[2], + snprintf(buf, sizeof(buf), (const char *)"GMT%c%c%c:%c%c", offset[0], offset[1], offset[2], offset[3], offset[4]); #endif return strdup(buf); diff -Nru openjdk-17-17.0.12+7/src/java.base/unix/native/libjli/java_md.c openjdk-17-17.0.13+11/src/java.base/unix/native/libjli/java_md.c --- openjdk-17-17.0.12+7/src/java.base/unix/native/libjli/java_md.c 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/unix/native/libjli/java_md.c 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -388,7 +388,7 @@ if (lastslash) *lastslash = '\0'; - sprintf(new_runpath, LD_LIBRARY_PATH "=" + snprintf(new_runpath, new_runpath_size, LD_LIBRARY_PATH "=" "%s:" "%s/lib:" "%s/../lib", diff -Nru openjdk-17-17.0.12+7/src/java.base/unix/native/libnet/NetworkInterface.c openjdk-17-17.0.13+11/src/java.base/unix/native/libnet/NetworkInterface.c --- openjdk-17-17.0.12+7/src/java.base/unix/native/libnet/NetworkInterface.c 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/unix/native/libnet/NetworkInterface.c 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -1271,7 +1271,7 @@ char addr6[40]; struct sockaddr_in6 addr; - sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s", + snprintf(addr6, sizeof(addr6), "%s:%s:%s:%s:%s:%s:%s:%s", addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4], addr6p[5], addr6p[6], addr6p[7]); diff -Nru openjdk-17-17.0.12+7/src/java.base/unix/native/libnet/net_util_md.c openjdk-17-17.0.13+11/src/java.base/unix/native/libnet/net_util_md.c --- openjdk-17-17.0.12+7/src/java.base/unix/native/libnet/net_util_md.c 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/unix/native/libnet/net_util_md.c 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2020, 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 @@ -221,7 +221,7 @@ buf = (char *) malloc(size); if (buf) { jstring s; - sprintf(buf, format, hostname, error_string); + snprintf(buf, size, format, hostname, error_string); s = JNU_NewStringPlatform(env, buf); if (s != NULL) { jobject x = JNU_NewObjectByName(env, diff -Nru openjdk-17-17.0.12+7/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c openjdk-17-17.0.13+11/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c --- openjdk-17-17.0.12+7/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c 2024-10-10 14:01:59.000000000 +0000 @@ -154,9 +154,10 @@ #define STATX_MODE 0x00000002U #endif -#ifndef STATX_ALL -#define STATX_ALL (STATX_BTIME | STATX_BASIC_STATS) -#endif +// +// STATX_ALL is deprecated; use a different name to avoid confusion. +// +#define LOCAL_STATX_ALL (STATX_BASIC_STATS | STATX_BTIME) #ifndef AT_FDCWD #define AT_FDCWD -100 @@ -632,8 +633,19 @@ (*env)->SetLongField(env, attrs, attrs_st_atime_sec, (jlong)buf->stx_atime.tv_sec); (*env)->SetLongField(env, attrs, attrs_st_mtime_sec, (jlong)buf->stx_mtime.tv_sec); (*env)->SetLongField(env, attrs, attrs_st_ctime_sec, (jlong)buf->stx_ctime.tv_sec); - (*env)->SetLongField(env, attrs, attrs_st_birthtime_sec, (jlong)buf->stx_btime.tv_sec); - (*env)->SetLongField(env, attrs, attrs_st_birthtime_nsec, (jlong)buf->stx_btime.tv_nsec); + if ((buf->stx_mask & STATX_BTIME) != 0) { + // Birth time was filled in so use it + (*env)->SetLongField(env, attrs, attrs_st_birthtime_sec, + (jlong)buf->stx_btime.tv_sec); + (*env)->SetLongField(env, attrs, attrs_st_birthtime_nsec, + (jlong)buf->stx_btime.tv_nsec); + } else { + // Birth time was not filled in: fall back to last modification time + (*env)->SetLongField(env, attrs, attrs_st_birthtime_sec, + (jlong)buf->stx_mtime.tv_sec); + (*env)->SetLongField(env, attrs, attrs_st_birthtime_nsec, + (jlong)buf->stx_mtime.tv_nsec); + } (*env)->SetLongField(env, attrs, attrs_st_atime_nsec, (jlong)buf->stx_atime.tv_nsec); (*env)->SetLongField(env, attrs, attrs_st_mtime_nsec, (jlong)buf->stx_mtime.tv_nsec); (*env)->SetLongField(env, attrs, attrs_st_ctime_nsec, (jlong)buf->stx_ctime.tv_nsec); @@ -687,7 +699,7 @@ #if defined(__linux__) struct my_statx statx_buf; int flags = AT_STATX_SYNC_AS_STAT; - unsigned int mask = STATX_ALL; + unsigned int mask = LOCAL_STATX_ALL; if (my_statx_func != NULL) { // Prefer statx over stat64 on Linux if it's available @@ -748,7 +760,7 @@ #if defined(__linux__) struct my_statx statx_buf; int flags = AT_STATX_SYNC_AS_STAT | AT_SYMLINK_NOFOLLOW; - unsigned int mask = STATX_ALL; + unsigned int mask = LOCAL_STATX_ALL; if (my_statx_func != NULL) { // Prefer statx over stat64 on Linux if it's available @@ -779,7 +791,7 @@ #if defined(__linux__) struct my_statx statx_buf; int flags = AT_EMPTY_PATH | AT_STATX_SYNC_AS_STAT; - unsigned int mask = STATX_ALL; + unsigned int mask = LOCAL_STATX_ALL; if (my_statx_func != NULL) { // statx supports FD use via dirfd iff pathname is an empty string and the @@ -812,7 +824,7 @@ #if defined(__linux__) struct my_statx statx_buf; int flags = AT_STATX_SYNC_AS_STAT; - unsigned int mask = STATX_ALL; + unsigned int mask = LOCAL_STATX_ALL; if (my_statx_func != NULL) { // Prefer statx over stat64 on Linux if it's available diff -Nru openjdk-17-17.0.12+7/src/java.base/windows/native/libjava/Console_md.c openjdk-17-17.0.13+11/src/java.base/windows/native/libjava/Console_md.c --- openjdk-17-17.0.12+7/src/java.base/windows/native/libjava/Console_md.c 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/windows/native/libjava/Console_md.c 2024-10-10 14:01:59.000000000 +0000 @@ -56,11 +56,11 @@ char buf[64]; int cp = GetConsoleCP(); if (cp >= 874 && cp <= 950) - sprintf(buf, "ms%d", cp); + snprintf(buf, sizeof(buf), "ms%d", cp); else if (cp == 65001) - sprintf(buf, "UTF-8"); + snprintf(buf, sizeof(buf), "UTF-8"); else - sprintf(buf, "cp%d", cp); + snprintf(buf, sizeof(buf), "cp%d", cp); return JNU_NewStringPlatform(env, buf); } diff -Nru openjdk-17-17.0.12+7/src/java.base/windows/native/libjava/TimeZone_md.c openjdk-17-17.0.13+11/src/java.base/windows/native/libjava/TimeZone_md.c --- openjdk-17-17.0.12+7/src/java.base/windows/native/libjava/TimeZone_md.c 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/windows/native/libjava/TimeZone_md.c 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2018, 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 @@ -122,7 +122,7 @@ /* * Produces custom name "GMT+hh:mm" from the given bias in buffer. */ -static void customZoneName(LONG bias, char *buffer) { +static void customZoneName(LONG bias, char *buffer, size_t bufSize) { LONG gmtOffset; int sign; @@ -134,7 +134,7 @@ sign = 1; } if (gmtOffset != 0) { - sprintf(buffer, "GMT%c%02d:%02d", + snprintf(buffer, bufSize, "GMT%c%02d:%02d", ((sign >= 0) ? '+' : '-'), gmtOffset / 60, gmtOffset % 60); @@ -146,7 +146,7 @@ /* * Gets the current time zone entry in the "Time Zones" registry. */ -static int getWinTimeZone(char *winZoneName) +static int getWinTimeZone(char *winZoneName, size_t winZoneNameBufSize) { DYNAMIC_TIME_ZONE_INFORMATION dtzi; DWORD timeType; @@ -173,7 +173,7 @@ */ if (dtzi.TimeZoneKeyName[0] != 0) { if (dtzi.DynamicDaylightTimeDisabled) { - customZoneName(dtzi.Bias, winZoneName); + customZoneName(dtzi.Bias, winZoneName, winZoneNameBufSize); return VALUE_GMTOFFSET; } wcstombs(winZoneName, dtzi.TimeZoneKeyName, MAX_ZONE_CHAR); @@ -206,7 +206,7 @@ * is disabled. */ if (val == 1) { - customZoneName(dtzi.Bias, winZoneName); + customZoneName(dtzi.Bias, winZoneName, winZoneNameBufSize); (void) RegCloseKey(hKey); return VALUE_GMTOFFSET; } @@ -251,7 +251,7 @@ if (ret == ERROR_SUCCESS) { if (val == 1 && tzi.DaylightDate.wMonth != 0) { (void) RegCloseKey(hKey); - customZoneName(tzi.Bias, winZoneName); + customZoneName(tzi.Bias, winZoneName, winZoneNameBufSize); return VALUE_GMTOFFSET; } } @@ -519,7 +519,7 @@ char *std_timezone = NULL; int result; - result = getWinTimeZone(winZoneName); + result = getWinTimeZone(winZoneName, sizeof(winZoneName)); if (result != VALUE_UNKNOWN) { if (result == VALUE_GMTOFFSET) { @@ -569,6 +569,6 @@ } } - customZoneName(bias, zonename); + customZoneName(bias, zonename, sizeof(zonename)); return _strdup(zonename); } diff -Nru openjdk-17-17.0.12+7/src/java.base/windows/native/libjava/java_props_md.c openjdk-17-17.0.13+11/src/java.base/windows/native/libjava/java_props_md.c --- openjdk-17-17.0.12+7/src/java.base/windows/native/libjava/java_props_md.c 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/windows/native/libjava/java_props_md.c 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -134,18 +134,19 @@ static char* getConsoleEncoding() { - char* buf = malloc(16); + size_t buflen = 16; + char* buf = malloc(buflen); int cp; if (buf == NULL) { return NULL; } cp = GetConsoleCP(); if (cp >= 874 && cp <= 950) - sprintf(buf, "ms%d", cp); + snprintf(buf, buflen, "ms%d", cp); else if (cp == 65001) - sprintf(buf, "UTF-8"); + snprintf(buf, buflen, "UTF-8"); else - sprintf(buf, "cp%d", cp); + snprintf(buf, buflen, "cp%d", cp); return buf; } @@ -575,7 +576,7 @@ sprops.os_name = "Windows (unknown)"; break; } - sprintf(buf, "%d.%d", majorVersion, minorVersion); + snprintf(buf, sizeof(buf), "%d.%d", majorVersion, minorVersion); sprops.os_version = _strdup(buf); #if defined(_M_AMD64) sprops.os_arch = "amd64"; diff -Nru openjdk-17-17.0.12+7/src/java.base/windows/native/libnet/net_util_md.c openjdk-17-17.0.13+11/src/java.base/windows/native/libnet/net_util_md.c --- openjdk-17-17.0.12+7/src/java.base/windows/native/libnet/net_util_md.c 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.base/windows/native/libnet/net_util_md.c 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2020, 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 @@ -189,7 +189,7 @@ if (excP == NULL) { excP = "SocketException"; } - sprintf(exc, "%s%s", JNU_JAVANETPKG, excP); + snprintf(exc, sizeof(exc), "%s%s", JNU_JAVANETPKG, excP); JNU_ThrowByName(env, exc, fullMsg); } diff -Nru openjdk-17-17.0.12+7/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.c openjdk-17-17.0.13+11/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.c --- openjdk-17-17.0.12+7/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.c 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.c 2024-10-10 14:01:59.000000000 +0000 @@ -103,29 +103,29 @@ } -void getDeviceString(char* buffer, int card, int device, int subdevice, - int usePlugHw, int isMidi) { +void getDeviceString(char* buffer, size_t bufferSize, int card, int device, + int subdevice, int usePlugHw, int isMidi) { if (needEnumerateSubdevices(isMidi)) { - sprintf(buffer, "%s:%d,%d,%d", + snprintf(buffer, bufferSize, "%s:%d,%d,%d", usePlugHw ? ALSA_PLUGHARDWARE : ALSA_HARDWARE, card, device, subdevice); } else { - sprintf(buffer, "%s:%d,%d", + snprintf(buffer, bufferSize, "%s:%d,%d", usePlugHw ? ALSA_PLUGHARDWARE : ALSA_HARDWARE, card, device); } } -void getDeviceStringFromDeviceID(char* buffer, UINT32 deviceID, - int usePlugHw, int isMidi) { +void getDeviceStringFromDeviceID(char* buffer, size_t bufferSize, + UINT32 deviceID, int usePlugHw, int isMidi) { int card, device, subdevice; if (deviceID == ALSA_DEFAULT_DEVICE_ID) { strcpy(buffer, ALSA_DEFAULT_DEVICE_NAME); } else { decodeDeviceID(deviceID, &card, &device, &subdevice, isMidi); - getDeviceString(buffer, card, device, subdevice, usePlugHw, isMidi); + getDeviceString(buffer, bufferSize, card, device, subdevice, usePlugHw, isMidi); } } diff -Nru openjdk-17-17.0.12+7/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.h openjdk-17-17.0.13+11/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.h --- openjdk-17-17.0.12+7/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.h 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.h 2024-10-10 14:01:59.000000000 +0000 @@ -73,8 +73,8 @@ void decodeDeviceID(UINT32 deviceID, int* card, int* device, int* subdevice, int isMidi); -void getDeviceStringFromDeviceID(char* buffer, UINT32 deviceID, - int usePlugHw, int isMidi); +void getDeviceStringFromDeviceID(char* buffer, size_t bufferSize, + UINT32 deviceID, int usePlugHw, int isMidi); void getALSAVersion(char* buffer, int len); diff -Nru openjdk-17-17.0.12+7/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.c openjdk-17-17.0.13+11/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.c --- openjdk-17-17.0.12+7/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.c 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.c 2024-10-10 14:01:59.000000000 +0000 @@ -98,7 +98,7 @@ // try to get card info card = snd_rawmidi_info_get_card(rawmidi_info); if (card >= 0) { - sprintf(devname, ALSA_HARDWARE_CARD, card); + snprintf(devname, sizeof(devname), ALSA_HARDWARE_CARD, card); if (snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK) >= 0) { if (snd_ctl_card_info(handle, card_info) >= 0) { defcardinfo = card_info; @@ -121,7 +121,7 @@ if (snd_card_next(&card) >= 0) { TRACE1("Found card %d\n", card); while (doContinue && (card >= 0)) { - sprintf(devname, ALSA_HARDWARE_CARD, card); + snprintf(devname, sizeof(devname), ALSA_HARDWARE_CARD, card); TRACE1("Opening control for alsa rawmidi device \"%s\"...\n", devname); err = snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK); if (err < 0) { @@ -230,7 +230,7 @@ buffer[0]=' '; buffer[1]='['; // buffer[300] is enough to store the actual device string w/o overrun - getDeviceStringFromDeviceID(&buffer[2], deviceID, usePlugHw, ALSA_RAWMIDI); + getDeviceStringFromDeviceID(&buffer[2], sizeof(buffer) - 2, deviceID, usePlugHw, ALSA_RAWMIDI); strncat(buffer, "]", sizeof(buffer) - strlen(buffer) - 1); strncpy(desc->name, (cardinfo != NULL) @@ -392,7 +392,7 @@ // TODO: iterate to get dev ID from index err = getMidiDeviceID(direction, deviceIndex, &deviceID); TRACE1(" openMidiDevice(): deviceID: %d\n", (int) deviceID); - getDeviceStringFromDeviceID(devicename, deviceID, + getDeviceStringFromDeviceID(devicename, sizeof(devicename), deviceID, usePlugHw, ALSA_RAWMIDI); TRACE1(" openMidiDevice(): deviceString: %s\n", devicename); diff -Nru openjdk-17-17.0.12+7/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.c openjdk-17-17.0.13+11/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.c --- openjdk-17-17.0.12+7/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.c 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.c 2024-10-10 14:01:59.000000000 +0000 @@ -75,7 +75,7 @@ // try to get card info card = snd_pcm_info_get_card(pcminfo); if (card >= 0) { - sprintf(devname, ALSA_HARDWARE_CARD, card); + snprintf(devname, sizeof(devname), ALSA_HARDWARE_CARD, card); if (snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK) >= 0) { if (snd_ctl_card_info(handle, cardinfo) >= 0) { defcardinfo = cardinfo; @@ -101,7 +101,7 @@ if (card < 0) { break; } - sprintf(devname, ALSA_HARDWARE_CARD, card); + snprintf(devname, sizeof(devname), ALSA_HARDWARE_CARD, card); TRACE1("Opening alsa device \"%s\"...\n", devname); err = snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK); if (err < 0) { @@ -185,7 +185,7 @@ *desc->deviceID = deviceID; buffer[0]=' '; buffer[1]='['; // buffer[300] is enough to store the actual device string w/o overrun - getDeviceStringFromDeviceID(&buffer[2], deviceID, usePlugHw, ALSA_PCM); + getDeviceStringFromDeviceID(&buffer[2], sizeof(buffer) - 2, deviceID, usePlugHw, ALSA_PCM); strncat(buffer, "]", sizeof(buffer) - strlen(buffer) - 1); strncpy(desc->name, (cardinfo != NULL) @@ -217,7 +217,7 @@ int ret; initAlsaSupport(); - getDeviceStringFromDeviceID(buffer, deviceID, !hardware, ALSA_PCM); + getDeviceStringFromDeviceID(buffer, sizeof(buffer), deviceID, !hardware, ALSA_PCM); TRACE1("Opening ALSA device %s\n", buffer); ret = snd_pcm_open(handle, buffer, diff -Nru openjdk-17-17.0.12+7/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_Ports.c openjdk-17-17.0.13+11/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_Ports.c --- openjdk-17-17.0.12+7/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_Ports.c 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_Ports.c 2024-10-10 14:01:59.000000000 +0000 @@ -85,7 +85,7 @@ mixerCount = 0; if (snd_card_next(&card) >= 0) { while (card >= 0) { - sprintf(devname, ALSA_HARDWARE_CARD, card); + snprintf(devname, sizeof(devname), ALSA_HARDWARE_CARD, card); TRACE1("PORT_GetPortMixerCount: Opening alsa device \"%s\"...\n", devname); err = snd_ctl_open(&handle, devname, 0); if (err < 0) { @@ -115,7 +115,7 @@ TRACE0("> PORT_GetPortMixerDescription\n"); snd_ctl_card_info_malloc(&card_info); - sprintf(devname, ALSA_HARDWARE_CARD, (int) mixerIndex); + snprintf(devname, sizeof(devname), ALSA_HARDWARE_CARD, (int) mixerIndex); TRACE1("Opening alsa device \"%s\"...\n", devname); err = snd_ctl_open(&handle, devname, 0); if (err < 0) { @@ -127,7 +127,7 @@ ERROR2("ERROR: snd_ctl_card_info, card=%d: %s\n", (int) mixerIndex, snd_strerror(err)); } strncpy(description->name, snd_ctl_card_info_get_id(card_info), PORT_STRING_LENGTH - 1); - sprintf(buffer, " [%s]", devname); + snprintf(buffer, sizeof(buffer), " [%s]", devname); strncat(description->name, buffer, PORT_STRING_LENGTH - 1 - strlen(description->name)); strncpy(description->vendor, "ALSA (http://www.alsa-project.org)", PORT_STRING_LENGTH - 1); strncpy(description->description, snd_ctl_card_info_get_name(card_info), PORT_STRING_LENGTH - 1); @@ -149,7 +149,7 @@ PortMixer* handle; TRACE0("> PORT_Open\n"); - sprintf(devname, ALSA_HARDWARE_CARD, (int) mixerIndex); + snprintf(devname, sizeof(devname), ALSA_HARDWARE_CARD, (int) mixerIndex); if ((err = snd_mixer_open(&mixer_handle, 0)) < 0) { ERROR2("Mixer %s open error: %s", devname, snd_strerror(err)); return NULL; diff -Nru openjdk-17-17.0.12+7/src/java.desktop/macosx/classes/sun/font/CStrike.java openjdk-17-17.0.13+11/src/java.desktop/macosx/classes/sun/font/CStrike.java --- openjdk-17-17.0.12+7/src/java.desktop/macosx/classes/sun/font/CStrike.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/macosx/classes/sun/font/CStrike.java 2024-10-10 14:01:59.000000000 +0000 @@ -201,7 +201,7 @@ getGlyphImageBounds(glyphCode, pt.x, pt.y, floatRect); if (floatRect.width == 0 && floatRect.height == 0) { - result.setRect(0, 0, -1, -1); + result.setRect(0, 0, 0, 0); return; } diff -Nru openjdk-17-17.0.12+7/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java openjdk-17-17.0.13+11/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java --- openjdk-17-17.0.12+7/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2021, 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 @@ -35,10 +35,11 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.lang.annotation.Native; -import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Set; import java.util.concurrent.Callable; import java.util.Arrays; @@ -64,7 +65,6 @@ import javax.swing.JList; import javax.swing.JTree; import javax.swing.KeyStroke; -import javax.swing.tree.TreePath; import sun.awt.AWTAccessor; import sun.lwawt.LWWindowPeer; @@ -742,21 +742,6 @@ return new Object[]{childrenAndRoles.get(whichChildren * 2), childrenAndRoles.get((whichChildren * 2) + 1)}; } - private static Accessible createAccessibleTreeNode(JTree t, TreePath p) { - Accessible a = null; - - try { - Class accessibleJTreeNodeClass = Class.forName("javax.swing.JTree$AccessibleJTree$AccessibleJTreeNode"); - Constructor constructor = accessibleJTreeNodeClass.getConstructor(t.getAccessibleContext().getClass(), JTree.class, TreePath.class, Accessible.class); - constructor.setAccessible(true); - a = ((Accessible) constructor.newInstance(t.getAccessibleContext(), t, p, null)); - } catch (Exception e) { - e.printStackTrace(); - } - - return a; - } - // This method is called from the native // Each child takes up three entries in the array: one for itself, one for its role, and one for the recursion level private static Object[] getChildrenAndRolesRecursive(final Accessible a, final Component c, final int whichChildren, final boolean allowIgnored, final int level) { @@ -764,62 +749,21 @@ return invokeAndWait(new Callable() { public Object[] call() throws Exception { ArrayList allChildren = new ArrayList(); - - Accessible at = null; - if (a instanceof CAccessible) { - at = CAccessible.getSwingAccessible(a); - } else { - at = a; - } - - if (at instanceof JTree) { - JTree tree = ((JTree) at); - - if (whichChildren == JAVA_AX_ALL_CHILDREN) { - int count = tree.getRowCount(); - for (int i = 0; i < count; i++) { - TreePath path = tree.getPathForRow(i); - Accessible an = createAccessibleTreeNode(tree, path); - if (an != null) { - AccessibleContext ac = an.getAccessibleContext(); - if (ac != null) { - allChildren.add(an); - allChildren.add(ac.getAccessibleRole());; - allChildren.add(String.valueOf((tree.isRootVisible() ? path.getPathCount() : path.getPathCount() - 1))); - } - } - } - } - - if (whichChildren == JAVA_AX_SELECTED_CHILDREN) { - int count = tree.getSelectionCount(); - for (int i = 0; i < count; i++) { - TreePath path = tree.getSelectionPaths()[i]; - Accessible an = createAccessibleTreeNode(tree, path); - if (an != null) { - AccessibleContext ac = an.getAccessibleContext(); - if (ac != null) { - allChildren.add(an); - allChildren.add(ac.getAccessibleRole()); - allChildren.add(String.valueOf((tree.isRootVisible() ? path.getPathCount() : path.getPathCount() - 1))); - } - } - } - } - - return allChildren.toArray(); - } - ArrayList currentLevelChildren = new ArrayList(); ArrayList parentStack = new ArrayList(); + HashMap> childrenOfParent = new HashMap<>(); parentStack.add(a); ArrayList indexses = new ArrayList(); Integer index = 0; int currentLevel = level; while (!parentStack.isEmpty()) { Accessible p = parentStack.get(parentStack.size() - 1); - - currentLevelChildren.addAll(Arrays.asList(getChildrenAndRolesImpl(p, c, JAVA_AX_ALL_CHILDREN, allowIgnored, ChildrenOperations.COMMON))); + if (!childrenOfParent.containsKey(p)) { + childrenOfParent.put(p, Arrays.asList(getChildrenAndRolesImpl(p, + c, JAVA_AX_ALL_CHILDREN, allowIgnored, + ChildrenOperations.COMMON))); + } + currentLevelChildren.addAll(childrenOfParent.get(p)); if ((currentLevelChildren.size() == 0) || (index >= currentLevelChildren.size())) { if (!parentStack.isEmpty()) parentStack.remove(parentStack.size() - 1); if (!indexses.isEmpty()) index = indexses.remove(indexses.size() - 1); @@ -862,7 +806,6 @@ currentLevel += 1; continue; } - } return allChildren.toArray(); diff -Nru openjdk-17-17.0.12+7/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java openjdk-17-17.0.13+11/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java --- openjdk-17-17.0.12+7/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -454,7 +454,7 @@ desktopProperties.put("awt.multiClickInterval", getMultiClickTime()); // These DnD properties must be set, otherwise Swing ends up spewing NPEs - // all over the place. The values came straight off of MToolkit. + // all over the place. The values came straight off of XToolkit. desktopProperties.put("DnD.Autoscroll.initialDelay", Integer.valueOf(50)); desktopProperties.put("DnD.Autoscroll.interval", Integer.valueOf(50)); desktopProperties.put("DnD.Autoscroll.cursorHysteresis", Integer.valueOf(5)); diff -Nru openjdk-17-17.0.12+7/src/java.desktop/macosx/native/libawt_lwawt/awt/CPrinterJob.m openjdk-17-17.0.13+11/src/java.desktop/macosx/native/libawt_lwawt/awt/CPrinterJob.m --- openjdk-17-17.0.12+7/src/java.desktop/macosx/native/libawt_lwawt/awt/CPrinterJob.m 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/macosx/native/libawt_lwawt/awt/CPrinterJob.m 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -63,7 +63,7 @@ GET_CPRINTERDIALOG_CLASS_RETURN(ret); \ GET_FIELD_RETURN(sjm_printerJob, sjc_CPrinterDialog, "fPrinterJob", "Lsun/lwawt/macosx/CPrinterJob;", ret); -static NSPrintInfo* createDefaultNSPrintInfo(); +static NSPrintInfo* createDefaultNSPrintInfo(JNIEnv* env, jstring printer); static void makeBestFit(NSPrintInfo* src); diff -Nru openjdk-17-17.0.12+7/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineAccessibility.h openjdk-17-17.0.13+11/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineAccessibility.h --- openjdk-17-17.0.12+7/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineAccessibility.h 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineAccessibility.h 2024-10-10 14:01:59.000000000 +0000 @@ -1,6 +1,6 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2021, JetBrains s.r.o.. All rights reserved. + * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, JetBrains s.r.o.. All rights reserved. * 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,7 +29,12 @@ // This is a tree representation. See: https://developer.apple.com/documentation/appkit/nsoutlineview @interface OutlineAccessibility : ListAccessibility - +{ + NSMutableArray> *rowCache; + BOOL rowCacheValid; + NSMutableArray> *selectedRowCache; + BOOL selectedRowCacheValid; +} @property(readonly) BOOL isTreeRootVisible; @end diff -Nru openjdk-17-17.0.12+7/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineAccessibility.m openjdk-17-17.0.13+11/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineAccessibility.m --- openjdk-17-17.0.12+7/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineAccessibility.m 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineAccessibility.m 2024-10-10 14:01:59.000000000 +0000 @@ -1,6 +1,6 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2021, JetBrains s.r.o.. All rights reserved. + * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, JetBrains s.r.o.. All rights reserved. * 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,4 +55,88 @@ return [[super accessibilityLabel] isEqualToString:@"list"] ? @"tree" : [super accessibilityLabel]; } +- (nullable NSArray> *)accessibilityRows +{ + return [self accessibilityChildren]; +} + +- (nullable NSArray> *)accessibilitySelectedRows +{ + return [self accessibilitySelectedChildren]; +} + +- (nullable NSArray> *)accessibilityChildren +{ + if (![self isCacheValid]) { + NSArray *t = [super accessibilityChildren]; + if (t != nil) { + rowCache = [[NSMutableArray arrayWithArray:t] retain]; + } else { + rowCache = nil; + } + rowCacheValid = YES; + } + return rowCache; +} + +- (nullable NSArray> *)accessibilitySelectedChildren +{ + if (!selectedRowCacheValid) { + NSArray *t = [super accessibilitySelectedChildren]; + if (t != nil) { + selectedRowCache = [[NSMutableArray arrayWithArray:t] retain]; + } else { + selectedRowCache = nil; + } + selectedRowCacheValid = YES; + } + return selectedRowCache; +} + +- (BOOL)isCacheValid +{ + if (rowCacheValid && [[self parent] respondsToSelector:NSSelectorFromString(@"isCacheValid")]) { + return [[self parent] isCacheValid]; + } + return rowCacheValid; +} + +- (void)invalidateCache +{ + rowCacheValid = NO; +} + +- (void)invalidateSelectionCache +{ + selectedRowCacheValid = NO; +} + +- (void)postSelectionChanged +{ + AWT_ASSERT_APPKIT_THREAD; + [self invalidateSelectionCache]; + [super postSelectionChanged]; +} + +- (void)postTreeNodeCollapsed +{ + AWT_ASSERT_APPKIT_THREAD; + [self invalidateCache]; + [super postTreeNodeCollapsed]; +} + +- (void)postTreeNodeExpanded +{ + AWT_ASSERT_APPKIT_THREAD; + [self invalidateCache]; + [super postTreeNodeExpanded]; +} + +- (void)postSelectedCellsChanged +{ + AWT_ASSERT_APPKIT_THREAD; + [self invalidateSelectionCache]; + [super postSelectedCellsChanged]; +} + @end diff -Nru openjdk-17-17.0.12+7/src/java.desktop/macosx/native/libawt_lwawt/font/AWTStrike.m openjdk-17-17.0.13+11/src/java.desktop/macosx/native/libawt_lwawt/font/AWTStrike.m --- openjdk-17-17.0.12+7/src/java.desktop/macosx/native/libawt_lwawt/font/AWTStrike.m 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/macosx/native/libawt_lwawt/font/AWTStrike.m 2024-10-10 14:01:59.000000000 +0000 @@ -102,7 +102,7 @@ #define AWT_FONT_CLEANUP_FINISH \ if (_fontThrowJavaException == YES) { \ char s[512]; \ - sprintf(s, "%s-%s:%d", __FILE__, __FUNCTION__, __LINE__); \ + snprintf(s, sizeof(s), "%s-%s:%d", __FILE__, __FUNCTION__, __LINE__); \ JNU_ThrowByName(env, "java/lang/RuntimeException", s); \ } diff -Nru openjdk-17-17.0.12+7/src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m openjdk-17-17.0.13+11/src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m --- openjdk-17-17.0.12+7/src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m 2024-10-10 14:01:59.000000000 +0000 @@ -1020,4 +1020,20 @@ CTFontGetAdvancesForGlyphs(font, kCTFontDefaultOrientation, glyphs, advances, count); } } -} \ No newline at end of file + int MAX_SIZE = 1 << 30; + if (bboxes) { + for (int i = 0; i < count; i++) { + if (bboxes[i].origin.x > (double)MAX_SIZE) bboxes[i].origin.x = 0; + if (bboxes[i].origin.y > (double)MAX_SIZE) bboxes[i].origin.y = 0; + if (bboxes[i].size.width > (double)MAX_SIZE) bboxes[i].size.width = 0; + if (bboxes[i].size.height > (double)MAX_SIZE) bboxes[i].size.height = 0; + } + } + if (advances) { + for (int i = 0; i < count; i++) { + if (advances[i].width > (double)MAX_SIZE) advances[i].width = 0; + if (advances[i].height > (double)MAX_SIZE) advances[i].height = 0; + } + } +} + diff -Nru openjdk-17-17.0.12+7/src/java.desktop/macosx/native/libjsound/PLATFORM_API_MacOSX_Ports.cpp openjdk-17-17.0.13+11/src/java.desktop/macosx/native/libjsound/PLATFORM_API_MacOSX_Ports.cpp --- openjdk-17-17.0.12+7/src/java.desktop/macosx/native/libjsound/PLATFORM_API_MacOSX_Ports.cpp 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/macosx/native/libjsound/PLATFORM_API_MacOSX_Ports.cpp 2024-10-10 14:01:59.000000000 +0000 @@ -635,7 +635,7 @@ if (channelName == NULL) { return; } - sprintf(channelName, "Ch %d", ch); + snprintf(channelName, 16, "Ch %d", ch); } void* jControls[2]; diff -Nru openjdk-17-17.0.12+7/src/java.desktop/share/classes/java/awt/Robot.java openjdk-17-17.0.13+11/src/java.desktop/share/classes/java/awt/Robot.java --- openjdk-17-17.0.12+7/src/java.desktop/share/classes/java/awt/Robot.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/share/classes/java/awt/Robot.java 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, 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 @@ -68,6 +68,43 @@ *

    * Applications that use Robot for purposes other than self-testing should * handle these error conditions gracefully. + *

    + * Platforms and desktop environments may impose restrictions or limitations + * on the access required to implement all functionality in the Robot class. + * For example: + *

      + *
    • preventing access to the contents of any part of a desktop + * or Window on the desktop that is not owned by the running application.
    • + *
    • treating window decorations as non-owned content.
    • + *
    • ignoring or limiting specific requests to manipulate windows.
    • + *
    • ignoring or limiting specific requests for Robot generated (synthesized) + * events related to keyboard and mouse etc.
    • + *
    • requiring specific or global permissions to any access to window + * contents, even application owned content,or to perform even limited + * synthesizing of events.
    • + *
    + * + * The Robot API specification requires that approvals for these be granted + * for full operation. + * If they are not granted, the API will be degraded as discussed here. + * Relevant specific API methods may document more specific limitations + * and requirements. + * Depending on the policies of the desktop environment, + * the approvals mentioned above may: + *
      + *
    • be required every time
    • + *
    • or persistent for the lifetime of an application,
    • + *
    • or persistent across multiple user desktop sessions
    • + *
    • be fine-grained permissions
    • + *
    • be associated with a specific binary application, + * or a class of binary applications.
    • + *
    + * + * When such approvals need to given interactively, it may impede the normal + * operation of the application until approved, and if approval is denied + * or not possible, or cannot be made persistent then it will degrade + * the functionality of this class and in turn any part of the operation + * of the application which is dependent on it. * * @author Robi Khan * @since 1.3 @@ -189,6 +226,11 @@ /** * Moves mouse pointer to given screen coordinates. + *

    + * The mouse pointer may not visually move on some platforms, + * while the subsequent mousePress and mouseRelease can be + * delivered to the correct location + * * @param x X position * @param y Y position */ @@ -383,8 +425,22 @@ /** * Returns the color of a pixel at the given screen coordinates. + *

    + * If the desktop environment requires that permissions be granted + * to capture screen content, and the required permissions are not granted, + * then a {@code SecurityException} may be thrown, + * or the content of the returned {@code Color} is undefined. + *

    + * @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 x X position of pixel * @param y Y position of pixel + * @throws SecurityException if {@code readDisplayPixels} permission + * is not granted, or access to the screen is denied + * by the desktop environment * @return Color of the pixel */ public synchronized Color getPixelColor(int x, int y) { @@ -395,12 +451,25 @@ } /** - * Creates an image containing pixels read from the screen. This image does - * not include the mouse cursor. + * Creates an image containing pixels read from the screen. + *

    + * If the desktop environment requires that permissions be granted + * to capture screen content, and the required permissions are not granted, + * then a {@code SecurityException} may be thrown, + * or the contents of the returned {@code BufferedImage} are undefined. + *

    + * @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 are not greater than zero - * @throws SecurityException if {@code readDisplayPixels} permission is not granted + * @throws IllegalArgumentException if {@code screenRect} width and height + * are not greater than zero + * @throws SecurityException if {@code readDisplayPixels} permission + * is not granted, or access to the screen is denied + * by the desktop environment * @see SecurityManager#checkPermission * @see AWTPermission */ @@ -410,7 +479,6 @@ /** * Creates an image containing pixels read from the screen. - * This image does not include the mouse cursor. * This method can be used in case there is a scaling transform * from user space to screen (device) space. * Typically this means that the display is a high resolution screen, @@ -443,8 +511,11 @@ * } * @param screenRect Rect to capture in screen coordinates * @return The captured image - * @throws IllegalArgumentException if {@code screenRect} width and height are not greater than zero - * @throws SecurityException if {@code readDisplayPixels} permission is not granted + * @throws IllegalArgumentException if {@code screenRect} width and height + * are not greater than zero + * @throws SecurityException if {@code readDisplayPixels} permission + * is not granted, or access to the screen is denied + * by the desktop environment * @see SecurityManager#checkPermission * @see AWTPermission * diff -Nru openjdk-17-17.0.12+7/src/java.desktop/share/classes/javax/swing/JEditorPane.java openjdk-17-17.0.13+11/src/java.desktop/share/classes/javax/swing/JEditorPane.java --- openjdk-17-17.0.12+7/src/java.desktop/share/classes/javax/swing/JEditorPane.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/share/classes/javax/swing/JEditorPane.java 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, 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 @@ -618,35 +618,37 @@ String charset = (String) getClientProperty("charset"); try(Reader r = (charset != null) ? new InputStreamReader(in, charset) : new InputStreamReader(in)) { - kit.read(r, doc, 0); - } catch (BadLocationException e) { - throw new IOException(e.getMessage()); - } catch (ChangedCharSetException changedCharSetException) { - String charSetSpec = changedCharSetException.getCharSetSpec(); - if (changedCharSetException.keyEqualsCharSet()) { - putClientProperty("charset", charSetSpec); - } else { - setCharsetFromContentTypeParameters(charSetSpec); - } try { - in.reset(); - } catch (IOException exception) { - //mark was invalidated - in.close(); - URL url = (URL)doc.getProperty(Document.StreamDescriptionProperty); - if (url != null) { - URLConnection conn = url.openConnection(); - in = conn.getInputStream(); + kit.read(r, doc, 0); + } catch (BadLocationException e) { + throw new IOException(e.getMessage()); + } catch (ChangedCharSetException changedCharSetException) { + String charSetSpec = changedCharSetException.getCharSetSpec(); + if (changedCharSetException.keyEqualsCharSet()) { + putClientProperty("charset", charSetSpec); } else { - //there is nothing we can do to recover stream - throw changedCharSetException; + setCharsetFromContentTypeParameters(charSetSpec); + } + try { + in.reset(); + } catch (IOException exception) { + //mark was invalidated + in.close(); + URL url = (URL)doc.getProperty(Document.StreamDescriptionProperty); + if (url != null) { + URLConnection conn = url.openConnection(); + in = conn.getInputStream(); + } else { + //there is nothing we can do to recover stream + throw changedCharSetException; + } } + try { + doc.remove(0, doc.getLength()); + } catch (BadLocationException e) {} + doc.putProperty("IgnoreCharsetDirective", Boolean.valueOf(true)); + read(in, doc); } - try { - doc.remove(0, doc.getLength()); - } catch (BadLocationException e) {} - doc.putProperty("IgnoreCharsetDirective", Boolean.valueOf(true)); - read(in, doc); } } diff -Nru openjdk-17-17.0.12+7/src/java.desktop/share/classes/javax/swing/JPopupMenu.java openjdk-17-17.0.13+11/src/java.desktop/share/classes/javax/swing/JPopupMenu.java --- openjdk-17-17.0.12+7/src/java.desktop/share/classes/javax/swing/JPopupMenu.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/share/classes/javax/swing/JPopupMenu.java 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, 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 @@ -37,6 +37,7 @@ import java.awt.Point; import java.awt.Rectangle; import java.awt.Toolkit; +import java.awt.Window; import java.awt.event.FocusEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; @@ -757,6 +758,16 @@ } } + private Window getMenuInvoker() { + if (invoker instanceof Window menuInvoker) { + return menuInvoker; + } else { + return invoker == null + ? null + : SwingUtilities.getWindowAncestor(invoker); + } + } + /** * Sets the visibility of the popup menu. * @@ -798,14 +809,24 @@ } } - if(b) { + if (b) { firePopupMenuWillBecomeVisible(); + + if (Toolkit.getDefaultToolkit() instanceof SunToolkit sunToolkit) { + sunToolkit.dismissPopupOnFocusLostIfNeeded(getMenuInvoker()); + } + showPopup(); firePropertyChange("visible", Boolean.FALSE, Boolean.TRUE); - } else if(popup != null) { + } else if (popup != null) { firePopupMenuWillBecomeInvisible(); + + if (Toolkit.getDefaultToolkit() instanceof SunToolkit sunToolkit) { + sunToolkit.dismissPopupOnFocusLostIfNeededCleanUp(getMenuInvoker()); + } + popup.hide(); popup = null; firePropertyChange("visible", Boolean.TRUE, Boolean.FALSE); diff -Nru openjdk-17-17.0.12+7/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java openjdk-17-17.0.13+11/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java --- openjdk-17-17.0.12+7/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, 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 @@ -98,10 +98,13 @@ * This method is used to interrupt file loading thread. */ public void invalidateFileCache() { - if (filesLoader != null) { - filesLoader.loadThread.interrupt(); - filesLoader.cancelRunnables(); - filesLoader = null; + synchronized (this) { + if (filesLoader != null) { + filesLoader.loadThread.interrupt(); + filesLoader = null; + // Increment fetch ID to invalidate pending DoChangeContents + fetchID.incrementAndGet(); + } } } @@ -156,14 +159,15 @@ if (currentDirectory == null) { return; } - if (filesLoader != null) { - filesLoader.loadThread.interrupt(); - filesLoader.cancelRunnables(); - } + synchronized (this) { + if (filesLoader != null) { + filesLoader.loadThread.interrupt(); + } - int fid = fetchID.incrementAndGet(); - setBusy(true, fid); - filesLoader = new FilesLoader(currentDirectory, fid); + int fid = fetchID.incrementAndGet(); + setBusy(true, fid); + filesLoader = new FilesLoader(currentDirectory, fid); + } } /** @@ -276,7 +280,6 @@ private final boolean fileSelectionEnabled; private final int fid; private final File currentDirectory; - private volatile DoChangeContents runnable; private final Thread loadThread; private FilesLoader(File currentDirectory, int fid) { @@ -297,22 +300,20 @@ } private void run0() { - FileSystemView fileSystem = fileSystemView; - if (loadThread.isInterrupted()) { return; } - File[] list = fileSystem.getFiles(currentDirectory, useFileHiding); + File[] list = fileSystemView.getFiles(currentDirectory, useFileHiding); if (loadThread.isInterrupted()) { return; } final Vector newFileCache = new Vector(); - Vector newFiles = new Vector(); + final Vector newFiles = new Vector(); - // run through the file list, add directories and selectable files to fileCache + // Run through the file list, add directories and selectable files to fileCache // Note that this block must be OUTSIDE of Invoker thread because of // deadlock possibility with custom synchronized FileSystemView for (File file : list) { @@ -339,60 +340,68 @@ // To avoid loads of synchronizations with Invoker and improve performance we // execute the whole block on the COM thread - runnable = ShellFolder.invoke(new Callable() { + DoChangeContents runnable = ShellFolder.invoke(new Callable() { public DoChangeContents call() { - int newSize = newFileCache.size(); - int oldSize = fileCache.size(); - - if (newSize > oldSize) { - //see if interval is added - int start = oldSize; - int end = newSize; - for (int i = 0; i < oldSize; i++) { - if (!newFileCache.get(i).equals(fileCache.get(i))) { - start = i; - for (int j = i; j < newSize; j++) { - if (newFileCache.get(j).equals(fileCache.get(i))) { - end = j; - break; + synchronized (fileCache) { + int newSize = newFileCache.size(); + int oldSize = fileCache.size(); + + if (newSize > oldSize) { + //see if interval is added + int start = oldSize; + int end = newSize; + for (int i = 0; i < oldSize; i++) { + if (!newFileCache.get(i).equals(fileCache.get(i))) { + start = i; + for (int j = i; j < newSize; j++) { + if (newFileCache.get(j).equals(fileCache.get(i))) { + end = j; + break; + } } + break; } - break; } - } - if (start >= 0 && end > start - && newFileCache.subList(end, newSize).equals(fileCache.subList(start, oldSize))) { - if (loadThread.isInterrupted()) { - return null; + + if (start >= 0 && end > start + && newFileCache.subList(end, newSize) + .equals(fileCache.subList(start, oldSize))) { + if (loadThread.isInterrupted()) { + return null; + } + return new DoChangeContents(newFileCache.subList(start, end), + start, null, 0, fid); } - return new DoChangeContents(newFileCache.subList(start, end), start, null, 0, fid); - } - } else if (newSize < oldSize) { - //see if interval is removed - int start = -1; - int end = -1; - for (int i = 0; i < newSize; i++) { - if (!newFileCache.get(i).equals(fileCache.get(i))) { - start = i; - end = i + oldSize - newSize; - break; + } else if (newSize < oldSize) { + //see if interval is removed + int start = -1; + int end = -1; + for (int i = 0; i < newSize; i++) { + if (!newFileCache.get(i).equals(fileCache.get(i))) { + start = i; + end = i + oldSize - newSize; + break; + } + } + + if (start >= 0 && end > start + && fileCache.subList(end, oldSize) + .equals(newFileCache.subList(start, newSize))) { + if (loadThread.isInterrupted()) { + return null; + } + return new DoChangeContents(null, 0, + new Vector<>(fileCache.subList(start, end)), start, fid); } } - if (start >= 0 && end > start - && fileCache.subList(end, oldSize).equals(newFileCache.subList(start, newSize))) { + if (!fileCache.equals(newFileCache)) { if (loadThread.isInterrupted()) { return null; } - return new DoChangeContents(null, 0, new Vector<>(fileCache.subList(start, end)), start, fid); - } - } - if (!fileCache.equals(newFileCache)) { - if (loadThread.isInterrupted()) { - cancelRunnables(); + return new DoChangeContents(newFileCache, 0, fileCache, 0, fid); } - return new DoChangeContents(newFileCache, 0, fileCache, 0, fid); + return null; } - return null; } }); @@ -400,12 +409,6 @@ SwingUtilities.invokeLater(runnable); } } - - private void cancelRunnables() { - if (runnable != null) { - runnable.cancel(); - } - } } @@ -514,13 +517,13 @@ private final class DoChangeContents implements Runnable { private final List addFiles; private final List remFiles; - private boolean doFire = true; private final int fid; - private int addStart = 0; - private int remStart = 0; + private final int addStart; + private final int remStart; - DoChangeContents(List addFiles, int addStart, List remFiles, - int remStart, int fid) { + private DoChangeContents(List addFiles, int addStart, + List remFiles, int remStart, + int fid) { this.addFiles = addFiles; this.addStart = addStart; this.remFiles = remFiles; @@ -528,31 +531,32 @@ this.fid = fid; } - synchronized void cancel() { - doFire = false; - } + @Override + public void run() { + if (fetchID.get() != fid) { + return; + } - public synchronized void run() { - if (fetchID.get() == fid && doFire) { - int remSize = (remFiles == null) ? 0 : remFiles.size(); - int addSize = (addFiles == null) ? 0 : addFiles.size(); - synchronized(fileCache) { - if (remSize > 0) { - fileCache.removeAll(remFiles); - } - if (addSize > 0) { - fileCache.addAll(addStart, addFiles); - } - files = null; - directories = null; + final int remSize = (remFiles == null) ? 0 : remFiles.size(); + final int addSize = (addFiles == null) ? 0 : addFiles.size(); + final int cacheSize; + synchronized (fileCache) { + if (remSize > 0) { + fileCache.removeAll(remFiles); } - if (remSize > 0 && addSize == 0) { - fireIntervalRemoved(BasicDirectoryModel.this, remStart, remStart + remSize - 1); - } else if (addSize > 0 && remSize == 0 && addStart + addSize <= fileCache.size()) { - fireIntervalAdded(BasicDirectoryModel.this, addStart, addStart + addSize - 1); - } else { - fireContentsChanged(); + if (addSize > 0) { + fileCache.addAll(addStart, addFiles); } + files = null; + directories = null; + cacheSize = fileCache.size(); + } + if (remSize > 0 && addSize == 0) { + fireIntervalRemoved(BasicDirectoryModel.this, remStart, remStart + remSize - 1); + } else if (addSize > 0 && remSize == 0 && addStart + addSize <= cacheSize) { + fireIntervalAdded(BasicDirectoryModel.this, addStart, addStart + addSize - 1); + } else { + fireContentsChanged(); } } } diff -Nru openjdk-17-17.0.12+7/src/java.desktop/share/classes/javax/swing/text/html/CSS.java openjdk-17-17.0.13+11/src/java.desktop/share/classes/javax/swing/text/html/CSS.java --- openjdk-17-17.0.12+7/src/java.desktop/share/classes/javax/swing/text/html/CSS.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/share/classes/javax/swing/text/html/CSS.java 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, 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 @@ -841,6 +841,22 @@ return r != null ? r : conv.parseCssValue(key.getDefaultValue()); } + static Object mergeTextDecoration(String value) { + if (value.startsWith("none")) { + return null; + } + + boolean underline = value.contains("underline"); + boolean strikeThrough = value.contains("line-through"); + if (!underline && !strikeThrough) { + return null; + } + String newValue = underline && strikeThrough + ? "underline,line-through" + : (underline ? "underline" : "line-through"); + return new StringValue().parseCssValue(newValue); + } + /** * Maps from a StyleConstants to a CSS Attribute. */ diff -Nru openjdk-17-17.0.12+7/src/java.desktop/share/classes/javax/swing/text/html/HTMLDocument.java openjdk-17-17.0.13+11/src/java.desktop/share/classes/javax/swing/text/html/HTMLDocument.java --- openjdk-17-17.0.12+7/src/java.desktop/share/classes/javax/swing/text/html/HTMLDocument.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/share/classes/javax/swing/text/html/HTMLDocument.java 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, 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 @@ -25,15 +25,43 @@ package javax.swing.text.html; import java.awt.font.TextAttribute; -import java.util.*; -import java.net.URL; +import java.io.IOException; +import java.io.StringReader; import java.net.MalformedURLException; -import java.io.*; -import javax.swing.*; -import javax.swing.event.*; -import javax.swing.text.*; -import javax.swing.undo.*; +import java.net.URL; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Stack; +import java.util.Vector; + +import javax.swing.ButtonGroup; +import javax.swing.DefaultButtonModel; +import javax.swing.DefaultComboBoxModel; +import javax.swing.DefaultListModel; +import javax.swing.JToggleButton; +import javax.swing.ListSelectionModel; +import javax.swing.event.DocumentEvent; +import javax.swing.event.EventListenerList; +import javax.swing.event.UndoableEditEvent; +import javax.swing.text.AbstractDocument; +import javax.swing.text.AttributeSet; +import javax.swing.text.BadLocationException; +import javax.swing.text.DefaultEditorKit; +import javax.swing.text.DefaultStyledDocument; +import javax.swing.text.Document; +import javax.swing.text.Element; +import javax.swing.text.ElementIterator; +import javax.swing.text.GapContent; +import javax.swing.text.MutableAttributeSet; +import javax.swing.text.PlainDocument; +import javax.swing.text.SimpleAttributeSet; +import javax.swing.text.StyleConstants; +import javax.swing.undo.UndoableEdit; + import sun.swing.SwingUtilities2; + import static sun.swing.SwingUtilities2.IMPLIED_CR; /** @@ -2473,9 +2501,9 @@ tagMap.put(HTML.Tag.SCRIPT, ha); tagMap.put(HTML.Tag.SELECT, fa); tagMap.put(HTML.Tag.SMALL, ca); - tagMap.put(HTML.Tag.SPAN, ca); + tagMap.put(HTML.Tag.SPAN, new ConvertSpanAction()); tagMap.put(HTML.Tag.STRIKE, conv); - tagMap.put(HTML.Tag.S, ca); + tagMap.put(HTML.Tag.S, conv); tagMap.put(HTML.Tag.STRONG, ca); tagMap.put(HTML.Tag.STYLE, new StyleAction()); tagMap.put(HTML.Tag.SUB, conv); @@ -3398,11 +3426,43 @@ if (styleAttributes != null) { charAttr.addAttributes(styleAttributes); } + + convertAttributes(t, attr); } public void end(HTML.Tag t) { popCharacterStyle(); } + + /** + * Converts HTML tags to CSS attributes. + * @param t the current HTML tag + * @param attr the attributes of the HTML tag + */ + void convertAttributes(HTML.Tag t, MutableAttributeSet attr) { + } + } + + final class ConvertSpanAction extends CharacterAction { + @Override + void convertAttributes(HTML.Tag t, MutableAttributeSet attr) { + Object newDecoration = attr.getAttribute(CSS.Attribute.TEXT_DECORATION); + Object previousDecoration = + charAttrStack.peek() + .getAttribute(CSS.Attribute.TEXT_DECORATION); + + if (newDecoration != null + && !"none".equals(newDecoration.toString()) + && previousDecoration != null + && !"none".equals(previousDecoration.toString())) { + StyleSheet sheet = getStyleSheet(); + sheet.addCSSAttribute(charAttr, + CSS.Attribute.TEXT_DECORATION, + CSS.mergeTextDecoration(newDecoration + "," + + previousDecoration) + .toString()); + } + } } /** @@ -3410,35 +3470,9 @@ * mappings that have a corresponding StyleConstants * and CSS mapping. The conversion is to CSS attributes. */ - class ConvertAction extends TagAction { - - public void start(HTML.Tag t, MutableAttributeSet attr) { - pushCharacterStyle(); - if (!foundInsertTag) { - // Note that the third argument should really be based off - // inParagraph and impliedP. If we're wrong (that is - // insertTagDepthDelta shouldn't be changed), we'll end up - // removing an extra EndSpec, which won't matter anyway. - boolean insert = canInsertTag(t, attr, false); - if (foundInsertTag) { - if (!inParagraph) { - inParagraph = impliedP = true; - } - } - if (!insert) { - return; - } - } - if (attr.isDefined(IMPLIED)) { - attr.removeAttribute(IMPLIED); - } - if (styleAttributes != null) { - charAttr.addAttributes(styleAttributes); - } - // We also need to add attr, otherwise we lose custom - // attributes, including class/id for style lookups, and - // further confuse style lookup (doesn't have tag). - charAttr.addAttribute(t, attr.copyAttributes()); + final class ConvertAction extends CharacterAction { + @Override + void convertAttributes(HTML.Tag t, MutableAttributeSet attr) { StyleSheet sheet = getStyleSheet(); if (t == HTML.Tag.B) { sheet.addCSSAttribute(charAttr, CSS.Attribute.FONT_WEIGHT, "bold"); @@ -3449,7 +3483,7 @@ String value = "underline"; value = (v != null) ? value + "," + v.toString() : value; sheet.addCSSAttribute(charAttr, CSS.Attribute.TEXT_DECORATION, value); - } else if (t == HTML.Tag.STRIKE) { + } else if (t == HTML.Tag.STRIKE || t == HTML.Tag.S) { Object v = charAttr.getAttribute(CSS.Attribute.TEXT_DECORATION); String value = "line-through"; value = (v != null) ? value + "," + v.toString() : value; @@ -3479,11 +3513,6 @@ } } } - - public void end(HTML.Tag t) { - popCharacterStyle(); - } - } class AnchorAction extends CharacterAction { diff -Nru openjdk-17-17.0.12+7/src/java.desktop/share/classes/javax/swing/text/html/MuxingAttributeSet.java openjdk-17-17.0.13+11/src/java.desktop/share/classes/javax/swing/text/html/MuxingAttributeSet.java --- openjdk-17-17.0.12+7/src/java.desktop/share/classes/javax/swing/text/html/MuxingAttributeSet.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/share/classes/javax/swing/text/html/MuxingAttributeSet.java 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,9 +24,16 @@ */ package javax.swing.text.html; -import javax.swing.text.*; import java.io.Serializable; -import java.util.*; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.stream.Collectors; + +import javax.swing.text.AttributeSet; +import javax.swing.text.MutableAttributeSet; +import javax.swing.text.SimpleAttributeSet; /** * An implementation of AttributeSet that can multiplex @@ -196,15 +203,24 @@ * @see AttributeSet#getAttribute */ public Object getAttribute(Object key) { - AttributeSet[] as = getAttributes(); - int n = as.length; - for (int i = 0; i < n; i++) { - Object o = as[i].getAttribute(key); - if (o != null) { - return o; - } - } - return null; + final AttributeSet[] as = getAttributes(); + final int n = as.length; + if (key != CSS.Attribute.TEXT_DECORATION) { + for (int i = 0; i < n; i++) { + Object o = as[i].getAttribute(key); + if (o != null) { + return o; + } + } + return null; + } + + String values = Arrays.stream(as) + .map(a -> a.getAttribute(key)) + .filter(Objects::nonNull) + .map(Object::toString) + .collect(Collectors.joining(",")); + return CSS.mergeTextDecoration(values); } /** diff -Nru openjdk-17-17.0.12+7/src/java.desktop/share/classes/javax/swing/text/html/StyleSheet.java openjdk-17-17.0.13+11/src/java.desktop/share/classes/javax/swing/text/html/StyleSheet.java --- openjdk-17-17.0.12+7/src/java.desktop/share/classes/javax/swing/text/html/StyleSheet.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/share/classes/javax/swing/text/html/StyleSheet.java 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, 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 @@ -24,17 +24,53 @@ */ package javax.swing.text.html; -import sun.swing.SwingUtilities2; -import java.util.*; -import java.awt.*; -import java.io.*; -import java.net.*; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Insets; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.Serializable; +import java.io.StringReader; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.EmptyStackException; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Stack; +import java.util.StringTokenizer; +import java.util.Vector; + import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.UIManager; -import javax.swing.border.*; +import javax.swing.border.BevelBorder; +import javax.swing.border.Border; import javax.swing.event.ChangeListener; -import javax.swing.text.*; +import javax.swing.text.AttributeSet; +import javax.swing.text.Document; +import javax.swing.text.Element; +import javax.swing.text.MutableAttributeSet; +import javax.swing.text.SimpleAttributeSet; +import javax.swing.text.Style; +import javax.swing.text.StyleConstants; +import javax.swing.text.StyleContext; +import javax.swing.text.StyledDocument; +import javax.swing.text.View; + +import sun.swing.SwingUtilities2; /** * Support for defining the visual characteristics of @@ -2822,18 +2858,40 @@ return doGetAttribute(key); } + /** + * Merges the current value of the 'text-decoration' property + * with the value from parent. + */ + private Object getTextDecoration(Object value) { + AttributeSet parent = getResolveParent(); + if (parent == null) { + return value; + } + + Object parentValue = parent.getAttribute(CSS.Attribute.TEXT_DECORATION); + return parentValue == null + ? value + : CSS.mergeTextDecoration(value + "," + parentValue); + } + Object doGetAttribute(Object key) { - if (key == CSS.Attribute.FONT_SIZE && !isDefined(key)) { + Object retValue = super.getAttribute(key); + if (retValue != null) { + if (key != CSS.Attribute.TEXT_DECORATION) { + return retValue; + } else { + // Merge current value with parent + return getTextDecoration(retValue); + } + } + + if (key == CSS.Attribute.FONT_SIZE) { // CSS.FontSize represents a specified value and we need // to inherit a computed value so don't resolve percentage // value from parent. return fontSizeInherit(); } - Object retValue = super.getAttribute(key); - if (retValue != null) { - return retValue; - } // didn't find it... try parent if it's a css attribute // that is inherited. if (key instanceof CSS.Attribute) { diff -Nru openjdk-17-17.0.12+7/src/java.desktop/share/classes/sun/awt/SunToolkit.java openjdk-17-17.0.13+11/src/java.desktop/share/classes/sun/awt/SunToolkit.java --- openjdk-17-17.0.12+7/src/java.desktop/share/classes/sun/awt/SunToolkit.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/share/classes/sun/awt/SunToolkit.java 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, 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 @@ -205,7 +205,7 @@ * access to Xlib, OpenGL, etc. However, these methods are implemented * in SunToolkit so that they can be called from shared code (e.g. * from the OGL pipeline) or from the X11 pipeline regardless of whether - * XToolkit or MToolkit is currently in use. There are native macros + * XToolkit is currently in use. There are native macros * (such as AWT_LOCK) defined in awt.h, so if the implementation of these * methods is changed, make sure it is compatible with the native macros. * @@ -1883,6 +1883,20 @@ return false; } + /** + * Checks if the system is running Linux with the Wayland server. + * + * @return true if running on Wayland, false otherwise + */ + public boolean isRunningOnWayland() { + return false; + } + + public void dismissPopupOnFocusLostIfNeeded(Window invoker) {} + + public void dismissPopupOnFocusLostIfNeededCleanUp(Window invoker) {} + + private static final Object DEACTIVATION_TIMES_MAP_KEY = new Object(); public synchronized void setWindowDeactivationTime(Window w, long time) { diff -Nru openjdk-17-17.0.12+7/src/java.desktop/share/classes/sun/font/FileFontStrike.java openjdk-17-17.0.13+11/src/java.desktop/share/classes/sun/font/FileFontStrike.java --- openjdk-17-17.0.12+7/src/java.desktop/share/classes/sun/font/FileFontStrike.java 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/share/classes/sun/font/FileFontStrike.java 2024-10-10 14:01:59.000000000 +0000 @@ -37,6 +37,7 @@ import java.awt.geom.Rectangle2D; import java.util.concurrent.ConcurrentHashMap; import static sun.awt.SunHints.*; +import sun.java2d.pipe.OutlineTextRenderer; public class FileFontStrike extends PhysicalStrike { @@ -107,6 +108,7 @@ boolean useNatives; NativeStrike[] nativeStrikes; + static final int MAX_IMAGE_SIZE = OutlineTextRenderer.THRESHHOLD; /* Used only for communication to native layer */ private int intPtSize; @@ -697,6 +699,20 @@ void getGlyphImageBounds(int glyphCode, Point2D.Float pt, Rectangle result) { + if (intPtSize > MAX_IMAGE_SIZE) { + Rectangle.Float obds = getGlyphOutlineBounds(glyphCode); + if (obds.isEmpty()) { + Rectangle bds = getGlyphOutline(glyphCode, pt.x, pt.y).getBounds(); + result.setBounds(bds); + } else { + result.x = (int)Math.floor(pt.x + obds.getX() + 0.5f); + result.y = (int)Math.floor(pt.y + obds.getY() + 0.5f); + result.width = (int)Math.floor(obds.getWidth() + 0.5f); + result.height = (int)Math.floor(obds.getHeight() + 0.5f); + } + return; + } + long ptr = getGlyphImagePtr(glyphCode); float topLeftX, topLeftY; diff -Nru openjdk-17-17.0.12+7/src/java.desktop/share/legal/giflib.md openjdk-17-17.0.13+11/src/java.desktop/share/legal/giflib.md --- openjdk-17-17.0.12+7/src/java.desktop/share/legal/giflib.md 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/share/legal/giflib.md 2024-10-10 14:01:59.000000000 +0000 @@ -1,4 +1,4 @@ -## GIFLIB v5.2.1 +## GIFLIB v5.2.2 ### GIFLIB License ``` @@ -24,7 +24,27 @@ THE SOFTWARE. -https://sourceforge.net/p/giflib/code/ci/master/tree/openbsd-reallocarray.c +tree/README -Copyright (c) 2008 Otto Moerbeek +== Authors == + +Gershon Elber +original giflib code + +Toshio Kuratomi +uncompressed gif writing code +former maintainer + +Eric Raymond +current as well as long time former maintainer of giflib code + +There have been many other contributors; see the attributions in the +version-control history to learn more. + + +tree/openbsd-reallocarray.c + +Copyright (C) 2008 Otto Moerbeek SPDX-License-Identifier: MIT + +``` diff -Nru openjdk-17-17.0.12+7/src/java.desktop/share/legal/libpng.md openjdk-17-17.0.13+11/src/java.desktop/share/legal/libpng.md --- openjdk-17-17.0.12+7/src/java.desktop/share/legal/libpng.md 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/share/legal/libpng.md 2024-10-10 14:01:59.000000000 +0000 @@ -1,4 +1,4 @@ -## libpng v1.6.40 +## libpng v1.6.43 ### libpng License
    @@ -9,11 +9,11 @@
     PNG Reference Library License version 2
     ---------------------------------------
     
    -Copyright (c) 1995-2023 The PNG Reference Library Authors.
    -Copyright (c) 2018-2023 Cosmin Truta
    -Copyright (c) 1998-2018 Glenn Randers-Pehrson
    -Copyright (c) 1996-1997 Andreas Dilger
    -Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
    +Copyright (C) 1995-2024 The PNG Reference Library Authors.
    +Copyright (C) 2018-2024 Cosmin Truta
    +Copyright (C) 1998-2018 Glenn Randers-Pehrson
    +Copyright (C) 1996-1997 Andreas Dilger
    +Copyright (C) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
     
     The software is supplied "as is", without warranty of any kind,
     express or implied, including, without limitation, the warranties
    @@ -157,7 +157,9 @@
     This is the list of PNG Reference Library ("libpng") Contributing
     Authors, for copyright and licensing purposes.
     
    + * Adam Richter
      * Andreas Dilger
    + * Chris Blume
      * Cosmin Truta
      * Dave Martindale
      * Eric S. Raymond
    @@ -186,21 +188,28 @@
      * Vadim Barkov
      * Willem van Schaik
      * Zhijie Liang
    + * Apple Inc.
    +    - Zixu Wang (王子旭)
      * Arm Holdings
    -   - Richard Townsend
    +    - Richard Townsend
      * Google Inc.
    -   - Dan Field
    -   - Leon Scroggins III
    -   - Matt Sarett
    -   - Mike Klein
    -   - Sami Boukortt
    -   - Wan-Teh Chang
    +    - Dan Field
    +    - Leon Scroggins III
    +    - Matt Sarett
    +    - Mike Klein
    +    - Sami Boukortt
    +    - Wan-Teh Chang
    + * Loongson Technology Corporation Ltd.
    +    - GuXiWei (顾希伟)
    +    - JinBo (金波)
    +    - ZhangLixia (张利霞)
     
     The build projects, the build scripts, the test scripts, and other
    -files in the "ci", "projects", "scripts" and "tests" directories, have
    +files in the "projects", "scripts" and "tests" directories, have
     other copyright owners, but are released under the libpng license.
     
    -Some files in the "contrib" directory, and some tools-generated files
    -that are distributed with libpng, have other copyright owners, and are
    -released under other open source licenses.
    +Some files in the "ci" and "contrib" directories, as well as some
    +of the tools-generated files that are distributed with libpng, have
    +other copyright owners, and are released under other open source
    +licenses.
     ```
    diff -Nru openjdk-17-17.0.12+7/src/java.desktop/share/native/common/awt/debug/debug_mem.c openjdk-17-17.0.13+11/src/java.desktop/share/native/common/awt/debug/debug_mem.c
    --- openjdk-17-17.0.12+7/src/java.desktop/share/native/common/awt/debug/debug_mem.c	2024-07-09 08:19:46.000000000 +0000
    +++ openjdk-17-17.0.13+11/src/java.desktop/share/native/common/awt/debug/debug_mem.c	2024-10-10 14:01:59.000000000 +0000
    @@ -279,7 +279,7 @@
             "-------";
     
         DMem_VerifyHeader(header);
    -    sprintf(report, reportFormat, header->filename, header->linenumber, header->size, header->order);
    +    snprintf(report, sizeof(report), reportFormat, header->filename, header->linenumber, header->size, header->order);
         DTRACE_PRINTLN(report);
     }
     
    diff -Nru openjdk-17-17.0.12+7/src/java.desktop/share/native/common/awt/debug/debug_trace.c openjdk-17-17.0.13+11/src/java.desktop/share/native/common/awt/debug/debug_trace.c
    --- openjdk-17-17.0.12+7/src/java.desktop/share/native/common/awt/debug/debug_trace.c	2024-07-09 08:19:46.000000000 +0000
    +++ openjdk-17-17.0.13+11/src/java.desktop/share/native/common/awt/debug/debug_trace.c	2024-10-10 14:01:59.000000000 +0000
    @@ -216,7 +216,7 @@
         DASSERT(fmt != NULL);
     
         /* format the trace message */
    -    vsprintf(DTraceBuffer, fmt, arglist);
    +    vsnprintf(DTraceBuffer, sizeof(DTraceBuffer), fmt, arglist);
         /* not a real great overflow check (memory would already be hammered) but better than nothing */
         DASSERT(strlen(DTraceBuffer) < MAX_TRACE_BUFFER);
         /* output the trace message */
    diff -Nru openjdk-17-17.0.12+7/src/java.desktop/share/native/common/java2d/opengl/OGLBufImgOps.c openjdk-17-17.0.13+11/src/java.desktop/share/native/common/java2d/opengl/OGLBufImgOps.c
    --- openjdk-17-17.0.12+7/src/java.desktop/share/native/common/java2d/opengl/OGLBufImgOps.c	2024-07-09 08:19:46.000000000 +0000
    +++ openjdk-17-17.0.13+11/src/java.desktop/share/native/common/java2d/opengl/OGLBufImgOps.c	2024-10-10 14:01:59.000000000 +0000
    @@ -50,7 +50,7 @@
      * Note that this shader source code includes some "holes" marked by "%s".
      * This allows us to build different shader programs (e.g. one for
      * 3x3, one for 5x5, and so on) simply by filling in these "holes" with
    - * a call to sprintf().  See the OGLBufImgOps_CreateConvolveProgram() method
    + * a call to snprintf().  See the OGLBufImgOps_CreateConvolveProgram() method
      * for more details.
      *
      * REMIND: Currently this shader (and the supporting code in the
    @@ -141,16 +141,16 @@
     
         if (IS_SET(CONVOLVE_EDGE_ZERO_FILL)) {
             // EDGE_ZERO_FILL: fill in zero at the edges
    -        sprintf(edge, "sum = vec4(0.0);");
    +        snprintf(edge, sizeof(edge), "sum = vec4(0.0);");
         } else {
             // EDGE_NO_OP: use the source pixel color at the edges
    -        sprintf(edge,
    +        snprintf(edge, sizeof(edge),
                     "sum = texture%s(baseImage, gl_TexCoord[0].st);",
                     target);
         }
     
         // compose the final source code string from the various pieces
    -    sprintf(finalSource, convolveShaderSource,
    +    snprintf(finalSource, sizeof(finalSource), convolveShaderSource,
                 kernelMax, target, edge, target);
     
         convolveProgram = OGLContext_CreateFragmentProgram(finalSource);
    @@ -296,7 +296,7 @@
      * Note that this shader source code includes some "holes" marked by "%s".
      * This allows us to build different shader programs (e.g. one for
      * GL_TEXTURE_2D targets, one for GL_TEXTURE_RECTANGLE_ARB targets, and so on)
    - * simply by filling in these "holes" with a call to sprintf().  See the
    + * simply by filling in these "holes" with a call to snprintf().  See the
      * OGLBufImgOps_CreateRescaleProgram() method for more details.
      */
     static const char *rescaleShaderSource =
    @@ -360,7 +360,7 @@
         }
     
         // compose the final source code string from the various pieces
    -    sprintf(finalSource, rescaleShaderSource,
    +    snprintf(finalSource, sizeof(finalSource), rescaleShaderSource,
                 target, target, preRescale, postRescale);
     
         rescaleProgram = OGLContext_CreateFragmentProgram(finalSource);
    @@ -502,7 +502,7 @@
      * Note that this shader source code includes some "holes" marked by "%s".
      * This allows us to build different shader programs (e.g. one for
      * GL_TEXTURE_2D targets, one for GL_TEXTURE_RECTANGLE_ARB targets, and so on)
    - * simply by filling in these "holes" with a call to sprintf().  See the
    + * simply by filling in these "holes" with a call to snprintf().  See the
      * OGLBufImgOps_CreateLookupProgram() method for more details.
      */
     static const char *lookupShaderSource =
    @@ -592,7 +592,7 @@
         }
     
         // compose the final source code string from the various pieces
    -    sprintf(finalSource, lookupShaderSource,
    +    snprintf(finalSource, sizeof(finalSource), lookupShaderSource,
                 target, target, preLookup, alpha, postLookup);
     
         lookupProgram = OGLContext_CreateFragmentProgram(finalSource);
    diff -Nru openjdk-17-17.0.12+7/src/java.desktop/share/native/common/java2d/opengl/OGLPaints.c openjdk-17-17.0.13+11/src/java.desktop/share/native/common/java2d/opengl/OGLPaints.c
    --- openjdk-17-17.0.12+7/src/java.desktop/share/native/common/java2d/opengl/OGLPaints.c	2024-07-09 08:19:46.000000000 +0000
    +++ openjdk-17-17.0.13+11/src/java.desktop/share/native/common/java2d/opengl/OGLPaints.c	2024-10-10 14:01:59.000000000 +0000
    @@ -578,15 +578,15 @@
         }
     
         if (cycleMethod == CYCLE_NONE) {
    -        sprintf(cycleCode, noCycleCode, texCoordCalcCode);
    +        snprintf(cycleCode, sizeof(cycleCode), noCycleCode, texCoordCalcCode);
         } else if (cycleMethod == CYCLE_REFLECT) {
    -        sprintf(cycleCode, reflectCode, texCoordCalcCode);
    +        snprintf(cycleCode, sizeof(cycleCode), reflectCode, texCoordCalcCode);
         } else { // (cycleMethod == CYCLE_REPEAT)
    -        sprintf(cycleCode, repeatCode, texCoordCalcCode);
    +        snprintf(cycleCode, sizeof(cycleCode), repeatCode, texCoordCalcCode);
         }
     
         // compose the final source code string from the various pieces
    -    sprintf(finalSource, multiGradientShaderSource,
    +    snprintf(finalSource, sizeof(finalSource), multiGradientShaderSource,
                 MAX_COLORS, maxFractions,
                 maskVars, paintVars, distCode,
                 cycleCode, colorSpaceCode, maskCode);
    diff -Nru openjdk-17-17.0.12+7/src/java.desktop/share/native/libfontmanager/freetypeScaler.c openjdk-17-17.0.13+11/src/java.desktop/share/native/libfontmanager/freetypeScaler.c
    --- openjdk-17-17.0.12+7/src/java.desktop/share/native/libfontmanager/freetypeScaler.c	2024-07-09 08:19:46.000000000 +0000
    +++ openjdk-17-17.0.13+11/src/java.desktop/share/native/libfontmanager/freetypeScaler.c	2024-10-10 14:01:59.000000000 +0000
    @@ -486,6 +486,8 @@
         return sqrt(a*a+b*b);
     }
     
    +#define TOO_LARGE(a, b) (abs((int)(a / b)) > 32766)
    +
     JNIEXPORT jlong JNICALL
     Java_sun_font_FreetypeFontScaler_createScalerContextNative(
             JNIEnv *env, jobject scaler, jlong pScaler, jdoubleArray matrix,
    @@ -497,6 +499,7 @@
                  (FTScalerInfo*) jlong_to_ptr(pScaler);
     
         if (context == NULL) {
    +        free(context);
             invalidateJavaScaler(env, scaler, NULL);
             return (jlong) 0;
         }
    @@ -506,7 +509,18 @@
             //text can not be smaller than 1 point
             ptsz = 1.0;
         }
    +    if (ptsz > 16384) {
    +        ptsz = 16384;    // far enough from 32767
    +        fm = TEXT_FM_ON; // avoids calculations which might overflow
    +    }
         context->ptsz = (int)(ptsz * 64);
    +    if (TOO_LARGE(dmat[0], ptsz) || TOO_LARGE(dmat[1], ptsz) ||
    +        TOO_LARGE(dmat[2], ptsz) || TOO_LARGE(dmat[3], ptsz))
    +    {
    +        free(context);
    +        return (jlong)0;
    +    }
    +
         context->transform.xx =  FloatToFTFixed((float)(dmat[0]/ptsz));
         context->transform.yx = -FloatToFTFixed((float)(dmat[1]/ptsz));
         context->transform.xy = -FloatToFTFixed((float)(dmat[2]/ptsz));
    diff -Nru openjdk-17-17.0.12+7/src/java.desktop/share/native/libharfbuzz/hb-meta.hh openjdk-17-17.0.13+11/src/java.desktop/share/native/libharfbuzz/hb-meta.hh
    --- openjdk-17-17.0.12+7/src/java.desktop/share/native/libharfbuzz/hb-meta.hh	2024-07-09 08:19:46.000000000 +0000
    +++ openjdk-17-17.0.13+11/src/java.desktop/share/native/libharfbuzz/hb-meta.hh	2024-10-10 14:01:59.000000000 +0000
    @@ -199,7 +199,7 @@
     template <> struct hb_int_max       : hb_integral_constant     {};
     #define hb_int_max(T) hb_int_max::value
     
    -#if defined(__GNUC__) && __GNUC__ < 5
    +#if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
     #define hb_is_trivially_copyable(T) __has_trivial_copy(T)
     #define hb_is_trivially_copy_assignable(T) __has_trivial_assign(T)
     #define hb_is_trivially_constructible(T) __has_trivial_constructor(T)
    diff -Nru openjdk-17-17.0.12+7/src/java.desktop/unix/classes/sun/awt/UNIXToolkit.java openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/UNIXToolkit.java
    --- openjdk-17-17.0.12+7/src/java.desktop/unix/classes/sun/awt/UNIXToolkit.java	2024-07-09 08:19:46.000000000 +0000
    +++ openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/UNIXToolkit.java	2024-10-10 14:01:59.000000000 +0000
    @@ -25,15 +25,37 @@
     package sun.awt;
     
     import java.awt.RenderingHints;
    -import static java.awt.RenderingHints.*;
    +
    +import static java.awt.RenderingHints.KEY_TEXT_ANTIALIASING;
    +import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT;
    +import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HBGR;
    +import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB;
    +import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VBGR;
    +import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VRGB;
    +import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON;
    +
     import static java.util.concurrent.TimeUnit.SECONDS;
     import java.awt.color.ColorSpace;
    -import java.awt.image.*;
    +
    +import java.awt.Window;
    +import java.awt.event.WindowAdapter;
    +import java.awt.event.WindowEvent;
    +import java.awt.event.WindowFocusListener;
    +import java.awt.image.BufferedImage;
    +import java.awt.image.ColorModel;
    +import java.awt.image.ComponentColorModel;
    +import java.awt.image.DataBuffer;
    +import java.awt.image.DataBufferByte;
    +import java.awt.image.Raster;
    +import java.awt.image.WritableRaster;
     import java.io.BufferedReader;
     import java.io.IOException;
     import java.io.InputStreamReader;
     import java.security.AccessController;
     import java.security.PrivilegedAction;
    +import java.util.Arrays;
    +
    +import sun.awt.X11.XBaseWindow;
     
     import sun.security.action.GetIntegerAction;
     import com.sun.java.swing.plaf.gtk.GTKConstants.TextDirection;
    @@ -491,4 +513,113 @@
             return AccessController.doPrivileged((PrivilegedAction)()
                     -> Boolean.getBoolean("jdk.gtk.verbose"));
         }
    +
    +    private static volatile Boolean isOnWayland = null;
    +
    +    @SuppressWarnings("removal")
    +    public static boolean isOnWayland() {
    +        Boolean result = isOnWayland;
    +        if (result == null) {
    +            synchronized (GTK_LOCK) {
    +                result = isOnWayland;
    +                if (result == null) {
    +                    isOnWayland
    +                            = result
    +                            = AccessController.doPrivileged(
    +                            (PrivilegedAction) () -> {
    +                                final String display =
    +                                        System.getenv("WAYLAND_DISPLAY");
    +
    +                                return display != null
    +                                        && !display.trim().isEmpty();
    +                            }
    +                    );
    +                }
    +            }
    +        }
    +        return result;
    +    }
    +
    +    @Override
    +    public boolean isRunningOnWayland() {
    +        return isOnWayland();
    +    }
    +
    +    // We rely on the X11 input grab mechanism, but for the Wayland session
    +    // it only works inside the XWayland server, so mouse clicks outside of it
    +    // will not be detected.
    +    // (window decorations, pure Wayland applications, desktop, etc.)
    +    //
    +    // As a workaround, we can dismiss menus when the window loses focus.
    +    //
    +    // However, there are "blind spots" though, which, when clicked, don't
    +    // transfer the focus away and don't dismiss the menu
    +    // (e.g. the window's own title or the area in the side dock without
    +    // application icons).
    +    private static final WindowFocusListener waylandWindowFocusListener;
    +
    +    static {
    +        if (isOnWayland()) {
    +            waylandWindowFocusListener = new WindowAdapter() {
    +                @Override
    +                public void windowLostFocus(WindowEvent e) {
    +                    Window window = e.getWindow();
    +                    Window oppositeWindow = e.getOppositeWindow();
    +
    +                    // The focus can move between the window calling the popup,
    +                    // and the popup window itself.
    +                    // We only dismiss the popup in other cases.
    +                    if (oppositeWindow != null) {
    +                        if (window == oppositeWindow.getParent() ) {
    +                            addWaylandWindowFocusListenerToWindow(oppositeWindow);
    +                            return;
    +                        }
    +                        if (window.getParent() == oppositeWindow) {
    +                            return;
    +                        }
    +                    }
    +
    +                    window.removeWindowFocusListener(this);
    +
    +                    // AWT
    +                    XBaseWindow.ungrabInput();
    +
    +                    // Swing
    +                    window.dispatchEvent(new UngrabEvent(window));
    +                }
    +            };
    +        } else {
    +            waylandWindowFocusListener = null;
    +        }
    +    }
    +
    +    private static void addWaylandWindowFocusListenerToWindow(Window window) {
    +        if (!Arrays
    +                .asList(window.getWindowFocusListeners())
    +                .contains(waylandWindowFocusListener)
    +        ) {
    +            window.addWindowFocusListener(waylandWindowFocusListener);
    +        }
    +    }
    +
    +    @Override
    +    public void dismissPopupOnFocusLostIfNeeded(Window invoker) {
    +        if (!isOnWayland() || invoker == null) {
    +            return;
    +        }
    +
    +        addWaylandWindowFocusListenerToWindow(invoker);
    +    }
    +
    +    @Override
    +    public void dismissPopupOnFocusLostIfNeededCleanUp(Window invoker) {
    +        if (!isOnWayland() || invoker == null) {
    +            return;
    +        }
    +
    +        invoker.removeWindowFocusListener(waylandWindowFocusListener);
    +        for (Window ownedWindow : invoker.getOwnedWindows()) {
    +            ownedWindow.removeWindowFocusListener(waylandWindowFocusListener);
    +        }
    +    }
     }
    diff -Nru openjdk-17-17.0.12+7/src/java.desktop/unix/classes/sun/awt/X11/XBaseWindow.java openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/X11/XBaseWindow.java
    --- openjdk-17-17.0.12+7/src/java.desktop/unix/classes/sun/awt/X11/XBaseWindow.java	2024-07-09 08:19:46.000000000 +0000
    +++ openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/X11/XBaseWindow.java	2024-10-10 14:01:59.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2003, 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
    @@ -25,9 +25,13 @@
     
     package sun.awt.X11;
     
    -import java.awt.*;
    -import sun.awt.*;
    -import java.util.*;
    +import java.awt.Dimension;
    +import java.awt.Point;
    +import java.awt.Rectangle;
    +import java.util.HashSet;
    +import java.util.Set;
    +
    +import sun.awt.SunToolkit;
     import sun.util.logging.PlatformLogger;
     
     public class XBaseWindow {
    @@ -912,7 +916,7 @@
             }
         }
     
    -    static void ungrabInput() {
    +    public static void ungrabInput() {
             XToolkit.awtLock();
             try {
                 XBaseWindow grabWindow = XAwtState.getGrabWindow();
    diff -Nru openjdk-17-17.0.12+7/src/java.desktop/unix/classes/sun/awt/X11/XDragSourceContextPeer.java openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/X11/XDragSourceContextPeer.java
    --- openjdk-17-17.0.12+7/src/java.desktop/unix/classes/sun/awt/X11/XDragSourceContextPeer.java	2024-07-09 08:19:46.000000000 +0000
    +++ openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/X11/XDragSourceContextPeer.java	2024-10-10 14:01:59.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2003, 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
    @@ -27,6 +27,7 @@
     
     import java.awt.Component;
     import java.awt.Cursor;
    +import java.awt.Toolkit;
     import java.awt.Window;
     
     import java.awt.datatransfer.DataFlavor;
    @@ -393,6 +394,40 @@
         }
     
         /**
    +     * Our X11 code expects the drop target window to be a top level window
    +     * and to have the XA_WM_STATE property.
    +     * This is not true when performing drag and drop from XWayland
    +     * to a native Wayland application.
    +     * In this case XWayland creates a dummy window with only one property,
    +     * XdndAware.
    +     *
    +     * @param window to test
    +     * @return true if window has XdndAware property when running under Wayland
    +     */
    +    private static boolean isXWaylandDndAwareWindow(long window) {
    +        Toolkit toolkit = Toolkit.getDefaultToolkit();
    +        if (!(toolkit instanceof SunToolkit)
    +                || !((SunToolkit) toolkit).isRunningOnWayland()) {
    +            return false;
    +        }
    +
    +        WindowPropertyGetter wpg =
    +            new WindowPropertyGetter(window, XDnDConstants.XA_XdndAware, 0, 1,
    +                                     false, XConstants.AnyPropertyType);
    +
    +        try {
    +            int status =
    +                wpg.execute(XErrorHandler.IgnoreBadWindowHandler.getInstance());
    +
    +            return status == XConstants.Success
    +                   && wpg.getData() != 0
    +                   && wpg.getActualType() == XAtom.XA_ATOM;
    +        } finally {
    +            wpg.dispose();
    +        }
    +    }
    +
    +    /**
          * Returns the client window under the specified root subwindow.
          */
         private static long findClientWindow(long window) {
    @@ -400,6 +435,10 @@
                 return window;
             }
     
    +        if (isXWaylandDndAwareWindow(window)) {
    +            return window;
    +        }
    +
             Set children = XlibUtil.getChildWindows(window);
             for (Long child : children) {
                 long win = findClientWindow(child);
    diff -Nru openjdk-17-17.0.12+7/src/java.desktop/unix/classes/sun/awt/X11/XMenuWindow.java openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/X11/XMenuWindow.java
    --- openjdk-17-17.0.12+7/src/java.desktop/unix/classes/sun/awt/X11/XMenuWindow.java	2024-07-09 08:19:46.000000000 +0000
    +++ openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/X11/XMenuWindow.java	2024-10-10 14:01:59.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2002, 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
    @@ -24,16 +24,21 @@
      */
     package sun.awt.X11;
     
    -import java.awt.*;
    -import java.awt.peer.*;
    -import java.awt.event.*;
    -
    -import java.awt.image.BufferedImage;
    -import java.awt.geom.Point2D;
    +import java.awt.Dimension;
    +import java.awt.Graphics;
    +import java.awt.MenuItem;
    +import java.awt.Point;
    +import java.awt.Rectangle;
    +import java.awt.Toolkit;
    +import java.awt.Window;
     
     import java.util.Vector;
    +
    +import sun.awt.SunToolkit;
     import sun.util.logging.PlatformLogger;
     
    +import javax.swing.SwingUtilities;
    +
     public class XMenuWindow extends XBaseMenuWindow {
     
         /************************************************
    @@ -389,6 +394,16 @@
             return true;
         }
     
    +    protected Window getMenuTarget() {
    +        if (target instanceof Window targetWindow) {
    +            return targetWindow;
    +        } else {
    +            return target == null
    +                    ? null
    +                    : SwingUtilities.getWindowAncestor(target);
    +        }
    +    }
    +
         /**
          * Init window if it's not inited yet
          * and show it at specified coordinates
    @@ -405,6 +420,9 @@
             XToolkit.awtLock();
             try {
                 reshape(bounds.x, bounds.y, bounds.width, bounds.height);
    +            if (Toolkit.getDefaultToolkit() instanceof SunToolkit sunToolkit) {
    +                sunToolkit.dismissPopupOnFocusLostIfNeeded(getMenuTarget());
    +            }
                 xSetVisible(true);
                 //Fixed 6267182: PIT: Menu is not visible after
                 //showing and disposing a file dialog, XToolkit
    @@ -421,6 +439,9 @@
         void hide() {
             selectItem(null, false);
             xSetVisible(false);
    +        if (Toolkit.getDefaultToolkit() instanceof SunToolkit sunToolkit) {
    +            sunToolkit.dismissPopupOnFocusLostIfNeededCleanUp(getMenuTarget());
    +        }
         }
     
         /************************************************
    diff -Nru openjdk-17-17.0.12+7/src/java.desktop/unix/classes/sun/awt/X11/XPopupMenuPeer.java openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/X11/XPopupMenuPeer.java
    --- openjdk-17-17.0.12+7/src/java.desktop/unix/classes/sun/awt/X11/XPopupMenuPeer.java	2024-07-09 08:19:46.000000000 +0000
    +++ openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/X11/XPopupMenuPeer.java	2024-10-10 14:01:59.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2002, 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
    @@ -24,12 +24,25 @@
      */
     package sun.awt.X11;
     
    -import java.awt.*;
    -import java.awt.peer.*;
    -import java.awt.event.*;
    +import java.awt.AWTEvent;
    +import java.awt.Component;
    +import java.awt.Dimension;
    +import java.awt.Event;
    +import java.awt.Font;
    +import java.awt.FontMetrics;
    +import java.awt.Graphics;
    +import java.awt.MenuItem;
    +import java.awt.Point;
    +import java.awt.PopupMenu;
    +import java.awt.Rectangle;
    +import java.awt.Toolkit;
    +import java.awt.event.KeyEvent;
    +import java.awt.event.MouseEvent;
     
    +import java.awt.peer.PopupMenuPeer;
     import java.util.Vector;
     import sun.awt.AWTAccessor;
    +import sun.awt.SunToolkit;
     import sun.util.logging.PlatformLogger;
     
     public class XPopupMenuPeer extends XMenuWindow implements PopupMenuPeer {
    @@ -125,6 +138,9 @@
                 //near the periphery of the screen, XToolkit
                 Rectangle bounds = getWindowBounds(pt, dim);
                 reshape(bounds);
    +            if (Toolkit.getDefaultToolkit() instanceof SunToolkit sunToolkit) {
    +                sunToolkit.dismissPopupOnFocusLostIfNeeded(getMenuTarget());
    +            }
                 xSetVisible(true);
                 toFront();
                 selectItem(null, false);
    diff -Nru openjdk-17-17.0.12+7/src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java
    --- openjdk-17-17.0.12+7/src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java	2024-07-09 08:19:46.000000000 +0000
    +++ openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java	2024-10-10 14:01:59.000000000 +0000
    @@ -35,21 +35,43 @@
     import sun.awt.UNIXToolkit;
     import sun.awt.X11GraphicsConfig;
     import sun.awt.X11GraphicsDevice;
    +import sun.awt.screencast.ScreencastHelper;
     import sun.security.action.GetPropertyAction;
     
     @SuppressWarnings("removal")
     final class XRobotPeer implements RobotPeer {
     
         private static final boolean tryGtk;
    +    private static final String screenshotMethod;
    +    private static final String METHOD_X11 = "x11";
    +    private static final String METHOD_SCREENCAST = "dbusScreencast";
    +
         static {
             loadNativeLibraries();
    +
             tryGtk = Boolean.parseBoolean(
    -                            AccessController.doPrivileged(
    -                                    new GetPropertyAction("awt.robot.gtk", "true")
    -                            ));
    +                     AccessController.doPrivileged(
    +                             new GetPropertyAction("awt.robot.gtk",
    +                                     "true")
    +                     ));
    +
    +        boolean isOnWayland = false;
    +
    +        if (Toolkit.getDefaultToolkit() instanceof SunToolkit sunToolkit) {
    +            isOnWayland = sunToolkit.isRunningOnWayland();
    +        }
    +
    +        screenshotMethod = AccessController.doPrivileged(
    +                new GetPropertyAction(
    +                        "awt.robot.screenshotMethod",
    +                        isOnWayland
    +                            ? METHOD_SCREENCAST
    +                            : METHOD_X11
    +                ));
         }
    +
         private static volatile boolean useGtk;
    -    private final X11GraphicsConfig  xgc;
    +    private final X11GraphicsConfig xgc;
     
         XRobotPeer(X11GraphicsDevice gd) {
             xgc = (X11GraphicsConfig) gd.getDefaultConfiguration();
    @@ -100,15 +122,31 @@
         @Override
         public int getRGBPixel(int x, int y) {
             int[] pixelArray = new int[1];
    -        getRGBPixelsImpl(xgc, x, y, 1, 1, pixelArray, useGtk);
    +        if (screenshotMethod.equals(METHOD_SCREENCAST)
    +            && ScreencastHelper.isAvailable()) {
    +
    +            ScreencastHelper.getRGBPixels(x, y, 1, 1, pixelArray);
    +        } else {
    +            getRGBPixelsImpl(xgc, x, y, 1, 1, pixelArray, useGtk);
    +        }
             return pixelArray[0];
         }
     
         @Override
    -    public int [] getRGBPixels(Rectangle bounds) {
    -        int[] pixelArray = new int[bounds.width*bounds.height];
    -        getRGBPixelsImpl(xgc, bounds.x, bounds.y, bounds.width, bounds.height,
    -                            pixelArray, useGtk);
    +    public int[] getRGBPixels(Rectangle bounds) {
    +        int[] pixelArray = new int[bounds.width * bounds.height];
    +        if (screenshotMethod.equals(METHOD_SCREENCAST)
    +            && ScreencastHelper.isAvailable()) {
    +
    +            ScreencastHelper.getRGBPixels(bounds.x, bounds.y,
    +                                          bounds.width, bounds.height,
    +                                          pixelArray);
    +        } else {
    +            getRGBPixelsImpl(xgc,
    +                             bounds.x, bounds.y,
    +                             bounds.width, bounds.height,
    +                             pixelArray, useGtk);
    +        }
             return pixelArray;
         }
     
    diff -Nru openjdk-17-17.0.12+7/src/java.desktop/unix/classes/sun/awt/X11/XWM.java openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/X11/XWM.java
    --- openjdk-17-17.0.12+7/src/java.desktop/unix/classes/sun/awt/X11/XWM.java	2024-07-09 08:19:46.000000000 +0000
    +++ openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/X11/XWM.java	2024-10-10 14:01:59.000000000 +0000
    @@ -1369,6 +1369,9 @@
                   case UNITY_COMPIZ_WM:
                       res = new Insets(28, 1, 1, 1);
                       break;
    +              case MUTTER_WM:
    +                  res = new Insets(37, 0, 0, 0);
    +                  break;
                   case MOTIF_WM:
                   case OPENLOOK_WM:
                   default:
    @@ -1380,6 +1383,7 @@
             }
             return res;
         }
    +
         /*
          * Some buggy WMs ignore window gravity when processing
          * ConfigureRequest and position window as if the gravity is Static.
    diff -Nru openjdk-17-17.0.12+7/src/java.desktop/unix/classes/sun/awt/X11GraphicsEnvironment.java openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/X11GraphicsEnvironment.java
    --- openjdk-17-17.0.12+7/src/java.desktop/unix/classes/sun/awt/X11GraphicsEnvironment.java	2024-07-09 08:19:46.000000000 +0000
    +++ openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/X11GraphicsEnvironment.java	2024-10-10 14:01:59.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1997, 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
    @@ -67,7 +67,7 @@
                     System.loadLibrary("awt");
     
                     /*
    -                 * Note: The MToolkit object depends on the static initializer
    +                 * Note: The XToolkit object depends on the static initializer
                      * of X11GraphicsEnvironment to initialize the connection to
                      * the X11 server.
                      */
    diff -Nru openjdk-17-17.0.12+7/src/java.desktop/unix/classes/sun/awt/screencast/ScreencastHelper.java openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/screencast/ScreencastHelper.java
    --- openjdk-17-17.0.12+7/src/java.desktop/unix/classes/sun/awt/screencast/ScreencastHelper.java	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/screencast/ScreencastHelper.java	2024-10-10 14:01:59.000000000 +0000
    @@ -0,0 +1,233 @@
    +/*
    + * 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 sun.awt.screencast;
    +
    +import sun.awt.UNIXToolkit;
    +import sun.java2d.pipe.Region;
    +import sun.security.action.GetPropertyAction;
    +
    +import java.awt.GraphicsConfiguration;
    +import java.awt.GraphicsEnvironment;
    +import java.awt.Rectangle;
    +import java.awt.Toolkit;
    +import java.awt.geom.AffineTransform;
    +import java.security.AccessController;
    +import java.util.Arrays;
    +import java.util.List;
    +import java.util.Set;
    +import java.util.Timer;
    +import java.util.TimerTask;
    +import java.util.stream.IntStream;
    +
    +/**
    + * Helper class for grabbing pixels from the screen using the
    + * 
    + * org.freedesktop.portal.ScreenCast API
    + */
    +
    +@SuppressWarnings("removal")
    +public class ScreencastHelper {
    +
    +    static final boolean SCREENCAST_DEBUG;
    +    private static final boolean IS_NATIVE_LOADED;
    +
    +
    +    private static final int ERROR = -1;
    +    private static final int DENIED = -11;
    +    private static final int OUT_OF_BOUNDS = -12;
    +
    +    private static final int DELAY_BEFORE_SESSION_CLOSE = 2000;
    +
    +    private static volatile TimerTask timerTask = null;
    +    private static final Timer timerCloseSession
    +            = new Timer("auto-close screencast session", true);
    +
    +
    +    private ScreencastHelper() {
    +    }
    +
    +    static {
    +        SCREENCAST_DEBUG = Boolean.parseBoolean(
    +                               AccessController.doPrivileged(
    +                                       new GetPropertyAction(
    +                                               "awt.robot.screenshotDebug",
    +                                               "false"
    +                                       )
    +                               ));
    +
    +        boolean loadFailed = false;
    +
    +        if (!(Toolkit.getDefaultToolkit() instanceof UNIXToolkit tk
    +              && tk.loadGTK())
    +              || !loadPipewire(SCREENCAST_DEBUG)) {
    +
    +            System.err.println(
    +                    "Could not load native libraries for ScreencastHelper"
    +            );
    +
    +            loadFailed = true;
    +        }
    +
    +        IS_NATIVE_LOADED = !loadFailed;
    +    }
    +
    +    public static boolean isAvailable() {
    +        return IS_NATIVE_LOADED;
    +    }
    +
    +    private static native boolean loadPipewire(boolean screencastDebug);
    +
    +    private static native int getRGBPixelsImpl(
    +            int x, int y, int width, int height,
    +            int[] pixelArray,
    +            int[] affectedScreensBoundsArray,
    +            String token
    +    );
    +
    +    private static List getSystemScreensBounds() {
    +        return Arrays
    +                .stream(GraphicsEnvironment
    +                        .getLocalGraphicsEnvironment()
    +                        .getScreenDevices())
    +                .map(graphicsDevice -> {
    +                    GraphicsConfiguration gc =
    +                            graphicsDevice.getDefaultConfiguration();
    +                    Rectangle screen = gc.getBounds();
    +                    AffineTransform tx = gc.getDefaultTransform();
    +
    +                    return new Rectangle(
    +                            Region.clipRound(screen.x * tx.getScaleX()),
    +                            Region.clipRound(screen.y * tx.getScaleY()),
    +                            Region.clipRound(screen.width * tx.getScaleX()),
    +                            Region.clipRound(screen.height * tx.getScaleY())
    +                    );
    +                })
    +                .toList();
    +    }
    +
    +    private static synchronized native void closeSession();
    +
    +    private static void timerCloseSessionRestart() {
    +        if (timerTask != null) {
    +            timerTask.cancel();
    +        }
    +
    +        timerTask = new TimerTask() {
    +            @Override
    +            public void run() {
    +                closeSession();
    +            }
    +        };
    +
    +        timerCloseSession.schedule(timerTask, DELAY_BEFORE_SESSION_CLOSE);
    +    }
    +
    +    public static synchronized void getRGBPixels(
    +            int x, int y, int width, int height, int[] pixelArray
    +    ) {
    +        if (!IS_NATIVE_LOADED) return;
    +
    +        timerCloseSessionRestart();
    +
    +        Rectangle captureArea = new Rectangle(x, y, width, height);
    +
    +        List affectedScreenBounds = getSystemScreensBounds()
    +                .stream()
    +                .filter(captureArea::intersects)
    +                .toList();
    +
    +        if (SCREENCAST_DEBUG) {
    +            System.out.printf("// getRGBPixels in %s, affectedScreenBounds %s\n",
    +                    captureArea, affectedScreenBounds);
    +        }
    +
    +        if (affectedScreenBounds.isEmpty()) {
    +            if (SCREENCAST_DEBUG) {
    +                System.out.println("// getRGBPixels - requested area "
    +                        + "outside of any screen");
    +            }
    +            return;
    +        }
    +
    +        int retVal;
    +        Set tokensForRectangle =
    +                TokenStorage.getTokens(affectedScreenBounds);
    +
    +        int[] affectedScreenBoundsArray = affectedScreenBounds
    +                .stream()
    +                .filter(captureArea::intersects)
    +                .flatMapToInt(bounds -> IntStream.of(
    +                        bounds.x, bounds.y,
    +                        bounds.width, bounds.height
    +                ))
    +                .toArray();
    +
    +        for (TokenItem tokenItem : tokensForRectangle) {
    +            retVal = getRGBPixelsImpl(
    +                    x, y, width, height,
    +                    pixelArray,
    +                    affectedScreenBoundsArray,
    +                    tokenItem.token
    +            );
    +
    +            if (retVal >= 0) { // we have received a screen data
    +                return;
    +            } else if (!checkReturnValue(retVal)) {
    +                return;
    +            } // else, try other tokens
    +        }
    +
    +        // we do not have a saved token or it did not work,
    +        // try without the token to show the system's permission request window
    +        retVal = getRGBPixelsImpl(
    +                x, y, width, height,
    +                pixelArray,
    +                affectedScreenBoundsArray,
    +                null
    +        );
    +
    +        checkReturnValue(retVal);
    +    }
    +
    +    private static boolean checkReturnValue(int retVal) {
    +        if (retVal == DENIED) {
    +            // user explicitly denied the capture, no more tries.
    +            throw new SecurityException(
    +                    "Screen Capture in the selected area was not allowed"
    +            );
    +        } else if (retVal == ERROR) {
    +            if (SCREENCAST_DEBUG) {
    +                System.err.println("Screen capture failed.");
    +            }
    +        } else if (retVal == OUT_OF_BOUNDS) {
    +            if (SCREENCAST_DEBUG) {
    +                System.err.println(
    +                        "Token does not provide access to requested area.");
    +            }
    +        }
    +        return retVal != ERROR;
    +    }
    +}
    diff -Nru openjdk-17-17.0.12+7/src/java.desktop/unix/classes/sun/awt/screencast/TokenItem.java openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/screencast/TokenItem.java
    --- openjdk-17-17.0.12+7/src/java.desktop/unix/classes/sun/awt/screencast/TokenItem.java	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/screencast/TokenItem.java	2024-10-10 14:01:59.000000000 +0000
    @@ -0,0 +1,154 @@
    +/*
    + * 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 sun.awt.screencast;
    +
    +import java.awt.Dimension;
    +import java.awt.Rectangle;
    +import java.util.ArrayList;
    +import java.util.Arrays;
    +import java.util.List;
    +import java.util.stream.Collectors;
    +import java.util.stream.IntStream;
    +
    +import static sun.awt.screencast.ScreencastHelper.SCREENCAST_DEBUG;
    +
    +/**
    + * Helper class used by {@link TokenStorage} as restore token record
    + * with its associated screen boundaries.
    + *
    + * It helps in serialization/deserialization of screen boundaries
    + * to/from string format.
    + *
    + * The screen boundary is represented as {@code _x_y_width_height}
    + * and can be repeated several times.
    + */
    +final class TokenItem {
    +
    +    final String token;
    +    final List allowedScreensBounds;
    +
    +    public TokenItem(String token, int[] allowedScreenBounds) {
    +        if (token == null || token.isBlank()) {
    +            throw new RuntimeException("empty or null tokens are not allowed");
    +        }
    +        if (allowedScreenBounds.length % 4 != 0) {
    +            throw new RuntimeException("array with incorrect length provided");
    +        }
    +
    +        this.token = token;
    +
    +        this.allowedScreensBounds = IntStream
    +                        .iterate(0,
    +                                i -> i < allowedScreenBounds.length,
    +                                i -> i + 4)
    +                        .mapToObj(i -> new Rectangle(
    +                                allowedScreenBounds[i], allowedScreenBounds[i+1],
    +                                allowedScreenBounds[i+2], allowedScreenBounds[i+3]
    +                        ))
    +                        .collect(Collectors.toList());
    +    }
    +
    +    public boolean hasAllScreensWithExactMatch(List bounds) {
    +        return allowedScreensBounds.containsAll(bounds);
    +    }
    +
    +    public boolean hasAllScreensOfSameSize(List screenSizes) {
    +        // We also need to consider duplicates, since there may be
    +        // multiple screens of the same size.
    +        // The token item must also have at least the same number
    +        // of screens with that size.
    +
    +        List tokenSizes = allowedScreensBounds
    +                .stream()
    +                .map(bounds -> new Dimension(bounds.width, bounds.height))
    +                .collect(Collectors.toCollection(ArrayList::new));
    +
    +        return screenSizes.size() == screenSizes
    +                .stream()
    +                .filter(tokenSizes::remove)
    +                .count();
    +    }
    +
    +    private static final int MAX_SIZE = 50000;
    +    private static final int MIN_SIZE = 1;
    +
    +    public boolean hasValidBounds() {
    +        //This check is very rough, in order to filter out abnormal values
    +        for (Rectangle bounds : allowedScreensBounds) {
    +            if (bounds.x < -MAX_SIZE || bounds.x > MAX_SIZE
    +                    || bounds.y < -MAX_SIZE || bounds.y > MAX_SIZE
    +                    || bounds.width < MIN_SIZE || bounds.width > MAX_SIZE
    +                    || bounds.height < MIN_SIZE || bounds.height > MAX_SIZE
    +            ) {
    +                return false;
    +            }
    +        }
    +        return true;
    +    }
    +
    +    public String dump() {
    +        StringBuilder sb = new StringBuilder();
    +        for (Rectangle bounds : allowedScreensBounds) {
    +            sb.append("_%d_%d_%d_%d"
    +                    .formatted(bounds.x, bounds.y, bounds.width, bounds.height));
    +        }
    +        return sb.toString();
    +    }
    +
    +    public static TokenItem parse(String token, Object input) {
    +        if (token == null || input == null) return null;
    +
    +        try {
    +            int[] integers = Arrays.stream(String.valueOf(input)
    +                    .split("_"))
    +                    .filter(s -> !s.isBlank())
    +                    .mapToInt(Integer::parseInt)
    +                    .toArray();
    +
    +            if (integers.length % 4 == 0) {
    +                TokenItem tokenItem = new TokenItem(token, integers);
    +                if (tokenItem.hasValidBounds()) {
    +                    return tokenItem;
    +                }
    +            }
    +        } catch (NumberFormatException ignored) {}
    +
    +        if (SCREENCAST_DEBUG) {
    +            System.err.printf("Malformed record for token %s: %s\n",
    +                    token, input);
    +        }
    +        return null;
    +    }
    +
    +    @Override
    +    public String toString() {
    +        StringBuilder sb = new StringBuilder("Token: " + token + "\n");
    +        for (Rectangle bounds : allowedScreensBounds) {
    +            sb.append("\t").append(bounds).append("\n");
    +        }
    +        return sb.toString();
    +    }
    +}
    \ No newline at end of file
    diff -Nru openjdk-17-17.0.12+7/src/java.desktop/unix/classes/sun/awt/screencast/TokenStorage.java openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/screencast/TokenStorage.java
    --- openjdk-17-17.0.12+7/src/java.desktop/unix/classes/sun/awt/screencast/TokenStorage.java	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/awt/screencast/TokenStorage.java	2024-10-10 14:01:59.000000000 +0000
    @@ -0,0 +1,461 @@
    +/*
    + * 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
    + * 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 sun.awt.screencast;
    +
    +import java.awt.Dimension;
    +import java.awt.Rectangle;
    +import java.io.BufferedReader;
    +import java.io.BufferedWriter;
    +import java.io.IOException;
    +import java.nio.file.FileSystems;
    +import java.nio.file.Files;
    +import java.nio.file.Path;
    +import java.nio.file.WatchEvent;
    +import java.nio.file.WatchKey;
    +import java.nio.file.WatchService;
    +import java.nio.file.attribute.PosixFilePermission;
    +import java.security.AccessController;
    +import java.security.PrivilegedAction;
    +import java.util.Arrays;
    +import java.util.HashSet;
    +import java.util.LinkedHashSet;
    +import java.util.List;
    +import java.util.Objects;
    +import java.util.Properties;
    +import java.util.Set;
    +
    +import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
    +import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
    +import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
    +import static java.nio.file.StandardWatchEventKinds.OVERFLOW;
    +import static sun.awt.screencast.ScreencastHelper.SCREENCAST_DEBUG;
    +
    +/**
    + * Helper class for persistent storage of ScreenCast restore tokens
    + * and associated screen boundaries.
    + *
    + * The restore token allows the ScreenCast session to be restored
    + * with previously granted screen access permissions.
    + */
    +@SuppressWarnings("removal")
    +final class TokenStorage {
    +
    +    private TokenStorage() {}
    +
    +    private static final String REL_NAME =
    +            ".awt/robot/screencast-tokens.properties";
    +
    +    private static final Properties PROPS = new Properties();
    +    private static final Path PROPS_PATH;
    +    private static final Path PROP_FILENAME;
    +
    +    private static void doPrivilegedRunnable(Runnable runnable) {
    +        AccessController.doPrivileged(new PrivilegedAction() {
    +            @Override
    +            public Void run() {
    +                runnable.run();
    +                return null;
    +            }
    +        });
    +    }
    +
    +    static {
    +        PROPS_PATH = AccessController.doPrivileged(new PrivilegedAction() {
    +            @Override
    +            public Path run() {
    +                return setupPath();
    +            }
    +        });
    +
    +        if (PROPS_PATH != null) {
    +            PROP_FILENAME = PROPS_PATH.getFileName();
    +            if (SCREENCAST_DEBUG) {
    +                System.out.println("Token storage: using " + PROPS_PATH);
    +            }
    +            setupWatch();
    +        } else {
    +            // We can still work with tokens,
    +            // but they are not saved between sessions.
    +            PROP_FILENAME = null;
    +        }
    +    }
    +
    +    private static Path setupPath() {
    +        String userHome = System.getProperty("user.home", null);
    +        if (userHome == null) {
    +            return null;
    +        }
    +
    +        Path path = Path.of(userHome, REL_NAME);
    +        Path workdir = path.getParent();
    +
    +        if (!Files.exists(workdir)) {
    +            try {
    +                Files.createDirectories(workdir);
    +            } catch (Exception e) {
    +                if (SCREENCAST_DEBUG) {
    +                    System.err.printf("Token storage: cannot create" +
    +                                    " directory %s %s\n", workdir, e);
    +                }
    +                return null;
    +            }
    +        }
    +
    +        if (!Files.isWritable(workdir)) {
    +            if (SCREENCAST_DEBUG) {
    +                System.err.printf("Token storage: %s is not writable\n", workdir);
    +            }
    +            return null;
    +        }
    +
    +        try {
    +            Files.setPosixFilePermissions(
    +                    workdir,
    +                    Set.of(PosixFilePermission.OWNER_READ,
    +                           PosixFilePermission.OWNER_WRITE,
    +                           PosixFilePermission.OWNER_EXECUTE)
    +            );
    +        } catch (IOException e) {
    +            if (SCREENCAST_DEBUG) {
    +                System.err.printf("Token storage: cannot set permissions " +
    +                        "for directory %s %s\n", workdir, e);
    +            }
    +        }
    +
    +        if (Files.exists(path)) {
    +            if (!setFilePermission(path)) {
    +                return null;
    +            }
    +
    +            readTokens(path);
    +        }
    +
    +        return path;
    +    }
    +
    +    private static boolean setFilePermission(Path path) {
    +        try {
    +            Files.setPosixFilePermissions(
    +                    path,
    +                    Set.of(PosixFilePermission.OWNER_READ,
    +                           PosixFilePermission.OWNER_WRITE)
    +            );
    +            return true;
    +        } catch (IOException e) {
    +            if (SCREENCAST_DEBUG) {
    +                System.err.printf("Token storage: failed to set " +
    +                        "property file permission %s %s\n", path, e);
    +            }
    +        }
    +        return false;
    +    }
    +
    +    private static class WatcherThread extends Thread {
    +        private final WatchService watcher;
    +
    +        public WatcherThread(WatchService watchService) {
    +            this.watcher = watchService;
    +            setName("ScreencastWatcher");
    +            setDaemon(true);
    +        }
    +
    +        @Override
    +        public void run() {
    +            if (SCREENCAST_DEBUG) {
    +                System.out.println("ScreencastWatcher: started");
    +            }
    +            for (;;) {
    +                WatchKey key;
    +                try {
    +                    key = watcher.take();
    +                } catch (InterruptedException e) {
    +                    if (SCREENCAST_DEBUG) {
    +                        System.err.println("ScreencastWatcher: interrupted");
    +                    }
    +                    return;
    +                }
    +
    +                for (WatchEvent event: key.pollEvents()) {
    +                    WatchEvent.Kind kind = event.kind();
    +                    if (kind == OVERFLOW
    +                            || !event.context().equals(PROP_FILENAME)) {
    +                        continue;
    +                    }
    +
    +                    if (SCREENCAST_DEBUG) {
    +                        System.out.printf("ScreencastWatcher: %s %s\n",
    +                                kind, event.context());
    +                    }
    +
    +                    if (kind == ENTRY_CREATE) {
    +                        doPrivilegedRunnable(() -> setFilePermission(PROPS_PATH));
    +                    } else if (kind == ENTRY_MODIFY) {
    +                        doPrivilegedRunnable(() -> readTokens(PROPS_PATH));
    +                    } else if (kind == ENTRY_DELETE) {
    +                        synchronized (PROPS) {
    +                            PROPS.clear();
    +                        }
    +                    }
    +                }
    +
    +                key.reset();
    +            }
    +        }
    +    }
    +
    +    private static WatchService watchService;
    +
    +    private static void setupWatch() {
    +        doPrivilegedRunnable(() -> {
    +            try {
    +                watchService =
    +                        FileSystems.getDefault().newWatchService();
    +
    +                PROPS_PATH
    +                        .getParent()
    +                        .register(watchService,
    +                                ENTRY_CREATE,
    +                                ENTRY_DELETE,
    +                                ENTRY_MODIFY);
    +
    +            } catch (Exception e) {
    +                if (SCREENCAST_DEBUG) {
    +                    System.err.printf("Token storage: failed to setup " +
    +                            "file watch %s\n", e);
    +                }
    +            }
    +        });
    +
    +        if (watchService != null) {
    +            new WatcherThread(watchService).start();
    +        }
    +    }
    +
    +    // called from native
    +    private static void storeTokenFromNative(String oldToken,
    +                                             String newToken,
    +                                             int[] allowedScreenBounds) {
    +        if (SCREENCAST_DEBUG) {
    +            System.out.printf("// storeToken old: |%s| new |%s| " +
    +                            "allowed bounds %s\n",
    +                    oldToken, newToken,
    +                    Arrays.toString(allowedScreenBounds));
    +        }
    +
    +        if (allowedScreenBounds == null) return;
    +
    +        TokenItem tokenItem = new TokenItem(newToken, allowedScreenBounds);
    +
    +        if (SCREENCAST_DEBUG) {
    +            System.out.printf("// Storing TokenItem:\n%s\n", tokenItem);
    +        }
    +
    +        synchronized (PROPS) {
    +            String oldBoundsRecord = PROPS.getProperty(tokenItem.token, null);
    +            String newBoundsRecord = tokenItem.dump();
    +
    +            boolean changed = false;
    +
    +            if (oldBoundsRecord == null
    +                    || !oldBoundsRecord.equals(newBoundsRecord)) {
    +                PROPS.setProperty(tokenItem.token, newBoundsRecord);
    +                if (SCREENCAST_DEBUG) {
    +                    System.out.printf(
    +                            "// Writing new TokenItem:\n%s\n", tokenItem);
    +                }
    +                changed = true;
    +            }
    +
    +            if (oldToken != null && !oldToken.equals(newToken)) {
    +                // old token is no longer valid
    +                if (SCREENCAST_DEBUG) {
    +                    System.out.printf(
    +                            "// storeTokenFromNative old token |%s| is "
    +                                    + "no longer valid, removing\n", oldToken);
    +                }
    +
    +                PROPS.remove(oldToken);
    +                changed = true;
    +            }
    +
    +            if (changed) {
    +                doPrivilegedRunnable(() -> store("save tokens"));
    +            }
    +        }
    +    }
    +
    +    private static boolean readTokens(Path path) {
    +        if (path == null) return false;
    +
    +        try (BufferedReader reader = Files.newBufferedReader(path)) {
    +            synchronized (PROPS) {
    +                PROPS.clear();
    +                PROPS.load(reader);
    +            }
    +        } catch (IOException e) {
    +            if (SCREENCAST_DEBUG) {
    +                System.err.printf("""
    +                        Token storage: failed to load property file %s
    +                        %s
    +                        """, path, e);
    +            }
    +            return false;
    +        }
    +
    +        return true;
    +    }
    +
    +    static Set getTokens(List affectedScreenBounds) {
    +        // We need an ordered set to store tokens
    +        // with exact matches at the beginning.
    +        LinkedHashSet result = new LinkedHashSet<>();
    +
    +        Set malformed = new HashSet<>();
    +        List allTokenItems;
    +
    +        synchronized (PROPS) {
    +            allTokenItems =
    +                    PROPS.entrySet()
    +                    .stream()
    +                    .map(o -> {
    +                        String token = String.valueOf(o.getKey());
    +                        TokenItem tokenItem =
    +                                TokenItem.parse(token, o.getValue());
    +                        if (tokenItem == null) {
    +                            malformed.add(token);
    +                        }
    +                        return tokenItem;
    +                    })
    +                    .filter(Objects::nonNull)
    +                    .sorted((t1, t2) -> //Token with more screens preferred
    +                            t2.allowedScreensBounds.size()
    +                            - t1.allowedScreensBounds.size()
    +                    )
    +                    .toList();
    +        }
    +
    +        doPrivilegedRunnable(() -> removeMalformedRecords(malformed));
    +
    +        // 1. Try to find exact matches
    +        for (TokenItem tokenItem : allTokenItems) {
    +            if (tokenItem != null
    +                && tokenItem.hasAllScreensWithExactMatch(affectedScreenBounds)) {
    +
    +                result.add(tokenItem);
    +            }
    +        }
    +
    +        if (SCREENCAST_DEBUG) {
    +            System.out.println("// getTokens exact matches 1. " + result);
    +        }
    +
    +        // 2. Try screens of the same size but in different locations,
    +        // screens may have been moved while the token is still valid
    +        List dimensions =
    +                affectedScreenBounds
    +                .stream()
    +                .map(rectangle -> new Dimension(
    +                        rectangle.width,
    +                        rectangle.height
    +                ))
    +                .toList();
    +
    +        for (TokenItem tokenItem : allTokenItems) {
    +            if (tokenItem != null
    +                && tokenItem.hasAllScreensOfSameSize(dimensions)) {
    +
    +                result.add(tokenItem);
    +            }
    +        }
    +
    +        if (SCREENCAST_DEBUG) {
    +            System.out.println("// getTokens same sizes 2. " + result);
    +        }
    +
    +        // 3. add tokens with the same or greater number of screens
    +        // This is useful if we once received a token with one screen resolution
    +        // and the same screen was later scaled in the system.
    +        // In that case, the token is still valid.
    +
    +        allTokenItems
    +                .stream()
    +                .filter(t ->
    +                        t.allowedScreensBounds.size() >= affectedScreenBounds.size())
    +                .forEach(result::add);
    +
    +        return result;
    +    }
    +
    +    private static void removeMalformedRecords(Set malformedRecords) {
    +        if (!isWritable()
    +            || malformedRecords == null
    +            || malformedRecords.isEmpty()) {
    +            return;
    +        }
    +
    +        synchronized (PROPS) {
    +            for (String token : malformedRecords) {
    +                Object remove = PROPS.remove(token);
    +                if (SCREENCAST_DEBUG) {
    +                    System.err.println("removing malformed record\n" + remove);
    +                }
    +            }
    +
    +            store("remove malformed records");
    +        }
    +    }
    +
    +    private static void store(String failMsg) {
    +        if (!isWritable()) {
    +            return;
    +        }
    +
    +        synchronized (PROPS) {
    +            try (BufferedWriter writer = Files.newBufferedWriter(PROPS_PATH)) {
    +                PROPS.store(writer, null);
    +            } catch (IOException e) {
    +                if (SCREENCAST_DEBUG) {
    +                    System.err.printf(
    +                            "Token storage: unable to %s\n%s\n", failMsg, e);
    +                }
    +            }
    +        }
    +    }
    +
    +    private static boolean isWritable() {
    +        if (PROPS_PATH == null
    +            || (Files.exists(PROPS_PATH) && !Files.isWritable(PROPS_PATH))) {
    +
    +            if (SCREENCAST_DEBUG) {
    +                System.err.printf(
    +                        "Token storage: %s is not writable\n", PROPS_PATH);
    +            }
    +            return false;
    +        } else {
    +            return true;
    +        }
    +    }
    +}
    diff -Nru openjdk-17-17.0.12+7/src/java.desktop/unix/classes/sun/java2d/opengl/GLXGraphicsConfig.java openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/java2d/opengl/GLXGraphicsConfig.java
    --- openjdk-17-17.0.12+7/src/java.desktop/unix/classes/sun/java2d/opengl/GLXGraphicsConfig.java	2024-07-09 08:19:46.000000000 +0000
    +++ openjdk-17-17.0.13+11/src/java.desktop/unix/classes/sun/java2d/opengl/GLXGraphicsConfig.java	2024-10-10 14:01:59.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2003, 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
    @@ -216,7 +216,7 @@
         }
     
         /**
    -     * The following methods are invoked from MToolkit or XToolkit.java and
    +     * The following methods are invoked from XToolkit.java and
          * X11ComponentPeer.java rather than having the X11-dependent
          * implementations hardcoded in those classes.  This way the appropriate
          * actions are taken based on the peer's GraphicsConfig, whether it is
    diff -Nru openjdk-17-17.0.12+7/src/java.desktop/unix/legal/pipewire.md openjdk-17-17.0.13+11/src/java.desktop/unix/legal/pipewire.md
    --- openjdk-17-17.0.12+7/src/java.desktop/unix/legal/pipewire.md	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.13+11/src/java.desktop/unix/legal/pipewire.md	2024-10-10 14:01:59.000000000 +0000
    @@ -0,0 +1,41 @@
    +## PipeWire 0.3.68
    +
    +### PipeWire license:
    +
    +All PipeWire header files are licensed under the MIT License:
    +
    +
    +
    +Copyright © 2018-2023 Wim Taymans
    +
    +Permission is hereby granted, free of charge, to any person obtaining a
    +copy of this software and associated documentation files (the "Software"),
    +to deal in the Software without restriction, including without limitation
    +the rights to use, copy, modify, merge, publish, distribute, sublicense,
    +and/or sell copies of the Software, and to permit persons to whom the
    +Software is furnished to do so, subject to the following conditions:
    +
    +The above copyright notice and this permission notice (including the next
    +paragraph) shall be included in all copies or substantial portions of the
    +Software.
    +
    +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
    +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    +DEALINGS IN THE SOFTWARE.
    +
    + +The below copyright applies to the following files: + +spa/include/spa/monitor/type-info.h +``` +Copyright © 2021 Collabora Ltd. +``` + +spa/include/spa/utils/string.h +``` +Copyright © 2021 Red Hat, Inc. +``` diff -Nru openjdk-17-17.0.12+7/src/java.desktop/unix/native/common/awt/awt.h openjdk-17-17.0.13+11/src/java.desktop/unix/native/common/awt/awt.h --- openjdk-17-17.0.12+7/src/java.desktop/unix/native/common/awt/awt.h 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/unix/native/common/awt/awt.h 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 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 @@ -41,7 +41,7 @@ #endif /* !HEADLESS && !MACOSX */ -/* The JVM instance: defined in awt_MToolkit.c */ +/* The JVM instance: defined in awt_LoadLibrary.c */ extern JavaVM *jvm; extern jclass tkClass; diff -Nru openjdk-17-17.0.12+7/src/java.desktop/unix/native/libawt_xawt/awt/fp_pipewire.h openjdk-17-17.0.13+11/src/java.desktop/unix/native/libawt_xawt/awt/fp_pipewire.h --- openjdk-17-17.0.12+7/src/java.desktop/unix/native/libawt_xawt/awt/fp_pipewire.h 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/unix/native/libawt_xawt/awt/fp_pipewire.h 2024-10-10 14:01:59.000000000 +0000 @@ -0,0 +1,91 @@ +/* + * 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. + */ + +#ifdef HEADLESS +#error This file should not be included in headless library +#endif +#ifndef _FP_PIPEWIRE_H +#define _FP_PIPEWIRE_H + + +struct pw_buffer *(*fp_pw_stream_dequeue_buffer)(struct pw_stream *stream); +const char * (*fp_pw_stream_state_as_string)(enum pw_stream_state state); +int (*fp_pw_stream_queue_buffer)(struct pw_stream *stream, + struct pw_buffer *buffer); +int (*fp_pw_stream_set_active)(struct pw_stream *stream, bool active); + +int (*fp_pw_stream_connect)( + struct pw_stream *stream, + enum pw_direction direction, + uint32_t target_id, + enum pw_stream_flags flags, + const struct spa_pod **params, + uint32_t n_params); + +struct pw_stream *(*fp_pw_stream_new)( + struct pw_core *core, + const char *name, + struct pw_properties *props +); +void (*fp_pw_stream_add_listener)(struct pw_stream *stream, + struct spa_hook *listener, + const struct pw_stream_events *events, + void *data); +int (*fp_pw_stream_disconnect)(struct pw_stream *stream); +void (*fp_pw_stream_destroy)(struct pw_stream *stream); + + +void (*fp_pw_init)(int *argc, char **argv[]); +void (*fp_pw_deinit)(void); + +struct pw_core * +(*fp_pw_context_connect_fd)(struct pw_context *context, + int fd, + struct pw_properties *properties, + size_t user_data_size); + +int (*fp_pw_core_disconnect)(struct pw_core *core); + +struct pw_context * (*fp_pw_context_new)(struct pw_loop *main_loop, + struct pw_properties *props, + size_t user_data_size); + +struct pw_thread_loop * +(*fp_pw_thread_loop_new)(const char *name, const struct spa_dict *props); +struct pw_loop * (*fp_pw_thread_loop_get_loop)(struct pw_thread_loop *loop); +void (*fp_pw_thread_loop_signal)(struct pw_thread_loop *loop, + bool wait_for_accept); +void (*fp_pw_thread_loop_wait)(struct pw_thread_loop *loop); +void (*fp_pw_thread_loop_accept)(struct pw_thread_loop *loop); +int (*fp_pw_thread_loop_start)(struct pw_thread_loop *loop); +void (*fp_pw_thread_loop_stop)(struct pw_thread_loop *loop); +void (*fp_pw_thread_loop_destroy)(struct pw_thread_loop *loop); +void (*fp_pw_thread_loop_lock)(struct pw_thread_loop *loop); +void (*fp_pw_thread_loop_unlock)(struct pw_thread_loop *loop); + +struct pw_properties * (*fp_pw_properties_new)(const char *key, ...); + + +#endif //_FP_PIPEWIRE_H diff -Nru openjdk-17-17.0.12+7/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.h openjdk-17-17.0.13+11/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.h --- openjdk-17-17.0.12+7/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.h 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.h 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -88,13 +88,6 @@ typedef struct { gint x; - gint y; - gint width; - gint height; -} GdkRectangle; - -typedef struct { - gint x; gint y; gint width; gint height; diff -Nru openjdk-17-17.0.12+7/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c openjdk-17-17.0.13+11/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c --- openjdk-17-17.0.12+7/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -42,6 +42,10 @@ static void *gtk3_libhandle = NULL; static void *gthread_libhandle = NULL; +static void transform_detail_string (const gchar *detail, + GtkStyleContext *context); +static void gtk3_init(GtkApi* gtk); + static jmp_buf j; /* Widgets */ @@ -244,6 +248,7 @@ static gboolean gtk3_version_3_10 = TRUE; static gboolean gtk3_version_3_14 = FALSE; static gboolean gtk3_version_3_20 = FALSE; +gboolean glib_version_2_68 = FALSE; GtkApi* gtk3_load(JNIEnv *env, const char* lib_name) { @@ -312,6 +317,10 @@ /* Pixbuf */ fp_gdk_pixbuf_new = dl_symbol("gdk_pixbuf_new"); + fp_gdk_pixbuf_new_from_data = dl_symbol("gdk_pixbuf_new_from_data"); + fp_gdk_pixbuf_scale_simple = dl_symbol("gdk_pixbuf_scale_simple"); + fp_gdk_pixbuf_copy_area = dl_symbol("gdk_pixbuf_copy_area"); + fp_gdk_pixbuf_new_from_file = dl_symbol("gdk_pixbuf_new_from_file"); fp_gdk_pixbuf_get_from_drawable = @@ -565,6 +574,51 @@ fp_g_list_append = dl_symbol("g_list_append"); fp_g_list_free = dl_symbol("g_list_free"); fp_g_list_free_full = dl_symbol("g_list_free_full"); + + /** + * other + */ + + fp_g_bus_get_sync = dl_symbol("g_bus_get_sync"); + fp_g_dbus_proxy_call_sync = dl_symbol("g_dbus_proxy_call_sync"); + fp_g_dbus_proxy_new_sync = dl_symbol("g_dbus_proxy_new_sync"); + fp_g_dbus_connection_get_unique_name = dl_symbol("g_dbus_connection_get_unique_name"); + fp_g_dbus_connection_call_sync = dl_symbol("g_dbus_connection_call_sync"); + fp_g_dbus_connection_signal_subscribe = dl_symbol("g_dbus_connection_signal_subscribe"); + fp_g_dbus_connection_signal_unsubscribe = dl_symbol("g_dbus_connection_signal_unsubscribe"); + fp_g_dbus_proxy_call_with_unix_fd_list_sync = dl_symbol("g_dbus_proxy_call_with_unix_fd_list_sync"); + + fp_g_variant_builder_init = dl_symbol("g_variant_builder_init"); + fp_g_variant_builder_add = dl_symbol("g_variant_builder_add"); + fp_g_variant_new = dl_symbol("g_variant_new"); + fp_g_variant_new_string = dl_symbol("g_variant_new_string"); + fp_g_variant_new_uint32 = dl_symbol("g_variant_new_uint32"); + fp_g_variant_new_boolean = dl_symbol("g_variant_new_boolean"); + fp_g_variant_get = dl_symbol("g_variant_get"); + fp_g_variant_get_string = dl_symbol("g_variant_get_string"); + fp_g_variant_get_uint32 = dl_symbol("g_variant_get_uint32"); + fp_g_variant_iter_loop = dl_symbol("g_variant_iter_loop"); + fp_g_variant_unref = dl_symbol("g_variant_unref"); + fp_g_variant_lookup = dl_symbol("g_variant_lookup"); + fp_g_variant_lookup_value = dl_symbol("g_variant_lookup_value"); + fp_g_variant_iter_init = dl_symbol("g_variant_iter_init"); + fp_g_variant_iter_n_children = dl_symbol("g_variant_iter_n_children"); + + fp_g_string_new = dl_symbol("g_string_new"); + fp_g_string_erase = dl_symbol("g_string_erase"); + fp_g_string_set_size = dl_symbol("g_string_set_size"); + fp_g_string_free = dl_symbol("g_string_free"); + + glib_version_2_68 = !fp_glib_check_version(2, 68, 0); + if (glib_version_2_68) { + fp_g_string_replace = dl_symbol("g_string_replace"); //since: 2.68 + fp_g_uuid_string_is_valid = //since: 2.52 + dl_symbol("g_uuid_string_is_valid"); + } + fp_g_string_printf = dl_symbol("g_string_printf"); + + fp_g_error_free = dl_symbol("g_error_free"); + fp_g_unix_fd_list_get = dl_symbol("g_unix_fd_list_get"); } /* Now we have only one kind of exceptions: NO_SYMBOL_EXCEPTION * Otherwise we can check the return value of setjmp method. @@ -3008,4 +3062,53 @@ gtk->g_list_append = fp_g_list_append; gtk->g_list_free = fp_g_list_free; gtk->g_list_free_full = fp_g_list_free_full; + + gtk->g_bus_get_sync = fp_g_bus_get_sync; + gtk->g_dbus_proxy_call_sync = fp_g_dbus_proxy_call_sync; + gtk->g_dbus_proxy_new_sync = fp_g_dbus_proxy_new_sync; + gtk->g_dbus_connection_get_unique_name = fp_g_dbus_connection_get_unique_name; + gtk->g_dbus_connection_signal_subscribe = fp_g_dbus_connection_signal_subscribe; + gtk->g_dbus_connection_signal_unsubscribe = fp_g_dbus_connection_signal_unsubscribe; + gtk->g_dbus_proxy_call_with_unix_fd_list_sync = fp_g_dbus_proxy_call_with_unix_fd_list_sync; + gtk->g_dbus_connection_call_sync = fp_g_dbus_connection_call_sync; + + gtk->g_variant_new = fp_g_variant_new; + gtk->g_variant_new_string = fp_g_variant_new_string; + gtk->g_variant_new_boolean = fp_g_variant_new_boolean; + gtk->g_variant_new_uint32 = fp_g_variant_new_uint32; + + gtk->g_variant_get = fp_g_variant_get; + gtk->g_variant_get_string = fp_g_variant_get_string; + gtk->g_variant_get_uint32 = fp_g_variant_get_uint32; + + gtk->g_variant_lookup = fp_g_variant_lookup; + + gtk->g_variant_iter_loop = fp_g_variant_iter_loop; + + gtk->g_variant_unref = fp_g_variant_unref; + + gtk->g_variant_builder_init = fp_g_variant_builder_init; + gtk->g_variant_builder_add = fp_g_variant_builder_add; + + gtk->g_variant_lookup_value = fp_g_variant_lookup_value; + gtk->g_variant_iter_init = fp_g_variant_iter_init; + gtk->g_variant_iter_n_children = fp_g_variant_iter_n_children; + + gtk->g_string_new = fp_g_string_new; + gtk->g_string_erase = fp_g_string_erase; + gtk->g_string_set_size = fp_g_string_set_size; + gtk->g_string_free = fp_g_string_free; + gtk->g_string_replace = fp_g_string_replace; + gtk->g_string_printf = fp_g_string_printf; + gtk->g_uuid_string_is_valid = fp_g_uuid_string_is_valid; + + gtk->g_main_context_iteration = fp_g_main_context_iteration; + gtk->g_error_free = fp_g_error_free; + gtk->g_unix_fd_list_get = fp_g_unix_fd_list_get; + + gtk->gdk_pixbuf_new = fp_gdk_pixbuf_new; + gtk->gdk_pixbuf_new_from_data = fp_gdk_pixbuf_new_from_data; + gtk->gdk_pixbuf_scale_simple = fp_gdk_pixbuf_scale_simple; + gtk->gdk_pixbuf_get_pixels = fp_gdk_pixbuf_get_pixels; + gtk->gdk_pixbuf_copy_area = fp_gdk_pixbuf_copy_area; } diff -Nru openjdk-17-17.0.12+7/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.h openjdk-17-17.0.13+11/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.h --- openjdk-17-17.0.12+7/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.h 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.h 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -236,13 +236,6 @@ } GPollFD; typedef struct { - gint x; - gint y; - gint width; - gint height; -} GdkRectangle; - -typedef struct { int x, y; int width, height; } GtkAllocation; @@ -375,7 +368,6 @@ guint32 timestamp, GError **error); // Implementation functions prototypes -static void gtk3_init(GtkApi* gtk); static GValue* (*fp_g_value_init)(GValue *value, GType g_type); static gboolean (*fp_g_type_is_a)(GType type, GType is_a_type); static gboolean (*fp_g_value_get_boolean)(const GValue *value); @@ -494,16 +486,15 @@ gdouble x, gdouble y, gdouble width, gdouble height); static gboolean (*fp_gtk_style_context_has_class)(GtkStyleContext *context, const gchar *class_name); -static void transform_detail_string (const gchar *detail, - GtkStyleContext *context); -void (*fp_gtk_style_context_set_junction_sides)(GtkStyleContext *context, + +static void (*fp_gtk_style_context_set_junction_sides)(GtkStyleContext *context, GtkJunctionSides sides); -void (*fp_gtk_style_context_add_region)(GtkStyleContext *context, +static void (*fp_gtk_style_context_add_region)(GtkStyleContext *context, const gchar *region_name, GtkRegionFlags flags); -void (*fp_gtk_render_arrow)(GtkStyleContext *context, cairo_t *cr, +static void (*fp_gtk_render_arrow)(GtkStyleContext *context, cairo_t *cr, gdouble angle, gdouble x, gdouble y, gdouble size); -void (*fp_gtk_bin_set_child)(GtkBin *bin, GtkWidget *widget); -void (*fp_gtk_scrolled_window_set_shadow_type)( +static void (*fp_gtk_bin_set_child)(GtkBin *bin, GtkWidget *widget); +static void (*fp_gtk_scrolled_window_set_shadow_type)( GtkScrolledWindow *scrolled_window, GtkShadowType type); static void (*fp_gtk_render_slider)(GtkStyleContext *context, cairo_t *cr, gdouble x, gdouble y, gdouble width, gdouble height, @@ -522,7 +513,7 @@ static void (*fp_gtk_adjustment_set_lower)(GtkAdjustment *adjustment, gdouble lower); static void (*fp_gtk_adjustment_set_page_increment)(GtkAdjustment *adjustment, - gdouble page_increment); + gdouble page_increment); static void (*fp_gtk_adjustment_set_page_size)(GtkAdjustment *adjustment, gdouble page_size); static void (*fp_gtk_adjustment_set_step_increment)(GtkAdjustment *adjustment, @@ -537,6 +528,30 @@ gint, gint, gint, gint); static GdkPixbuf *(*fp_gdk_pixbuf_new)(GdkColorspace colorspace, gboolean has_alpha, int bits_per_sample, int width, int height); + +static GdkPixbuf *(*fp_gdk_pixbuf_new_from_data)( + const guchar *data, + GdkColorspace colorspace, + gboolean has_alpha, + int bits_per_sample, + int width, + int height, + int rowstride, + GdkPixbufDestroyNotify destroy_fn, + gpointer destroy_fn_data +); + +static void (*fp_gdk_pixbuf_copy_area) ( + const GdkPixbuf* src_pixbuf, + int src_x, + int src_y, + int width, + int height, + GdkPixbuf* dest_pixbuf, + int dest_x, + int dest_y +); + static void (*fp_gdk_drawable_get_size)(GdkDrawable *drawable, gint* width, gint* height); static gboolean (*fp_gtk_init_check)(int* argc, char** argv); @@ -637,4 +652,159 @@ static void (*fp_gtk_widget_path_unref) (GtkWidgetPath *path); static GtkStyleContext* (*fp_gtk_style_context_new) (void); + +// ---------- fp_g_dbus_* ---------- +static GVariant *(*fp_g_dbus_proxy_call_sync)( + GDBusProxy *proxy, + const gchar *method_name, + GVariant *parameters, + GDBusCallFlags flags, + gint timeout_msec, + GCancellable *cancellable, + GError **error +); + +static GDBusProxy *(*fp_g_dbus_proxy_new_sync)( + GDBusConnection *connection, + GDBusProxyFlags flags, + GDBusInterfaceInfo *info, + const gchar *name, + const gchar *object_path, + const gchar *interface_name, + GCancellable *cancellable, + GError **error +); + +static const gchar *(*fp_g_dbus_connection_get_unique_name)( + GDBusConnection *connection +); + +static GDBusConnection *(*fp_g_bus_get_sync)(GBusType bus_type, + GCancellable *cancellable, + GError **error); + +static guint (*fp_g_dbus_connection_signal_subscribe)( + GDBusConnection *connection, + const gchar *sender, + const gchar *interface_name, + const gchar *member, + const gchar *object_path, + const gchar *arg0, + GDBusSignalFlags flags, + GDBusSignalCallback callback, + gpointer user_data, + GDestroyNotify user_data_free_func +); + +static void (*fp_g_dbus_connection_signal_unsubscribe)( + GDBusConnection *connection, + guint subscription_id +); + +static GVariant *(*fp_g_dbus_proxy_call_with_unix_fd_list_sync)( + GDBusProxy *proxy, + const gchar *method_name, + GVariant *parameters, + GDBusCallFlags flags, + gint timeout_msec, + GUnixFDList *fd_list, + GUnixFDList **out_fd_list, + GCancellable *cancellable, + GError **error +); + +static GVariant *(*fp_g_dbus_connection_call_sync)( + GDBusConnection *connection, + const gchar *bus_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + const GVariantType *reply_type, + GDBusCallFlags flags, + gint timeout_msec, + GCancellable *cancellable, + GError **error +); + +// ---------- fp_g_variant_* ---------- + +static GVariant *(*fp_g_variant_new)(const gchar *format_string, ...); + +static GVariant *(*fp_g_variant_new_string)(const gchar *string); + +static GVariant *(*fp_g_variant_new_boolean)(gboolean value); + +static GVariant *(*fp_g_variant_new_uint32)(guint32 value); + +static void (*fp_g_variant_get)(GVariant *value, + const gchar *format_string, + ...); + +static const gchar *(*fp_g_variant_get_string)(GVariant *value, + gsize *length); + +static guint32 (*fp_g_variant_get_uint32)(GVariant *value); + +static gboolean (*fp_g_variant_lookup)(GVariant *dictionary, + const gchar *key, + const gchar *format_string, + ...); + +static gboolean (*fp_g_variant_iter_loop)(GVariantIter *iter, + const gchar *format_string, + ...); + +static void (*fp_g_variant_unref)(GVariant *value); + +static void (*fp_g_variant_builder_init)(GVariantBuilder *builder, + const GVariantType *type); + +static void (*fp_g_variant_builder_add)(GVariantBuilder *builder, + const gchar *format_string, + ...); + +static GVariant *(*fp_g_variant_lookup_value)(GVariant *dictionary, + const gchar *key, + const GVariantType *expected_type); + +static gsize (*fp_g_variant_iter_init)(GVariantIter *iter, + GVariant *value); + +static gsize (*fp_g_variant_iter_n_children)(GVariantIter *iter); + + +// ---------- fp_g_string_* ---------- + +static GString *(*fp_g_string_new)(const gchar *init); + +static GString *(*fp_g_string_erase)(GString *string, + gssize pos, + gssize len); + +static GString *(*fp_g_string_set_size)(GString* string, + gsize len); + +static gchar *(*fp_g_string_free)(GString *string, + gboolean free_segment); + +static guint (*fp_g_string_replace)(GString *string, + const gchar *find, + const gchar *replace, + guint limit); + +static void *(*fp_g_string_printf)(GString *string, + const gchar *format, + ...); + +static gboolean (*fp_g_uuid_string_is_valid)(const gchar *str); + + +// ---------- * ---------- +static void (*fp_g_error_free)(GError *error); + +static gint (*fp_g_unix_fd_list_get)(GUnixFDList *list, + gint index_, + GError **error); + #endif /* !_GTK3_INTERFACE_H */ diff -Nru openjdk-17-17.0.12+7/src/java.desktop/unix/native/libawt_xawt/awt/gtk_interface.h openjdk-17-17.0.13+11/src/java.desktop/unix/native/libawt_xawt/awt/gtk_interface.h --- openjdk-17-17.0.12+7/src/java.desktop/unix/native/libawt_xawt/awt/gtk_interface.h 2024-07-09 08:19:46.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/unix/native/libawt_xawt/awt/gtk_interface.h 2024-10-10 14:01:59.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -108,7 +108,7 @@ typedef unsigned short guint16; typedef unsigned int guint; typedef unsigned int guint32; -typedef unsigned int gsize; +typedef unsigned long gsize; typedef unsigned long gulong; typedef signed long long gint64; typedef unsigned long long guint64; @@ -128,6 +128,93 @@ GSList *next; }; +typedef signed long gssize; +typedef struct _GString GString; + +struct _GString +{ + gchar *str; + gsize len; + gsize allocated_len; +}; + +typedef struct _GVariant GVariant; +typedef struct _GVariantIter GVariantIter; +struct _GVariantIter { + /*< private >*/ + gsize x[16]; +}; + +typedef struct _GVariantType GVariantType; +typedef struct _GVariantBuilder GVariantBuilder; + +struct _GVariantBuilder { + /*< private >*/ + union + { + struct { + gsize partial_magic; + const GVariantType *type; + gsize y[14]; + } s; + gsize x[16]; + } u; +}; + + +#define G_VARIANT_TYPE_VARDICT ((const GVariantType *) "a{sv}") +#define G_VARIANT_TYPE_ARRAY ((const GVariantType *) "a*") +#define G_VARIANT_TYPE_STRING ((const GVariantType *) "s") + +typedef struct _GDBusProxy GDBusProxy; +typedef enum { + G_DBUS_CALL_FLAGS_NONE = 0, + G_DBUS_CALL_FLAGS_NO_AUTO_START = (1<<0), + G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION = (1<<1) +} GDBusCallFlags; + +typedef void GMainContext; +typedef void GUnixFDList; + +typedef void GDBusConnection; +typedef enum /*< flags >*/ +{ + G_DBUS_SIGNAL_FLAGS_NONE = 0, + G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE = (1<<0), + G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE = (1<<1), + G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH = (1<<2) +} GDBusSignalFlags; + +typedef void (*GDBusSignalCallback) (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data); + +typedef struct _GCancellable GCancellable; + +typedef enum +{ + G_BUS_TYPE_STARTER = -1, + G_BUS_TYPE_NONE = 0, + G_BUS_TYPE_SYSTEM = 1, + G_BUS_TYPE_SESSION = 2 +} GBusType; + +typedef enum +{ + G_DBUS_PROXY_FLAGS_NONE = 0, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES = (1<<0), + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS = (1<<1), + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START = (1<<2), + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES = (1<<3), + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START_AT_CONSTRUCTION = (1<<4) +} GDBusProxyFlags; + +typedef struct _GDBusInterfaceInfo GDBusInterfaceInfo; + typedef enum { BUTTON, /* GtkButton */ CHECK_BOX, /* GtkCheckButton */ @@ -409,14 +496,29 @@ } GConnectFlags; //------------------------------ +typedef guint32 GQuark; +struct _GError +{ + GQuark domain; + gint code; + gchar *message; +}; +typedef struct _GError GError; -typedef void GError; typedef void GdkScreen; typedef void GtkWindow; typedef void GdkWindow; typedef void GClosure; typedef void GtkFileChooser; typedef void GtkFileFilter; + +typedef struct { + gint x; + gint y; + gint width; + gint height; +} GdkRectangle; + typedef struct { GtkFileFilterFlags contains; const gchar *filename; @@ -430,6 +532,8 @@ typedef void (*GDestroyNotify)(gpointer data); typedef void (*GCallback)(void); +typedef void GdkPixbuf; +typedef void (* GdkPixbufDestroyNotify) (guchar *pixels, gpointer data); typedef struct GtkApi { int version; @@ -513,7 +617,6 @@ jint jwidth, int dx, int dy, jint scale); void (*g_free)(gpointer mem); - gchar* (*gtk_file_chooser_get_filename)(GtkFileChooser *chooser); void (*gtk_widget_hide)(void* widget); void (*gtk_main_quit)(void); @@ -558,6 +661,185 @@ GList* (*g_list_append) (GList *list, gpointer data); void (*g_list_free) (GList *list); void (*g_list_free_full) (GList *list, GDestroyNotify free_func); + + + /* */ + GVariant *(*g_dbus_proxy_call_sync)( + GDBusProxy *proxy, + const gchar *method_name, + GVariant *parameters, + GDBusCallFlags flags, + gint timeout_msec, + GCancellable *cancellable, + GError **error); + + GVariant *(*g_variant_new)(const gchar *format_string, ...); + GVariant *(*g_variant_new_string)(const gchar *string); + GVariant *(*g_variant_new_boolean)(gboolean value); + GVariant *(*g_variant_new_uint32)(guint32 value); + + + void (*g_variant_get)(GVariant *value, + const gchar *format_string, + ...); + const gchar *(*g_variant_get_string)(GVariant *value, gsize *length); + guint32 (*g_variant_get_uint32)(GVariant *value); + + gboolean (*g_variant_lookup)(GVariant *dictionary, + const gchar *key, + const gchar *format_string, + ...); + gboolean (*g_variant_iter_loop)(GVariantIter *iter, + const gchar *format_string, + ...); + + void (*g_variant_unref)(GVariant *value); + + void (*g_variant_builder_init)(GVariantBuilder *builder, //+ + const GVariantType *type); + + void (*g_variant_builder_add)(GVariantBuilder *builder, //+ + const gchar *format_string, + ...); + + GVariant *(*g_variant_lookup_value)(GVariant *dictionary, + const gchar *key, + const GVariantType *expected_type); + + gsize (*g_variant_iter_init)(GVariantIter *iter, + GVariant *value); + + gsize (*g_variant_iter_n_children)(GVariantIter *iter); + + + GString *(*g_string_new)(const gchar *init); + + GString *(*g_string_erase)(GString *string, + gssize pos, + gssize len); + + GString *(*g_string_set_size)(GString* string, + gsize len); + + + gchar *(*g_string_free)(GString *string, + gboolean free_segment); + + guint (*g_string_replace)(GString *string, + const gchar *find, + const gchar *replace, + guint limit); + + void *(*g_string_printf)(GString *string, + const gchar *format, + ...); + + gboolean (*g_uuid_string_is_valid)(const gchar *str); + + + GDBusConnection *(*g_bus_get_sync)(GBusType bus_type, + GCancellable *cancellable, + GError **error); + + GDBusProxy *(*g_dbus_proxy_new_sync)(GDBusConnection *connection, + GDBusProxyFlags flags, + GDBusInterfaceInfo *info, + const gchar *name, + const gchar *object_path, + const gchar *interface_name, + GCancellable *cancellable, + GError **error); + + const gchar *(*g_dbus_connection_get_unique_name)(GDBusConnection *connection); + + + + guint (*g_dbus_connection_signal_subscribe)(GDBusConnection *connection, + const gchar *sender, + const gchar *interface_name, + const gchar *member, + const gchar *object_path, + const gchar *arg0, + GDBusSignalFlags flags, + GDBusSignalCallback callback, + gpointer user_data, + GDestroyNotify user_data_free_func); + + void (*g_dbus_connection_signal_unsubscribe)(GDBusConnection *connection, + guint subscription_id); + + GVariant *(*g_dbus_proxy_call_with_unix_fd_list_sync)(GDBusProxy *proxy, + const gchar *method_name, + GVariant *parameters, + GDBusCallFlags flags, + gint timeout_msec, + GUnixFDList *fd_list, + GUnixFDList **out_fd_list, + GCancellable *cancellable, + GError **error); + + GVariant *(*g_dbus_connection_call_sync)(GDBusConnection *connection, + const gchar *bus_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + const GVariantType *reply_type, + GDBusCallFlags flags, + gint timeout_msec, + GCancellable *cancellable, + GError **error); + + gboolean (*g_main_context_iteration)(GMainContext *context, + gboolean may_block); + + void (*g_error_free)(GError *error); + + gint (*g_unix_fd_list_get)(GUnixFDList *list, + gint index_, + GError **error); + + GdkPixbuf *(*gdk_pixbuf_new)(GdkColorspace colorspace, + gboolean has_alpha, + int bits_per_sample, + int width, + int height); + + + GdkPixbuf *(*gdk_pixbuf_new_from_data)( + const guchar *data, + GdkColorspace colorspace, + gboolean has_alpha, + int bits_per_sample, + int width, + int height, + int rowstride, + GdkPixbufDestroyNotify destroy_fn, + gpointer destroy_fn_data + ); + + + GdkPixbuf *(*gdk_pixbuf_scale_simple)(GdkPixbuf *src, + int dest_width, + int dest_heigh, + GdkInterpType interp_type + ); + + guchar* (*gdk_pixbuf_get_pixels) (const GdkPixbuf* pixbuf); + + + void (*gdk_pixbuf_copy_area) ( + const GdkPixbuf* src_pixbuf, + int src_x, + int src_y, + int width, + int height, + GdkPixbuf* dest_pixbuf, + int dest_x, + int dest_y + ); + + /* */ } GtkApi; gboolean gtk_load(JNIEnv *env, GtkVersion version, gboolean verbose); diff -Nru openjdk-17-17.0.12+7/src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.c openjdk-17-17.0.13+11/src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.c --- openjdk-17-17.0.12+7/src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.c 2024-10-10 14:01:59.000000000 +0000 @@ -0,0 +1,1038 @@ +/* + * 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. + */ + +#ifdef HEADLESS +#error This file should not be included in headless library +#endif + +#include +#include "jni_util.h" +#include "awt.h" +#include "screencast_pipewire.h" +#include "fp_pipewire.h" +#include + +#include "gtk_interface.h" +#include "gtk3_interface.h" + +int DEBUG_SCREENCAST_ENABLED = FALSE; + +#define EXCEPTION_CHECK_DESCRIBE() if ((*env)->ExceptionCheck(env)) { \ + (*env)->ExceptionDescribe(env); \ + } + +static gboolean hasPipewireFailed = FALSE; +static gboolean sessionClosed = TRUE; +static GString *activeSessionToken; + +struct ScreenSpace screenSpace = {0}; +static struct PwLoopData pw = {0}; + +jclass tokenStorageClass = NULL; +jmethodID storeTokenMethodID = NULL; + +#if defined(AIX) && defined(__open_xl_version__) && __open_xl_version__ >= 17 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +#endif + +inline void debug_screencast( + const char *__restrict fmt, + ... +) { + if (DEBUG_SCREENCAST_ENABLED) { + va_list myargs; + va_start(myargs, fmt); + vfprintf(stdout, fmt, myargs); + va_end(myargs); + } +} + +/** + * @return TRUE on success + */ +static gboolean initScreenSpace() { + screenSpace.screenCount = 0; + screenSpace.allocated = SCREEN_SPACE_DEFAULT_ALLOCATED; + screenSpace.screens = calloc( + SCREEN_SPACE_DEFAULT_ALLOCATED, + sizeof(struct ScreenProps) + ); + + if (!screenSpace.screens) { + ERR("failed to allocate memory\n"); + return FALSE; + } + return TRUE; +} + +static void doCleanup() { + if (pw.loop) { + DEBUG_SCREENCAST("STOPPING loop\n", NULL); + fp_pw_thread_loop_stop(pw.loop); + } + + for (int i = 0; i < screenSpace.screenCount; ++i) { + struct ScreenProps *screenProps = &screenSpace.screens[i]; + if (screenProps->data) { + if (screenProps->data->stream) { + fp_pw_thread_loop_lock(pw.loop); + fp_pw_stream_disconnect(screenProps->data->stream); + fp_pw_stream_destroy(screenProps->data->stream); + fp_pw_thread_loop_unlock(pw.loop); + screenProps->data->stream = NULL; + } + free(screenProps->data); + screenProps->data = NULL; + } + } + + if (pw.pwFd > 0) { + close(pw.pwFd); + pw.pwFd = -1; + } + + portalScreenCastCleanup(); + + if (pw.core) { + fp_pw_core_disconnect(pw.core); + pw.core = NULL; + } + + if (pw.loop) { + fp_pw_thread_loop_destroy(pw.loop); + pw.loop = NULL; + } + + if (screenSpace.screens) { + free(screenSpace.screens); + screenSpace.screens = NULL; + screenSpace.screenCount = 0; + } + + if (!sessionClosed) { + fp_pw_deinit(); + } + + gtk->g_string_set_size(activeSessionToken, 0); + sessionClosed = TRUE; +} + +/** + * @return TRUE on success + */ +static gboolean initScreencast(const gchar *token, + GdkRectangle *affectedBounds, + gint affectedBoundsLength) { + gboolean isSameToken = !token + ? FALSE + : strcmp(token, activeSessionToken->str) == 0; + + if (!sessionClosed) { + if (isSameToken) { + DEBUG_SCREENCAST("Reusing active session.\n", NULL); + return TRUE; + } else { + DEBUG_SCREENCAST( + "Active session has a different token |%s| -> |%s|," + " closing current session.\n", + activeSessionToken->str, token + ); + doCleanup(); + } + } + + fp_pw_init(NULL, NULL); + + pw.pwFd = RESULT_ERROR; + + if (!initScreenSpace() + || !initXdgDesktopPortal() + || (pw.pwFd = getPipewireFd(token, + affectedBounds, + affectedBoundsLength)) < 0) { + doCleanup(); + return FALSE; + } + + gtk->g_string_printf(activeSessionToken, "%s", token); + hasPipewireFailed = FALSE; + sessionClosed = FALSE; + return TRUE; +} + +static void onStreamParamChanged( + void *userdata, + uint32_t id, + const struct spa_pod *param +) { + struct PwStreamData *data = userdata; + uint32_t mediaType; + uint32_t mediaSubtype; + + DEBUG_SCREEN_PREFIX(data->screenProps, "param event id %i\n", id); + + if (param == NULL || id != SPA_PARAM_Format) { + return; + } + + if (spa_format_parse(param, + &mediaType, + &mediaSubtype) < 0) { + return; + } + + if (mediaType != SPA_MEDIA_TYPE_video || + mediaSubtype != SPA_MEDIA_SUBTYPE_raw) { + return; + } + + if (spa_format_video_raw_parse(param, &data->rawFormat) < 0) { + return; + } + + DEBUG_SCREEN_PREFIX(data->screenProps, "stream format: %s (%d)\t%dx%d\n", + spa_debug_type_find_name( + spa_type_video_format, + data->rawFormat.format + ), + data->rawFormat.format, + data->rawFormat.size.width, + data->rawFormat.size.height); + + data->hasFormat = TRUE; + fp_pw_thread_loop_signal(pw.loop, TRUE); +} + +static void onStreamProcess(void *userdata) { + struct PwStreamData *data = userdata; + + struct ScreenProps *screen = data->screenProps; + + DEBUG_SCREEN_PREFIX(screen, + "hasFormat %i " + "captureDataReady %i shouldCapture %i\n", + data->hasFormat, + screen->captureDataReady, + screen->shouldCapture + ); + if ( + !data->hasFormat + || !screen->shouldCapture + || screen->captureDataReady + ) { + return; + } + + struct pw_buffer *pwBuffer; + struct spa_buffer *spaBuffer; + + if (!data->stream + || (pwBuffer = fp_pw_stream_dequeue_buffer(data->stream)) == NULL) { + DEBUG_SCREEN_PREFIX(screen, "!!! out of buffers\n", NULL); + return; + } + + spaBuffer = pwBuffer->buffer; + if (!spaBuffer + || spaBuffer->n_datas < 1 + || spaBuffer->datas[0].data == NULL) { + DEBUG_SCREEN_PREFIX(screen, "!!! no data, n_datas %d\n", + spaBuffer->n_datas); + return; + } + + struct spa_data spaData = spaBuffer->datas[0]; + + gint streamWidth = data->rawFormat.size.width; + gint streamHeight = data->rawFormat.size.height; + + DEBUG_SCREEN(screen); + DEBUG_SCREEN_PREFIX(screen, + "got a frame of size %d offset %d stride %d " + "flags %d FD %li captureDataReady %i of stream %dx%d\n", + spaBuffer->datas[0].chunk->size, + spaData.chunk->offset, + spaData.chunk->stride, + spaData.chunk->flags, + spaData.fd, + screen->captureDataReady, + streamWidth, + streamHeight + ); + + GdkRectangle captureArea = screen->captureArea; + GdkRectangle screenBounds = screen->bounds; + + GdkPixbuf *pixbuf = gtk->gdk_pixbuf_new_from_data(spaData.data, + GDK_COLORSPACE_RGB, + TRUE, + 8, + streamWidth, + streamHeight, + spaData.chunk->stride, + NULL, + NULL); + + if (screen->bounds.width != streamWidth + || screen->bounds.height != streamHeight) { + + DEBUG_SCREEN_PREFIX(screen, "scaling stream data %dx%d -> %dx%d\n", + streamWidth, streamHeight, + screen->bounds.width, screen->bounds.height + ); + + GdkPixbuf *scaled = gtk->gdk_pixbuf_scale_simple(pixbuf, + screen->bounds.width, + screen->bounds.height, + GDK_INTERP_BILINEAR); + + gtk->g_object_unref(pixbuf); + pixbuf = scaled; + } + + GdkPixbuf *cropped = NULL; + if (captureArea.width != screenBounds.width + || captureArea.height != screenBounds.height) { + + cropped = gtk->gdk_pixbuf_new(GDK_COLORSPACE_RGB, + TRUE, + 8, + captureArea.width, + captureArea.height); + if (cropped) { + gtk->gdk_pixbuf_copy_area(pixbuf, + captureArea.x, + captureArea.y, + captureArea.width, + captureArea.height, + cropped, + 0, 0); + } else { + ERR("Cannot create a new pixbuf.\n"); + } + + gtk->g_object_unref(pixbuf); + pixbuf = NULL; + + data->screenProps->captureDataPixbuf = cropped; + } else { + data->screenProps->captureDataPixbuf = pixbuf; + } + + screen->captureDataReady = TRUE; + + DEBUG_SCREEN_PREFIX(screen, "data ready\n", NULL); + fp_pw_stream_queue_buffer(data->stream, pwBuffer); + + fp_pw_thread_loop_signal(pw.loop, FALSE); +} + +static void onStreamStateChanged( + void *userdata, + enum pw_stream_state old, + enum pw_stream_state state, + const char *error +) { + struct PwStreamData *data = userdata; + DEBUG_SCREEN_PREFIX(data->screenProps, "state %i (%s) -> %i (%s) err %s\n", + old, fp_pw_stream_state_as_string(old), + state, fp_pw_stream_state_as_string(state), + error); + if (state == PW_STREAM_STATE_ERROR + || state == PW_STREAM_STATE_UNCONNECTED) { + + hasPipewireFailed = TRUE; + fp_pw_thread_loop_signal(pw.loop, FALSE); + } +} + +static const struct pw_stream_events streamEvents = { + PW_VERSION_STREAM_EVENTS, + .param_changed = onStreamParamChanged, + .process = onStreamProcess, + .state_changed = onStreamStateChanged, +}; + + +static bool startStream( + struct pw_stream *stream, + uint32_t node +) { + char buffer[1024]; + struct spa_pod_builder builder = + SPA_POD_BUILDER_INIT(buffer, sizeof(buffer)); + const struct spa_pod *param; + + + param = spa_pod_builder_add_object( + &builder, + SPA_TYPE_OBJECT_Format, + SPA_PARAM_EnumFormat, + SPA_FORMAT_mediaType, + SPA_POD_Id(SPA_MEDIA_TYPE_video), + SPA_FORMAT_mediaSubtype, + SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw), + SPA_FORMAT_VIDEO_format, + SPA_POD_Id(SPA_VIDEO_FORMAT_BGRx), + SPA_FORMAT_VIDEO_size, + SPA_POD_CHOICE_RANGE_Rectangle( + &SPA_RECTANGLE(320, 240), + &SPA_RECTANGLE(1, 1), + &SPA_RECTANGLE(8192, 8192) + ), + SPA_FORMAT_VIDEO_framerate, + SPA_POD_CHOICE_RANGE_Fraction( + &SPA_FRACTION(25, 1), + &SPA_FRACTION(0, 1), + &SPA_FRACTION(1000, 1) + ) + ); + + DEBUG_SCREENCAST("screenId#%i: stream connecting %p\n", node, stream); + + return fp_pw_stream_connect( + stream, + PW_DIRECTION_INPUT, + node, + PW_STREAM_FLAG_AUTOCONNECT + | PW_STREAM_FLAG_MAP_BUFFERS, + ¶m, + 1 + ) >= 0; +} + +/** + * @param index of a screen + * @return TRUE on success + */ +static gboolean connectStream(int index) { + DEBUG_SCREENCAST("@@@ using screen %i\n", index); + if (index >= screenSpace.screenCount) { + DEBUG_SCREENCAST("!!! Wrong index for screen\n", NULL); + return FALSE; + } + + struct PwStreamData *data = screenSpace.screens[index].data; + + data->screenProps = &screenSpace.screens[index]; + + if (!sessionClosed && data->stream) { + fp_pw_thread_loop_lock(pw.loop); + int result = fp_pw_stream_set_active(data->stream, TRUE); + fp_pw_thread_loop_unlock(pw.loop); + + DEBUG_SCREEN_PREFIX(data->screenProps, + "stream %p: activate result |%i|\n", + data->stream, result); + + return result == 0; // 0 - success + }; + + data->hasFormat = FALSE; + + data->stream = fp_pw_stream_new( + pw.core, + "AWT Screen Stream", + fp_pw_properties_new( + PW_KEY_MEDIA_TYPE, "Video", + PW_KEY_MEDIA_CATEGORY, "Capture", + PW_KEY_MEDIA_ROLE, "Screen", + NULL + ) + ); + + if (!data->stream) { + DEBUG_SCREEN_PREFIX(data->screenProps, + "!!! Could not create a pipewire stream\n", NULL); + fp_pw_thread_loop_unlock(pw.loop); + return FALSE; + } + + fp_pw_stream_add_listener( + data->stream, + &data->streamListener, + &streamEvents, + data + ); + + DEBUG_SCREEN(data->screenProps); + + if (!startStream(data->stream, screenSpace.screens[index].id)){ + DEBUG_SCREEN_PREFIX(data->screenProps, + "!!! Could not start a pipewire stream\n", NULL); + fp_pw_thread_loop_unlock(pw.loop); + return FALSE; + } + + while (!data->hasFormat) { + fp_pw_thread_loop_wait(pw.loop); + fp_pw_thread_loop_accept(pw.loop); + if (hasPipewireFailed) { + fp_pw_thread_loop_unlock(pw.loop); + return FALSE; + } + } + + DEBUG_SCREEN_PREFIX(data->screenProps, + "frame size: %dx%d\n", + data->rawFormat.size.width, data->rawFormat.size.height + ); + + return TRUE; +} + +/** + * @return TRUE if requested screenshot area intersects with a screen + */ +static gboolean checkScreen(int index, GdkRectangle requestedArea) { + if (index >= screenSpace.screenCount) { + DEBUG_SCREENCAST("!!! Wrong index for screen %i >= %i\n", + index, screenSpace.screenCount); + return FALSE; + } + + struct ScreenProps * screen = &screenSpace.screens[index]; + + int x1 = MAX(requestedArea.x, screen->bounds.x); + int y1 = MAX(requestedArea.y, screen->bounds.y); + + int x2 = MIN( + requestedArea.x + requestedArea.width, + screen->bounds.x + screen->bounds.width + ); + int y2 = MIN( + requestedArea.y + requestedArea.height, + screen->bounds.y + screen->bounds.height + ); + + screen->shouldCapture = x2 > x1 && y2 > y1; + + if (screen->shouldCapture) { //intersects + //in screen coords: + GdkRectangle * captureArea = &(screen->captureArea); + + captureArea->x = x1 - screen->bounds.x; + captureArea->y = y1 - screen->bounds.y; + captureArea->width = x2 - x1; + captureArea->height = y2 - y1; + + screen->captureArea.x = x1 - screen->bounds.x; + } + + DEBUG_SCREEN(screen); + return screen->shouldCapture; +} + + +static void onCoreError( + void *data, + uint32_t id, + int seq, + int res, + const char *message +) { + DEBUG_SCREENCAST( + "!!! pipewire error: id %u, seq: %d, res: %d (%s): %s\n", + id, seq, res, strerror(res), message + ); + if (id == PW_ID_CORE) { + fp_pw_thread_loop_lock(pw.loop); + hasPipewireFailed = TRUE; + fp_pw_thread_loop_signal(pw.loop, FALSE); + fp_pw_thread_loop_unlock(pw.loop); + } +} + +static const struct pw_core_events coreEvents = { + PW_VERSION_CORE_EVENTS, + .error = onCoreError, +}; + +/** + * + * @param requestedArea requested screenshot area + * @return TRUE on success + */ +static gboolean doLoop(GdkRectangle requestedArea) { + gboolean isLoopLockTaken = FALSE; + if (!pw.loop && !sessionClosed) { + pw.loop = fp_pw_thread_loop_new("AWT Pipewire Thread", NULL); + + if (!pw.loop) { + DEBUG_SCREENCAST("!!! Could not create a loop\n", NULL); + doCleanup(); + return FALSE; + } + + pw.context = fp_pw_context_new( + fp_pw_thread_loop_get_loop(pw.loop), + NULL, + 0 + ); + + if (!pw.context) { + DEBUG_SCREENCAST("!!! Could not create a pipewire context\n", NULL); + doCleanup(); + return FALSE; + } + + if (fp_pw_thread_loop_start(pw.loop) != 0) { + DEBUG_SCREENCAST("!!! Could not start pipewire thread loop\n", NULL); + doCleanup(); + return FALSE; + } + + fp_pw_thread_loop_lock(pw.loop); + isLoopLockTaken = TRUE; + + pw.core = fp_pw_context_connect_fd( + pw.context, + pw.pwFd, + NULL, + 0 + ); + + if (!pw.core) { + DEBUG_SCREENCAST("!!! Could not create pipewire core\n", NULL); + goto fail; + } + + pw_core_add_listener(pw.core, &pw.coreListener, &coreEvents, NULL); + } + + for (int i = 0; i < screenSpace.screenCount; ++i) { + struct ScreenProps *screen = &screenSpace.screens[i]; + if (!screen->data && !sessionClosed) { + struct PwStreamData *data = + (struct PwStreamData*) malloc(sizeof (struct PwStreamData)); + if (!data) { + ERR("failed to allocate memory\n"); + goto fail; + } + + memset(data, 0, sizeof (struct PwStreamData)); + + screen->data = data; + } + + DEBUG_SCREEN_PREFIX(screen, "@@@ adding screen %i\n", i); + if (checkScreen(i, requestedArea)) { + if (!connectStream(i)){ + goto fail; + } + } + DEBUG_SCREEN_PREFIX(screen, "@@@ screen processed %i\n", i); + } + + if (isLoopLockTaken) { + fp_pw_thread_loop_unlock(pw.loop); + } + + return TRUE; + + fail: + if (isLoopLockTaken) { + fp_pw_thread_loop_unlock(pw.loop); + } + doCleanup(); + return FALSE; +} + +static gboolean isAllDataReady() { + for (int i = 0; i < screenSpace.screenCount; ++i) { + if (!screenSpace.screens[i].shouldCapture) { + continue; + } + if (!screenSpace.screens[i].captureDataReady ) { + return FALSE; + } + } + return TRUE; +} + + +static void *pipewire_libhandle = NULL; +//glib_version_2_68 false for gtk2, as it comes from gtk3_interface.c + +extern gboolean glib_version_2_68; + +#define LOAD_SYMBOL(fp_name, name) do { \ + (fp_name) = dlsym(pipewire_libhandle, name); \ + if (!(fp_name)) { \ + debug_screencast("!!! %s:%i error loading dl_symbol %s\n", \ + __func__, __LINE__, name); \ + goto fail; \ + } \ +} while(0); + +static gboolean loadSymbols() { + if (!glib_version_2_68) { + DEBUG_SCREENCAST("glib version 2.68+ required\n", NULL); + return FALSE; + } + + pipewire_libhandle = dlopen(VERSIONED_JNI_LIB_NAME("pipewire-0.3", "0"), + RTLD_LAZY | RTLD_LOCAL); + + if (!pipewire_libhandle) { + DEBUG_SCREENCAST("could not load pipewire library\n", NULL); + return FALSE; + } + + LOAD_SYMBOL(fp_pw_stream_dequeue_buffer, "pw_stream_dequeue_buffer"); + LOAD_SYMBOL(fp_pw_stream_state_as_string, "pw_stream_state_as_string"); + LOAD_SYMBOL(fp_pw_stream_queue_buffer, "pw_stream_queue_buffer"); + LOAD_SYMBOL(fp_pw_stream_set_active, "pw_stream_set_active"); + LOAD_SYMBOL(fp_pw_stream_connect, "pw_stream_connect"); + LOAD_SYMBOL(fp_pw_stream_new, "pw_stream_new"); + LOAD_SYMBOL(fp_pw_stream_add_listener, "pw_stream_add_listener"); + LOAD_SYMBOL(fp_pw_stream_disconnect, "pw_stream_disconnect"); + LOAD_SYMBOL(fp_pw_stream_destroy, "pw_stream_destroy"); + LOAD_SYMBOL(fp_pw_init, "pw_init"); + LOAD_SYMBOL(fp_pw_deinit, "pw_deinit"); + LOAD_SYMBOL(fp_pw_context_connect_fd, "pw_context_connect_fd"); + LOAD_SYMBOL(fp_pw_core_disconnect, "pw_core_disconnect"); + LOAD_SYMBOL(fp_pw_context_new, "pw_context_new"); + LOAD_SYMBOL(fp_pw_thread_loop_new, "pw_thread_loop_new"); + LOAD_SYMBOL(fp_pw_thread_loop_get_loop, "pw_thread_loop_get_loop"); + LOAD_SYMBOL(fp_pw_thread_loop_signal, "pw_thread_loop_signal"); + LOAD_SYMBOL(fp_pw_thread_loop_wait, "pw_thread_loop_wait"); + LOAD_SYMBOL(fp_pw_thread_loop_accept, "pw_thread_loop_accept"); + LOAD_SYMBOL(fp_pw_thread_loop_start, "pw_thread_loop_start"); + LOAD_SYMBOL(fp_pw_thread_loop_stop, "pw_thread_loop_stop"); + LOAD_SYMBOL(fp_pw_thread_loop_destroy, "pw_thread_loop_destroy"); + LOAD_SYMBOL(fp_pw_thread_loop_lock, "pw_thread_loop_lock"); + LOAD_SYMBOL(fp_pw_thread_loop_unlock, "pw_thread_loop_unlock"); + LOAD_SYMBOL(fp_pw_properties_new, "pw_properties_new"); + + return TRUE; + + fail: + dlclose(pipewire_libhandle); + pipewire_libhandle = NULL; + return FALSE; +} + +void storeRestoreToken(const gchar* oldToken, const gchar* newToken) { + + JNIEnv* env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2); + DEBUG_SCREENCAST("saving token, old: |%s| > new: |%s|\n", oldToken, newToken); + if (env) { + jstring jOldToken = NULL; + if (oldToken) { + jOldToken = (*env)->NewStringUTF(env, oldToken); + EXCEPTION_CHECK_DESCRIBE(); + if (!jOldToken) { + return; + } + } + jstring jNewToken = (*env)->NewStringUTF(env, newToken); + EXCEPTION_CHECK_DESCRIBE(); + if (!jNewToken) { + (*env)->DeleteLocalRef(env, jOldToken); + return; + } + + jintArray allowedBounds = NULL; + if (screenSpace.screenCount > 0) { + allowedBounds = (*env)->NewIntArray(env, screenSpace.screenCount*4); + EXCEPTION_CHECK_DESCRIBE(); + if (!allowedBounds) { + return; + } + jint* elements = (*env)->GetIntArrayElements(env, allowedBounds, NULL); + EXCEPTION_CHECK_DESCRIBE(); + if (!elements) { + return; + } + + for (int i = 0; i < screenSpace.screenCount; ++i) { + GdkRectangle bounds = screenSpace.screens[i].bounds; + elements[4 * i] = bounds.x; + elements[4 * i + 1] = bounds.y; + elements[4 * i + 2] = bounds.width; + elements[4 * i + 3] = bounds.height; + } + + (*env)->ReleaseIntArrayElements(env, allowedBounds, elements, 0); + + (*env)->CallStaticVoidMethod(env, tokenStorageClass, + storeTokenMethodID, + jOldToken, jNewToken, + allowedBounds); + EXCEPTION_CHECK_DESCRIBE(); + } + (*env)->DeleteLocalRef(env, jOldToken); + (*env)->DeleteLocalRef(env, jNewToken); + } else { + DEBUG_SCREENCAST("!!! Could not get env\n", NULL); + } +} + +/* + * Class: sun_awt_UNIXToolkit + * Method: load_gtk + * Signature: (IZ)Z + */ +JNIEXPORT jboolean JNICALL Java_sun_awt_screencast_ScreencastHelper_loadPipewire( + JNIEnv *env, jclass cls, jboolean screencastDebug +) { + DEBUG_SCREENCAST_ENABLED = screencastDebug; + + if (!loadSymbols()) { + return JNI_FALSE; + } + + tokenStorageClass = (*env)->FindClass(env, "sun/awt/screencast/TokenStorage"); + if (!tokenStorageClass) { + return JNI_FALSE; + } + + tokenStorageClass = (*env)->NewGlobalRef(env, tokenStorageClass); + + if (tokenStorageClass) { + storeTokenMethodID = (*env)->GetStaticMethodID( + env, + tokenStorageClass, + "storeTokenFromNative", + "(Ljava/lang/String;Ljava/lang/String;[I)V" + ); + if (!storeTokenMethodID) { + return JNI_FALSE; + } + } else { + DEBUG_SCREENCAST("!!! @@@ tokenStorageClass %p\n", + tokenStorageClass); + return JNI_FALSE; + } + + activeSessionToken = gtk->g_string_new(""); + + gboolean usable = initXdgDesktopPortal(); + portalScreenCastCleanup(); + return usable; +} + +static void releaseToken(JNIEnv *env, jstring jtoken, const gchar *token) { + if (token) { + (*env)->ReleaseStringUTFChars(env, jtoken, token); + } +} + +static void arrayToRectangles(JNIEnv *env, + jintArray boundsArray, + jint boundsLen, + GdkRectangle *out +) { + if (!boundsArray) { + return; + } + + jint * body = (*env)->GetIntArrayElements(env, boundsArray, 0); + EXCEPTION_CHECK_DESCRIBE(); + if (!body) { + return; + } + + for (int i = 0; i < boundsLen; i += 4) { + GdkRectangle screenBounds = { + body[i], body[i + 1], + body[i + 2], body[i + 3] + }; + out[i / 4] = screenBounds; + } + + (*env)->ReleaseIntArrayElements(env, boundsArray, body, 0); +} + +static int makeScreencast( + const gchar *token, + GdkRectangle *requestedArea, + GdkRectangle *affectedScreenBounds, + gint affectedBoundsLength +) { + if (!initScreencast(token, affectedScreenBounds, affectedBoundsLength)) { + return pw.pwFd; + } + + if (!doLoop(*requestedArea)) { + return RESULT_ERROR; + } + + while (!isAllDataReady()) { + fp_pw_thread_loop_lock(pw.loop); + fp_pw_thread_loop_wait(pw.loop); + fp_pw_thread_loop_unlock(pw.loop); + if (hasPipewireFailed) { + doCleanup(); + return RESULT_ERROR; + } + } + + return RESULT_OK; +} + +/* + * Class: sun_awt_screencast_ScreencastHelper + * Method: closeSession + * Signature: ()V + */ +JNIEXPORT void JNICALL +Java_sun_awt_screencast_ScreencastHelper_closeSession(JNIEnv *env, jclass cls) { + DEBUG_SCREENCAST("closing screencast session\n\n", NULL); + doCleanup(); +} + +/* + * Class: sun_awt_screencast_ScreencastHelper + * Method: getRGBPixelsImpl + * Signature: (IIII[I[ILjava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_sun_awt_screencast_ScreencastHelper_getRGBPixelsImpl( + JNIEnv *env, + jclass cls, + jint jx, + jint jy, + jint jwidth, + jint jheight, + jintArray pixelArray, + jintArray affectedScreensBoundsArray, + jstring jtoken +) { + jsize boundsLen = 0; + gint affectedBoundsLength = 0; + if (affectedScreensBoundsArray) { + boundsLen = (*env)->GetArrayLength(env, affectedScreensBoundsArray); + EXCEPTION_CHECK_DESCRIBE(); + if (boundsLen % 4 != 0) { + DEBUG_SCREENCAST("incorrect array length\n", NULL); + return RESULT_ERROR; + } + affectedBoundsLength = boundsLen / 4; + } + + GdkRectangle affectedScreenBounds[affectedBoundsLength]; + arrayToRectangles(env, + affectedScreensBoundsArray, + boundsLen, + (GdkRectangle *) &affectedScreenBounds); + + GdkRectangle requestedArea = { jx, jy, jwidth, jheight}; + + const gchar *token = jtoken + ? (*env)->GetStringUTFChars(env, jtoken, NULL) + : NULL; + + DEBUG_SCREENCAST( + "taking screenshot at \n\tx: %5i y %5i w %5i h %5i with token |%s|\n", + jx, jy, jwidth, jheight, token + ); + + int attemptResult = makeScreencast( + token, &requestedArea, affectedScreenBounds, affectedBoundsLength); + + if (attemptResult) { + if (attemptResult == RESULT_DENIED) { + releaseToken(env, jtoken, token); + return attemptResult; + } + DEBUG_SCREENCAST("Screencast attempt failed with %i, re-trying...\n", + attemptResult); + attemptResult = makeScreencast( + token, &requestedArea, affectedScreenBounds, affectedBoundsLength); + if (attemptResult) { + releaseToken(env, jtoken, token); + return attemptResult; + } + } + + DEBUG_SCREENCAST("\nall data ready\n", NULL); + + for (int i = 0; i < screenSpace.screenCount; ++i) { + struct ScreenProps * screenProps = &screenSpace.screens[i]; + + if (screenProps->shouldCapture) { + GdkRectangle bounds = screenProps->bounds; + GdkRectangle captureArea = screenProps->captureArea; + DEBUG_SCREEN_PREFIX(screenProps, + "@@@ copying screen data %i, captureData %p\n" + "\t||\tx %5i y %5i w %5i h %5i %s\n" + "\t||\tx %5i y %5i w %5i h %5i %s\n" + "\t||\tx %5i y %5i w %5i h %5i %s\n\n", + i, screenProps->captureDataPixbuf, + requestedArea.x, requestedArea.y, + requestedArea.width, requestedArea.height, + "requested area", + + bounds.x, bounds.y, + bounds.width, bounds.height, + "screen bound", + + captureArea.x, captureArea.y, + captureArea.width, captureArea.height, + "in-screen coords capture area" + ); + + if (screenProps->captureDataPixbuf) { + for (int y = 0; y < captureArea.height; y++) { + jsize preY = (requestedArea.y > screenProps->bounds.y) + ? 0 + : screenProps->bounds.y - requestedArea.y; + jsize preX = (requestedArea.x > screenProps->bounds.x) + ? 0 + : screenProps->bounds.x - requestedArea.x; + jsize start = jwidth * (preY + y) + preX; + + jsize len = captureArea.width; + + (*env)->SetIntArrayRegion( + env, pixelArray, + start, len, + ((jint *) gtk->gdk_pixbuf_get_pixels( + screenProps->captureDataPixbuf + )) + + (captureArea.width * y) + ); + } + } + + if (screenProps->captureDataPixbuf) { + gtk->g_object_unref(screenProps->captureDataPixbuf); + screenProps->captureDataPixbuf = NULL; + } + screenProps->shouldCapture = FALSE; + + fp_pw_thread_loop_lock(pw.loop); + fp_pw_stream_set_active(screenProps->data->stream, FALSE); + fp_pw_thread_loop_unlock(pw.loop); + + screenProps->captureDataReady = FALSE; + } + } + + releaseToken(env, jtoken, token); + return 0; +} diff -Nru openjdk-17-17.0.12+7/src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.h openjdk-17-17.0.13+11/src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.h --- openjdk-17-17.0.12+7/src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.h 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.h 2024-10-10 14:01:59.000000000 +0000 @@ -0,0 +1,104 @@ +/* + * 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. + */ + +#ifdef HEADLESS +#error This file should not be included in headless library +#endif + + +#ifndef _SCREENCAST_PIPEWIRE_H +#define _SCREENCAST_PIPEWIRE_H + +#include "screencast_portal.h" + +#include +#include + +#include +#include + +void storeRestoreToken(const gchar* oldToken, const gchar* newToken); + +struct ScreenProps { + guint32 id; + GdkRectangle bounds; + + GdkRectangle captureArea; + struct PwStreamData *data; + + GdkPixbuf *captureDataPixbuf; + volatile gboolean shouldCapture; + volatile gboolean captureDataReady; +}; + + +#define SCREEN_SPACE_DEFAULT_ALLOCATED 2 +struct ScreenSpace { + struct ScreenProps *screens; + int screenCount; + int allocated; +}; + +#define DEBUG_SCREENCAST(FORMAT, ...) debug_screencast("%s:%i " FORMAT, \ + __func__, __LINE__, __VA_ARGS__); + +#define DEBUG_SCREEN(SCREEN) \ + DEBUG_SCREENCAST("screenId#%i\n" \ + "||\tbounds x %5i y %5i w %5i h %5i\n" \ + "||\tcapture area x %5i y %5i w %5i h %5i shouldCapture %i\n\n", \ + (SCREEN)->id, \ + (SCREEN)->bounds.x, (SCREEN)->bounds.y, \ + (SCREEN)->bounds.width, (SCREEN)->bounds.height, \ + (SCREEN)->captureArea.x, (SCREEN)->captureArea.y, \ + (SCREEN)->captureArea.width, (SCREEN)->captureArea.height, \ + (SCREEN)->shouldCapture); + +#define DEBUG_SCREEN_PREFIX(SCREEN, FORMAT, ...) \ + DEBUG_SCREENCAST("screenId#%i[loc(%d,%d) size(%dx%d)] "FORMAT, \ + (SCREEN)->id, (SCREEN)->bounds.x, (SCREEN)->bounds.y, \ + (SCREEN)->bounds.width, (SCREEN)->bounds.height, __VA_ARGS__); + +#define ERR(MSG) fprintf(stderr, "%s:%i " MSG, __func__, __LINE__); +#define ERR_HANDLE(ERROR) errHandle((ERROR), __func__, __LINE__); + +struct PwLoopData { + struct pw_thread_loop *loop; + struct pw_context *context; + struct pw_core *core; + struct spa_hook coreListener; + int pwFd; //negative values can also be used to store a failure reason +}; + +struct PwStreamData { + struct pw_stream *stream; + struct spa_hook streamListener; + + struct spa_video_info_raw rawFormat; + struct ScreenProps *screenProps; + + gboolean hasFormat; +}; + +#endif //_SCREENCAST_PIPEWIRE_H diff -Nru openjdk-17-17.0.12+7/src/java.desktop/unix/native/libawt_xawt/awt/screencast_portal.c openjdk-17-17.0.13+11/src/java.desktop/unix/native/libawt_xawt/awt/screencast_portal.c --- openjdk-17-17.0.12+7/src/java.desktop/unix/native/libawt_xawt/awt/screencast_portal.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.13+11/src/java.desktop/unix/native/libawt_xawt/awt/screencast_portal.c 2024-10-10 14:01:59.000000000 +0000 @@ -0,0 +1,906 @@ +/* + * 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. + */ + +#include "stdlib.h" +#include +#include +#include +#include +#include +#include "screencast_pipewire.h" +#include "screencast_portal.h" + + +extern struct ScreenSpace screenSpace; + +struct XdgDesktopPortalApi *portal = NULL; + +void errHandle( + GError *error, + const gchar *functionName, + int lineNum +) { + if (error) { + fprintf(stderr, "!!! %s:%i Error: domain %i code %i message: \"%s\"\n", + functionName, lineNum, + error->domain, error->code, error->message); + } + if (error) { + gtk->g_error_free(error); + } + error = NULL; +} + +gboolean validateToken(const gchar *token) { + if (!token) { + return FALSE; + } + + gboolean isValid = gtk->g_uuid_string_is_valid(token); + if (!isValid) { + DEBUG_SCREENCAST("!!! restore token " + "is not a valid UUID string:\n\"%s\"\n", + token); + } + return isValid; +} + +/** + * @return TRUE on success + */ +gboolean rebuildScreenData(GVariantIter *iterStreams, gboolean isTheOnlyMon) { + guint32 nodeID; + GVariant* prop = NULL; + + int screenIndex = 0; + + gboolean hasFailures = FALSE; + + while (gtk->g_variant_iter_loop( + iterStreams, + "(u@a{sv})", + &nodeID, + &prop + )) { + DEBUG_SCREENCAST("\n==== screenId#%i\n", nodeID); + + if (screenIndex >= screenSpace.allocated) { + screenSpace.screens = realloc( + screenSpace.screens, + ++screenSpace.allocated * sizeof(struct ScreenProps) + ); + if (!screenSpace.screens) { + ERR("failed to allocate memory\n"); + return FALSE; + } + } + + struct ScreenProps * screen = &screenSpace.screens[screenIndex]; + memset(screen, 0, sizeof(struct ScreenProps)); + + screenSpace.screenCount = screenIndex + 1; + + screen->id = nodeID; + + if ( + !gtk->g_variant_lookup( + prop, + "size", + "(ii)", + &screen->bounds.width, + &screen->bounds.height + ) + || ( + !gtk->g_variant_lookup( + prop, + "position", + "(ii)", + &screen->bounds.x, + &screen->bounds.y + ) + //Screen position is not specified in some cases + //(e.g. on Plasma). + //In this case, proceed only if there is only one screen. + && !isTheOnlyMon + ) + ) { + hasFailures = TRUE; + } + + DEBUG_SCREENCAST("-----------------------\n", NULL); + DEBUG_SCREEN(screen); + DEBUG_SCREENCAST("#---------------------#\n\n", NULL); + + gtk->g_variant_unref(prop); + screenIndex++; + }; + + if (hasFailures) { + DEBUG_SCREENCAST("screenId#%i hasFailures\n", nodeID); + } + + return !hasFailures; +} + +/** + * Checks screencast protocol version + * @return FALSE if version < 4, or could not be determined + */ +gboolean checkVersion() { + static guint32 version = 0; + if (version == 0) { + GError *error = NULL; + GVariant *retVersion = gtk->g_dbus_proxy_call_sync( + portal->screenCastProxy, + "org.freedesktop.DBus.Properties.Get", + gtk->g_variant_new("(ss)", + "org.freedesktop.portal.ScreenCast", + "version"), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, NULL + ); + + if (!retVersion) { //no backend on system + DEBUG_SCREENCAST("!!! could not detect the screencast version\n", + NULL); + return FALSE; + } + + ERR_HANDLE(error); + + GVariant *varVersion = NULL; + gtk->g_variant_get(retVersion, "(v)", &varVersion); + + if (!varVersion){ + gtk->g_variant_unref(retVersion); + DEBUG_SCREENCAST("!!! could not get the screencast version\n", + NULL); + return FALSE; + } + + version = gtk->g_variant_get_uint32(varVersion); + + gtk->g_variant_unref(varVersion); + gtk->g_variant_unref(retVersion); + + } + + DEBUG_SCREENCAST("ScreenCast protocol version %d\n", version); + if (version < 4) { + DEBUG_SCREENCAST("!!! ScreenCast protocol version %d < 4," + " session restore is not available\n", + version); + } + + // restore_token was added in version 4, without it, + // user confirmation is required for every screenshot. + return version >= 4; +} + +/** + * @return TRUE on success + */ +gboolean initXdgDesktopPortal() { + portal = calloc(1, sizeof(*portal)); + + if (!portal) { + ERR("failed to allocate memory\n"); + return FALSE; + } + + GError* err = NULL; + + portal->connection = gtk->g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &err); + + if (err) { + ERR_HANDLE(err); + return FALSE; + } + + const gchar *name = gtk + ->g_dbus_connection_get_unique_name(portal->connection); + if (!name) { + ERR("Failed to get unique connection name\n"); + return FALSE; + } + + GString * nameStr = gtk->g_string_new(name); + gtk->g_string_erase(nameStr, 0, 1); //remove leading colon ":" + gtk->g_string_replace(nameStr, ".", "_", 0); + portal->senderName = nameStr->str; + + gtk->g_string_free(nameStr, FALSE); + + DEBUG_SCREENCAST("connection/sender name %s / %s\n", + name, + portal->senderName); + + portal->screenCastProxy = gtk->g_dbus_proxy_new_sync( + portal->connection, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.freedesktop.portal.Desktop", + "/org/freedesktop/portal/desktop", + "org.freedesktop.portal.ScreenCast", + NULL, + &err + ); + + if (err) { + DEBUG_SCREENCAST("Failed to get ScreenCast portal: %s", err->message); + ERR_HANDLE(err); + return FALSE; + } + + return checkVersion(); +} + +static void updateRequestPath( + gchar **path, + gchar **token +) { + static uint64_t counter = 0; + ++counter; + + GString *tokenStr = gtk->g_string_new(NULL); + gtk->g_string_printf( + tokenStr, + PORTAL_TOKEN_TEMPLATE, + counter + ); + + *token = tokenStr->str; + gtk->g_string_free(tokenStr, FALSE); + + GString *pathStr = gtk->g_string_new(NULL); + + gtk->g_string_printf( + pathStr, + PORTAL_REQUEST_TEMPLATE, + portal->senderName, + counter + ); + + *path = pathStr->str; + gtk->g_string_free(pathStr, FALSE); +} + +static void updateSessionToken( + gchar **token +) { + static uint64_t counter = 0; + counter++; + + GString *tokenStr = gtk->g_string_new(NULL); + + gtk->g_string_printf( + tokenStr, + PORTAL_TOKEN_TEMPLATE, + counter + ); + + *token = tokenStr->str; + gtk->g_string_free(tokenStr, FALSE); +} + +static void registerScreenCastCallback( + const char *path, + struct DBusCallbackHelper *helper, + GDBusSignalCallback callback +) { + helper->id = gtk->g_dbus_connection_signal_subscribe( + portal->connection, + "org.freedesktop.portal.Desktop", + "org.freedesktop.portal.Request", + "Response", + path, + NULL, + G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE, + callback, + helper, + NULL + ); +} + +static void unregisterScreenCastCallback( + struct DBusCallbackHelper *helper +) { + if (helper->id) { + gtk->g_dbus_connection_signal_unsubscribe( + portal->connection, + helper->id + ); + } +} + +static void callbackScreenCastCreateSession( + GDBusConnection *connection, + const char *senderName, + const char *objectPath, + const char *interfaceName, + const char *signalName, + GVariant *parameters, + void *data +) { + struct DBusCallbackHelper *helper = data; + uint32_t status; + GVariant *result = NULL; + + gtk->g_variant_get( + parameters, + "(u@a{sv})", + &status, + &result + ); + + if (status != 0) { + DEBUG_SCREENCAST("Failed to create ScreenCast: %u\n", status); + } else { + gtk->g_variant_lookup(result, "session_handle", "s", helper->data); + } + + helper->isDone = TRUE; +} + +gboolean portalScreenCastCreateSession() { + GError *err = NULL; + + gchar *requestPath = NULL; + gchar *requestToken = NULL; + gchar *sessionToken = NULL; + + struct DBusCallbackHelper helper = { + .id = 0, + .data = &portal->screenCastSessionHandle + }; + + updateRequestPath( + &requestPath, + &requestToken + ); + updateSessionToken(&sessionToken); + + portal->screenCastSessionHandle = NULL; + + registerScreenCastCallback( + requestPath, + &helper, + callbackScreenCastCreateSession + ); + + GVariantBuilder builder; + + gtk->g_variant_builder_init( + &builder, + G_VARIANT_TYPE_VARDICT + ); + + gtk->g_variant_builder_add( + &builder, + "{sv}", + "handle_token", + gtk->g_variant_new_string(requestToken) + ); + + gtk->g_variant_builder_add( + &builder, + "{sv}", + "session_handle_token", + gtk->g_variant_new_string(sessionToken) + ); + + GVariant *response = gtk->g_dbus_proxy_call_sync( + portal->screenCastProxy, + "CreateSession", + gtk->g_variant_new("(a{sv})", &builder), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &err + ); + + if (err) { + DEBUG_SCREENCAST("Failed to create ScreenCast session: %s\n", + err->message); + ERR_HANDLE(err); + } else { + while (!helper.isDone) { + gtk->g_main_context_iteration(NULL, TRUE); + } + } + + unregisterScreenCastCallback(&helper); + if (response) { + gtk->g_variant_unref(response); + } + + free(sessionToken); + free(requestPath); + free(requestToken); + + return portal->screenCastSessionHandle != NULL; +} + +static void callbackScreenCastSelectSources( + GDBusConnection *connection, + const char *senderName, + const char *objectPath, + const char *interfaceName, + const char *signalName, + GVariant *parameters, + void *data +) { + struct DBusCallbackHelper *helper = data; + + helper->data = (void *) 0; + + uint32_t status; + GVariant* result = NULL; + + gtk->g_variant_get(parameters, "(u@a{sv})", &status, &result); + + if (status != 0) { + DEBUG_SCREENCAST("Failed select sources: %u\n", status); + } else { + helper->data = (void *) 1; + } + + helper->isDone = TRUE; + + if (result) { + gtk->g_variant_unref(result); + } +} + +gboolean portalScreenCastSelectSources(const gchar *token) { + GError* err = NULL; + + gchar *requestPath = NULL; + gchar *requestToken = NULL; + + struct DBusCallbackHelper helper = {0}; + + updateRequestPath( + &requestPath, + &requestToken + ); + + registerScreenCastCallback( + requestPath, + &helper, + callbackScreenCastSelectSources + ); + + GVariantBuilder builder; + + gtk->g_variant_builder_init( + &builder, + G_VARIANT_TYPE_VARDICT + ); + + gtk->g_variant_builder_add( + &builder, + "{sv}", "handle_token", + gtk->g_variant_new_string(requestToken) + ); + + gtk->g_variant_builder_add( + &builder, + "{sv}", "multiple", + gtk->g_variant_new_boolean(TRUE)); + + // 1: MONITOR + // 2: WINDOW + // 4: VIRTUAL + gtk->g_variant_builder_add( + &builder, "{sv}", "types", + gtk->g_variant_new_uint32(1) + ); + + // 0: Do not persist (default) + // 1: Permissions persist as long as the application is running + // 2: Permissions persist until explicitly revoked + gtk->g_variant_builder_add( + &builder, + "{sv}", + "persist_mode", + gtk->g_variant_new_uint32(2) + ); + + if (validateToken(token)) { + gtk->g_variant_builder_add( + &builder, + "{sv}", + "restore_token", + gtk->g_variant_new_string(token) + ); + } + + GVariant *response = gtk->g_dbus_proxy_call_sync( + portal->screenCastProxy, + "SelectSources", + gtk->g_variant_new("(oa{sv})", portal->screenCastSessionHandle, &builder), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &err + ); + + if (err) { + DEBUG_SCREENCAST("Failed to call SelectSources: %s\n", err->message); + ERR_HANDLE(err); + } else { + while (!helper.isDone) { + gtk->g_main_context_iteration(NULL, TRUE); + } + } + + unregisterScreenCastCallback(&helper); + if (response) { + gtk->g_variant_unref(response); + } + + free(requestPath); + free(requestToken); + + return helper.data != NULL; +} + +static void callbackScreenCastStart( + GDBusConnection *connection, + const char *senderName, + const char *objectPath, + const char *interfaceName, + const char *signalName, + GVariant *parameters, + void *data +) { + struct DBusCallbackHelper *helper = data; + struct StartHelper *startHelper = helper->data; + + uint32_t status; + GVariant* result = NULL; + const gchar *oldToken = startHelper->token; + + gtk->g_variant_get(parameters, "(u@a{sv})", &status, &result); + + if (status != 0) { + // Cancel pressed on the system dialog + DEBUG_SCREENCAST("Failed to start screencast: %u\n", status); + startHelper->result = RESULT_DENIED; + helper->isDone = TRUE; + return; + } + + GVariant *streams = gtk->g_variant_lookup_value( + result, + "streams", + G_VARIANT_TYPE_ARRAY + ); + + GVariantIter iter; + gtk->g_variant_iter_init( + &iter, + streams + ); + + size_t count = gtk->g_variant_iter_n_children(&iter); + + DEBUG_SCREENCAST("available screen count %i\n", count); + + startHelper->result = (rebuildScreenData(&iter, count == 1)) + ? RESULT_OK + : RESULT_ERROR; + + DEBUG_SCREENCAST("rebuildScreenData result |%i|\n", startHelper->result); + + if (startHelper->result == RESULT_OK) { + GVariant *restoreTokenVar = gtk->g_variant_lookup_value( + result, + "restore_token", + G_VARIANT