diff --git a/bin/update_copyright_year.sh b/bin/update_copyright_year.sh index fa7989d234b..fcdac6b935f 100644 --- a/bin/update_copyright_year.sh +++ b/bin/update_copyright_year.sh @@ -1,7 +1,7 @@ #!/bin/bash -f # -# Copyright (c) 2010, 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2026, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,9 +23,13 @@ # questions. # -# Script to update the Copyright YEAR range in Mercurial & Git sources. +# Script to update the Copyright YEAR range in Git sources. # (Originally from xdono, Thanks!) +# To update Copyright years for changes in a specific branch, +# you use a command along these lines: +# $ git diff upstream/master... | lsdiff | cut -d '/' -f 2- | bash bin/update_copyright_year.sh -m - + #------------------------------------------------------------ copyright="Copyright" copyright_symbol="(c)" @@ -47,7 +51,7 @@ rm -f -r ${tmp} mkdir -p ${tmp} total=0 -usage="Usage: `basename "$0"` [-c company] [-y year] [-h|f]" +usage="Usage: `basename "$0"` [-c company] [-y year] [-m file] [-h|f]" Help() { # Display Help @@ -65,15 +69,18 @@ Help() echo "-b Specifies the base reference for change set lookup." echo "-f Updates the copyright for all change sets in a given year," echo " as specified by -y. Overrides -b flag." + echo "-m Read the list of modified files from the given file," + echo " use - to read from stdin" echo "-h Print this help." echo } full_year=false base_reference=master +modified_files_origin=""; # Process options -while getopts "b:c:fhy:" option; do +while getopts "b:c:fhm:y:" option; do case $option in b) # supplied base reference base_reference=${OPTARG} @@ -91,6 +98,9 @@ while getopts "b:c:fhy:" option; do y) # supplied company year year=${OPTARG} ;; + m) # modified files will be read from the given origin + modified_files_origin="${OPTARG}" + ;; \?) # illegal option echo "$usage" exit 1 @@ -110,18 +120,10 @@ git status &> /dev/null && git_found=true if [ "$git_found" != "true" ]; then echo "Error: Please execute script from within a JDK git repository." exit 1 -else - echo "Using Git version control system" - vcs_status=(git ls-files -m) - if [ "$full_year" = "true" ]; then - vcs_list_changesets=(git log --no-merges --since="${year}-01-01T00:00:00Z" --until="${year}-12-31T23:59:59Z" --pretty=tformat:"%H") - else - vcs_list_changesets=(git log --no-merges "${base_reference}..HEAD" --since="${year}-01-01T00:00:00Z" --until="${year}-12-31T23:59:59Z" --pretty=tformat:"%H") - fi - vcs_changeset_message=(git log -1 --pretty=tformat:"%B") # followed by ${changeset} - vcs_changeset_files=(git diff-tree --no-commit-id --name-only -r) # followed by ${changeset} fi +echo "Using Git version control system" + # Return true if it makes sense to edit this file saneFileToCheck() { @@ -168,6 +170,25 @@ updateFile() # file echo "${changed}" } +# Update the copyright year on files sent in stdin +updateFiles() # stdin: list of files to update +{ + count=0 + fcount=0 + while read i; do + fcount=`expr ${fcount} '+' 1` + if [ `updateFile "${i}"` = "true" ] ; then + count=`expr ${count} '+' 1` + fi + done + if [ ${count} -gt 0 ] ; then + printf " UPDATED year on %d of %d files.\n" ${count} ${fcount} + total=`expr ${total} '+' ${count}` + else + printf " None of the %d files were changed.\n" ${fcount} + fi +} + # Update the copyright year on all files changed by this changeset updateChangesetFiles() # changeset { @@ -178,18 +199,7 @@ updateChangesetFiles() # changeset | ${awk} -F' ' '{for(i=1;i<=NF;i++)print $i}' \ > ${files} if [ -f "${files}" -a -s "${files}" ] ; then - fcount=`cat ${files}| wc -l` - for i in `cat ${files}` ; do - if [ `updateFile "${i}"` = "true" ] ; then - count=`expr ${count} '+' 1` - fi - done - if [ ${count} -gt 0 ] ; then - printf " UPDATED year on %d of %d files.\n" ${count} ${fcount} - total=`expr ${total} '+' ${count}` - else - printf " None of the %d files were changed.\n" ${fcount} - fi + cat ${files} | updateFiles else printf " ERROR: No files changed in the changeset? Must be a mistake.\n" set -x @@ -204,67 +214,80 @@ updateChangesetFiles() # changeset } # Check if repository is clean +vcs_status=(git ls-files -m) previous=`"${vcs_status[@]}"|wc -l` if [ ${previous} -ne 0 ] ; then echo "WARNING: This repository contains previously edited working set files." echo " ${vcs_status[*]} | wc -l = `"${vcs_status[@]}" | wc -l`" fi -# Get all changesets this year -all_changesets=${tmp}/all_changesets -rm -f ${all_changesets} -"${vcs_list_changesets[@]}" > ${all_changesets} - -# Check changeset to see if it is Copyright only changes, filter changesets -if [ -s ${all_changesets} ] ; then - echo "Changesets made in ${year}: `cat ${all_changesets} | wc -l`" - index=0 - cat ${all_changesets} | while read changeset ; do - index=`expr ${index} '+' 1` - desc=${tmp}/desc.${changeset} - rm -f ${desc} - echo "------------------------------------------------" - "${vcs_changeset_message[@]}" "${changeset}" > ${desc} - printf "%d: %s\n%s\n" ${index} "${changeset}" "`cat ${desc}|head -1`" - if [ "${year}" = "2010" ] ; then - if cat ${desc} | grep -i -F "Added tag" > /dev/null ; then - printf " EXCLUDED tag changeset.\n" - elif cat ${desc} | grep -i -F rebrand > /dev/null ; then - printf " EXCLUDED rebrand changeset.\n" - elif cat ${desc} | grep -i -F copyright > /dev/null ; then - printf " EXCLUDED copyright changeset.\n" - else - updateChangesetFiles ${changeset} - fi - else - if cat ${desc} | grep -i -F "Added tag" > /dev/null ; then - printf " EXCLUDED tag changeset.\n" - elif cat ${desc} | grep -i -F "copyright year" > /dev/null ; then - printf " EXCLUDED copyright year changeset.\n" - else - updateChangesetFiles ${changeset} - fi - fi - rm -f ${desc} - done -fi - -if [ ${total} -gt 0 ] ; then - echo "---------------------------------------------" - echo "Updated the copyright year on a total of ${total} files." - if [ ${previous} -eq 0 ] ; then - echo "This count should match the count of modified files in the repository: ${vcs_status[*]}" - else - echo "WARNING: This repository contained previously edited working set files." - fi - echo " ${vcs_status[*]} | wc -l = `"${vcs_status[@]}" | wc -l`" +if [ "x$modified_files_origin" != "x" ]; then + cat $modified_files_origin | updateFiles else - echo "---------------------------------------------" - echo "No files were changed" - if [ ${previous} -ne 0 ] ; then - echo "WARNING: This repository contained previously edited working set files." - fi - echo " ${vcs_status[*]} | wc -l = `"${vcs_status[@]}" | wc -l`" + # Get all changesets this year + if [ "$full_year" = "true" ]; then + vcs_list_changesets=(git log --no-merges --since="${year}-01-01T00:00:00Z" --until="${year}-12-31T23:59:59Z" --pretty=tformat:"%H") + else + vcs_list_changesets=(git log --no-merges "${base_reference}..HEAD" --since="${year}-01-01T00:00:00Z" --until="${year}-12-31T23:59:59Z" --pretty=tformat:"%H") + fi + vcs_changeset_message=(git log -1 --pretty=tformat:"%B") # followed by ${changeset} + vcs_changeset_files=(git diff-tree --no-commit-id --name-only -r) # followed by ${changeset} + + all_changesets=${tmp}/all_changesets + rm -f ${all_changesets} + "${vcs_list_changesets[@]}" > ${all_changesets} + + # Check changeset to see if it is Copyright only changes, filter changesets + if [ -s ${all_changesets} ] ; then + echo "Changesets made in ${year}: `cat ${all_changesets} | wc -l`" + index=0 + cat ${all_changesets} | while read changeset ; do + index=`expr ${index} '+' 1` + desc=${tmp}/desc.${changeset} + rm -f ${desc} + echo "------------------------------------------------" + "${vcs_changeset_message[@]}" "${changeset}" > ${desc} + printf "%d: %s\n%s\n" ${index} "${changeset}" "`cat ${desc}|head -1`" + if [ "${year}" = "2010" ] ; then + if cat ${desc} | grep -i -F "Added tag" > /dev/null ; then + printf " EXCLUDED tag changeset.\n" + elif cat ${desc} | grep -i -F rebrand > /dev/null ; then + printf " EXCLUDED rebrand changeset.\n" + elif cat ${desc} | grep -i -F copyright > /dev/null ; then + printf " EXCLUDED copyright changeset.\n" + else + updateChangesetFiles ${changeset} + fi + else + if cat ${desc} | grep -i -F "Added tag" > /dev/null ; then + printf " EXCLUDED tag changeset.\n" + elif cat ${desc} | grep -i -F "copyright year" > /dev/null ; then + printf " EXCLUDED copyright year changeset.\n" + else + updateChangesetFiles ${changeset} + fi + fi + rm -f ${desc} + done + fi + + if [ ${total} -gt 0 ] ; then + echo "---------------------------------------------" + echo "Updated the copyright year on a total of ${total} files." + if [ ${previous} -eq 0 ] ; then + echo "This count should match the count of modified files in the repository: ${vcs_status[*]}" + else + echo "WARNING: This repository contained previously edited working set files." + fi + echo " ${vcs_status[*]} | wc -l = `"${vcs_status[@]}" | wc -l`" + else + echo "---------------------------------------------" + echo "No files were changed" + if [ ${previous} -ne 0 ] ; then + echo "WARNING: This repository contained previously edited working set files." + fi + echo " ${vcs_status[*]} | wc -l = `"${vcs_status[@]}" | wc -l`" + fi fi # Cleanup diff --git a/doc/building.html b/doc/building.html index 8e5a7625371..534888ef667 100644 --- a/doc/building.html +++ b/doc/building.html @@ -1385,10 +1385,9 @@ dpkg-deb -x /tmp/libasound2-dev_1.0.25-4_armhf.deb . can specify it by --with-alsa.

X11

-

You will need X11 libraries suitable for your target system. -In most cases, using Debian's pre-built libraries work fine.

-

Note that X11 is needed even if you only want to build a headless -JDK.

+

When not building a headless JDK, you will need X11 libraries +suitable for your target system. In most cases, using Debian's +pre-built libraries work fine.

* - * @see - * JLS 5.7.1 Exact Testing Conversions - * @see - * JLS 5.7.2 Unconditionally Exact Testing Conversions - * @see - * JLS 15.20.2 The instanceof Operator + * @jls primitive-types-in-patterns-instanceof-switch-5.7.1 Exact Testing Conversions + * @jls primitive-types-in-patterns-instanceof-switch-5.7.2 Unconditionally Exact Testing Conversions + * @jls primitive-types-in-patterns-instanceof-switch-15.20.2 The {@code instanceof} Operator * * @implNote Some exactness checks describe a test which can be redirected * safely through one of the existing methods. Those are omitted too (i.e., diff --git a/src/java.base/share/classes/java/nio/channels/AsynchronousServerSocketChannel.java b/src/java.base/share/classes/java/nio/channels/AsynchronousServerSocketChannel.java index 192b1f7958b..4e6cadc737c 100644 --- a/src/java.base/share/classes/java/nio/channels/AsynchronousServerSocketChannel.java +++ b/src/java.base/share/classes/java/nio/channels/AsynchronousServerSocketChannel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -208,7 +208,7 @@ public abstract class AsynchronousServerSocketChannel *

The {@code backlog} parameter is the maximum number of pending * connections on the socket. Its exact semantics are implementation specific. * In particular, an implementation may impose a maximum length or may choose - * to ignore the parameter altogther. If the {@code backlog} parameter has + * to ignore the parameter altogether. If the {@code backlog} parameter has * the value {@code 0}, or a negative value, then an implementation specific * default is used. * diff --git a/src/java.base/share/classes/java/nio/charset/Charset-X-Coder.java.template b/src/java.base/share/classes/java/nio/charset/Charset-X-Coder.java.template index e900c2eca0f..aca987ed678 100644 --- a/src/java.base/share/classes/java/nio/charset/Charset-X-Coder.java.template +++ b/src/java.base/share/classes/java/nio/charset/Charset-X-Coder.java.template @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -819,6 +819,12 @@ public abstract class Charset$Coder$ { */ public final $Otype$Buffer $code$($Itype$Buffer in) throws CharacterCodingException + { + return $code$(in, true); + } + + private $Otype$Buffer $code$($Itype$Buffer in, boolean throwOnError) + throws CharacterCodingException { int n = Math.min((int)(in.remaining() * average$ItypesPerOtype$()), ArraysSupport.SOFT_MAX_ARRAY_LENGTH); @@ -844,7 +850,11 @@ public abstract class Charset$Coder$ { out = o; continue; } - cr.throwException(); + if (throwOnError) { + cr.throwException(); + } else { + return null; + } } out.flip(); return out; @@ -938,7 +948,8 @@ public abstract class Charset$Coder$ { try { onMalformedInput(CodingErrorAction.REPORT); onUnmappableCharacter(CodingErrorAction.REPORT); - encode(cb); + ByteBuffer bb = encode(cb, false); + return bb != null; } catch (CharacterCodingException x) { return false; } finally { @@ -946,7 +957,6 @@ public abstract class Charset$Coder$ { onUnmappableCharacter(ua); reset(); } - return true; } /** diff --git a/src/java.base/share/classes/java/time/format/DateTimeFormatter.java b/src/java.base/share/classes/java/time/format/DateTimeFormatter.java index 16d7193c556..9368cf54afd 100644 --- a/src/java.base/share/classes/java/time/format/DateTimeFormatter.java +++ b/src/java.base/share/classes/java/time/format/DateTimeFormatter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -817,6 +817,7 @@ public final class DateTimeFormatter { *

  • The {@link #ISO_LOCAL_DATE} *
  • The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then * they will be handled even though this is not part of the ISO-8601 standard. + * The offset parsing is lenient, which allows the minutes and seconds to be optional. * Parsing is case insensitive. * *

    @@ -829,7 +830,9 @@ public final class DateTimeFormatter { ISO_OFFSET_DATE = new DateTimeFormatterBuilder() .parseCaseInsensitive() .append(ISO_LOCAL_DATE) + .parseLenient() .appendOffsetId() + .parseStrict() .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE); } @@ -846,6 +849,7 @@ public final class DateTimeFormatter { *

  • If the offset is not available then the format is complete. *
  • The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then * they will be handled even though this is not part of the ISO-8601 standard. + * The offset parsing is lenient, which allows the minutes and seconds to be optional. * Parsing is case insensitive. * *

    @@ -862,7 +866,9 @@ public final class DateTimeFormatter { .parseCaseInsensitive() .append(ISO_LOCAL_DATE) .optionalStart() + .parseLenient() .appendOffsetId() + .parseStrict() .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE); } @@ -919,6 +925,7 @@ public final class DateTimeFormatter { *

  • The {@link #ISO_LOCAL_TIME} *
  • The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then * they will be handled even though this is not part of the ISO-8601 standard. + * The offset parsing is lenient, which allows the minutes and seconds to be optional. * Parsing is case insensitive. * *

    @@ -930,7 +937,9 @@ public final class DateTimeFormatter { ISO_OFFSET_TIME = new DateTimeFormatterBuilder() .parseCaseInsensitive() .append(ISO_LOCAL_TIME) + .parseLenient() .appendOffsetId() + .parseStrict() .toFormatter(ResolverStyle.STRICT, null); } @@ -947,6 +956,7 @@ public final class DateTimeFormatter { *

  • If the offset is not available then the format is complete. *
  • The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then * they will be handled even though this is not part of the ISO-8601 standard. + * The offset parsing is lenient, which allows the minutes and seconds to be optional. * Parsing is case insensitive. * *

    @@ -962,7 +972,9 @@ public final class DateTimeFormatter { .parseCaseInsensitive() .append(ISO_LOCAL_TIME) .optionalStart() + .parseLenient() .appendOffsetId() + .parseStrict() .toFormatter(ResolverStyle.STRICT, null); } @@ -1075,6 +1087,7 @@ public final class DateTimeFormatter { *

  • If the offset is not available to format or parse then the format is complete. *
  • The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then * they will be handled even though this is not part of the ISO-8601 standard. + * The offset parsing is lenient, which allows the minutes and seconds to be optional. *
  • If the zone ID is not available or is a {@code ZoneOffset} then the format is complete. *
  • An open square bracket '['. *
  • The {@link ZoneId#getId() zone ID}. This is not part of the ISO-8601 standard. @@ -1094,7 +1107,9 @@ public final class DateTimeFormatter { ISO_DATE_TIME = new DateTimeFormatterBuilder() .append(ISO_LOCAL_DATE_TIME) .optionalStart() + .parseLenient() .appendOffsetId() + .parseStrict() .optionalStart() .appendLiteral('[') .parseCaseSensitive() @@ -1121,6 +1136,7 @@ public final class DateTimeFormatter { *
  • If the offset is not available to format or parse then the format is complete. *
  • The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then * they will be handled even though this is not part of the ISO-8601 standard. + * The offset parsing is lenient, which allows the minutes and seconds to be optional. * Parsing is case insensitive. * *

    @@ -1139,7 +1155,9 @@ public final class DateTimeFormatter { .appendLiteral('-') .appendValue(DAY_OF_YEAR, 3) .optionalStart() + .parseLenient() .appendOffsetId() + .parseStrict() .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE); } @@ -1165,6 +1183,7 @@ public final class DateTimeFormatter { *

  • If the offset is not available to format or parse then the format is complete. *
  • The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then * they will be handled even though this is not part of the ISO-8601 standard. + * The offset parsing is lenient, which allows the minutes and seconds to be optional. * Parsing is case insensitive. * *

    @@ -1185,7 +1204,9 @@ public final class DateTimeFormatter { .appendLiteral('-') .appendValue(DAY_OF_WEEK, 1) .optionalStart() + .parseLenient() .appendOffsetId() + .parseStrict() .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE); } diff --git a/src/java.base/share/classes/java/util/Optional.java b/src/java.base/share/classes/java/util/Optional.java index 3e577bd379c..3d0375c4354 100644 --- a/src/java.base/share/classes/java/util/Optional.java +++ b/src/java.base/share/classes/java/util/Optional.java @@ -25,7 +25,7 @@ package java.util; -import jdk.internal.vm.annotation.Stable; +import jdk.internal.vm.annotation.TrustFinalFields; import java.util.function.Consumer; import java.util.function.Function; @@ -62,6 +62,7 @@ import java.util.stream.Stream; * @since 1.8 */ @jdk.internal.ValueBased +@TrustFinalFields public final class Optional { /** * Common instance for {@code empty()}. @@ -71,7 +72,6 @@ public final class Optional { /** * If non-null, the value; if null, indicates no value is present */ - @Stable private final T value; /** diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java index 2250009e8f5..70acb8a0889 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java @@ -42,6 +42,8 @@ import java.util.function.IntUnaryOperator; import jdk.internal.misc.Unsafe; import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.Reflection; +import jdk.internal.vm.annotation.TrustFinalFields; + import java.lang.invoke.VarHandle; /** @@ -371,6 +373,7 @@ public abstract class AtomicIntegerFieldUpdater { /** * Standard hotspot implementation using intrinsics. */ + @TrustFinalFields private static final class AtomicIntegerFieldUpdaterImpl extends AtomicIntegerFieldUpdater { private static final Unsafe U = Unsafe.getUnsafe(); diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java index 5f0a666cb04..d3a3fe63d0f 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java @@ -42,6 +42,8 @@ import java.util.function.LongUnaryOperator; import jdk.internal.misc.Unsafe; import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.Reflection; +import jdk.internal.vm.annotation.TrustFinalFields; + import java.lang.invoke.VarHandle; /** @@ -368,6 +370,7 @@ public abstract class AtomicLongFieldUpdater { return next; } + @TrustFinalFields private static final class CASUpdater extends AtomicLongFieldUpdater { private static final Unsafe U = Unsafe.getUnsafe(); private final long offset; diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java index 4a758f77a47..3d47e8e323a 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java @@ -42,6 +42,8 @@ import java.util.function.UnaryOperator; import jdk.internal.misc.Unsafe; import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.Reflection; +import jdk.internal.vm.annotation.TrustFinalFields; + import java.lang.invoke.VarHandle; /** @@ -312,6 +314,7 @@ public abstract class AtomicReferenceFieldUpdater { return next; } + @TrustFinalFields private static final class AtomicReferenceFieldUpdaterImpl extends AtomicReferenceFieldUpdater { private static final Unsafe U = Unsafe.getUnsafe(); diff --git a/src/java.base/share/classes/java/util/jar/JarEntry.java b/src/java.base/share/classes/java/util/jar/JarEntry.java index ff0750a3342..6037ee243e5 100644 --- a/src/java.base/share/classes/java/util/jar/JarEntry.java +++ b/src/java.base/share/classes/java/util/jar/JarEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -114,8 +114,10 @@ public class JarEntry extends ZipEntry { * validate each signer's certificate chain, and determining whether * to trust the entry signed by the signers. * - * @return the {@code Certificate} objects for this entry, or - * {@code null} if none. + * @implSpec If non-null, this implementation returns a new array each time + * this method is invoked. + * + * @return the {@code Certificate} objects for this entry, or {@code null} if none. * */ public Certificate[] getCertificates() { @@ -139,8 +141,10 @@ public class JarEntry extends ZipEntry { * validate each signer's certificate chain, and determining whether * to trust the entry signed by the signers. * - * @return the {@code CodeSigner} objects for this entry, or - * {@code null} if none. + * @implSpec If non-null, this implementation returns a new array each time + * this method is invoked. + * + * @return the {@code CodeSigner} objects for this entry, or {@code null} if none. * * @since 1.5 */ diff --git a/src/java.base/share/classes/java/util/zip/ZipFile.java b/src/java.base/share/classes/java/util/zip/ZipFile.java index 7fa507980c2..a198c35c366 100644 --- a/src/java.base/share/classes/java/util/zip/ZipFile.java +++ b/src/java.base/share/classes/java/util/zip/ZipFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2026, Oracle and/or its affiliates. All rights reserved. * 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.nio.charset.Charset; import java.nio.file.InvalidPathException; import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.Files; +import java.nio.file.attribute.FileTime; import java.util.*; import java.util.function.Consumer; import java.util.function.IntFunction; @@ -86,11 +87,11 @@ public class ZipFile implements ZipConstants, Closeable { private final ZipCoder zipCoder; private volatile boolean closeRequested; - // The "resource" used by this ZIP file that needs to be - // cleaned after use. + // An object holding state which needs to be cleaned after + // this ZipFile is closed or becomes unreachable: // a) the input streams that need to be closed // b) the list of cached Inflater objects - // c) the "native" source of this ZIP file. + // c) the Source object providing read access to the actual ZIP file private final @Stable CleanableResource res; private static final int STORED = ZipEntry.STORED; @@ -1444,11 +1445,13 @@ public class ZipFile implements ZipConstants, Closeable { * The unique combination of these components identifies a Source of a ZipFile. */ private static class Key { - private final BasicFileAttributes attrs; private final File file; + private final Object fileKey; + private final FileTime lastModifiedTime; // the Charset that was provided when constructing the ZipFile instance private final Charset charset; + /** * Constructs a {@code Key} to a {@code Source} of a {@code ZipFile} * @@ -1457,7 +1460,8 @@ public class ZipFile implements ZipConstants, Closeable { * @param charset the Charset that was provided when constructing the ZipFile instance */ public Key(File file, BasicFileAttributes attrs, Charset charset) { - this.attrs = attrs; + this.fileKey = attrs.fileKey(); + this.lastModifiedTime = attrs.lastModifiedTime(); this.file = file; this.charset = charset; } @@ -1465,10 +1469,9 @@ public class ZipFile implements ZipConstants, Closeable { @Override public int hashCode() { long t = charset.hashCode(); - t += attrs.lastModifiedTime().toMillis(); - Object fk = attrs.fileKey(); + t += lastModifiedTime.toMillis(); return Long.hashCode(t) + - (fk != null ? fk.hashCode() : file.hashCode()); + (fileKey != null ? fileKey.hashCode() : file.hashCode()); } @Override @@ -1477,12 +1480,12 @@ public class ZipFile implements ZipConstants, Closeable { if (!charset.equals(key.charset)) { return false; } - if (!attrs.lastModifiedTime().equals(key.attrs.lastModifiedTime())) { + if (!lastModifiedTime.equals(key.lastModifiedTime)) { return false; } - Object fk = attrs.fileKey(); - if (fk != null) { - return fk.equals(key.attrs.fileKey()); + + if (fileKey != null) { + return fileKey.equals(key.fileKey); } else { return file.equals(key.file); } diff --git a/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java index b2a224f5917..9d980c3ba3b 100644 --- a/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java +++ b/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -448,15 +448,19 @@ public interface JavaLangAccess { PrintStream initialSystemErr(); /** - * Encodes as many ASCII codepoints as possible from the source array into - * the destination byte array, assuming that the encoding is ASCII - * compatible. - *

    - * WARNING: This method does not perform any bound checks. + * Encodes as many ASCII codepoints as possible from the source + * character array into the destination byte array, assuming that + * the encoding is ASCII compatible. * - * @return the number of bytes successfully encoded, or 0 if none + * @param sa the source character array + * @param sp the index of the source array to start reading from + * @param da the target byte array + * @param dp the index of the target array to start writing to + * @param len the total number of characters to be encoded + * @return the total number of characters successfully encoded + * @throws NullPointerException if any of the provided arrays is null */ - int uncheckedEncodeASCII(char[] src, int srcOff, byte[] dst, int dstOff, int len); + int encodeASCII(char[] sa, int sp, byte[] da, int dp, int len); /** * Set the cause of Throwable @@ -577,6 +581,16 @@ public interface JavaLangAccess { */ Object scopedValueBindings(); + /** + * Returns the native thread ID for the given platform thread or 0 if not set. + */ + long nativeThreadID(Thread thread); + + /** + * Sets the native thread ID for the current platform thread. + */ + void setThreadNativeID(long id); + /** * Returns the innermost mounted continuation */ @@ -640,4 +654,9 @@ public interface JavaLangAccess { * Are the string bytes compatible with the given charset? */ boolean bytesCompatible(String string, Charset charset, int srcIndex, int numChars); + + /** + * Finish initialization of the StackTraceElement objects in a stack trace. + */ + void finishInit(StackTraceElement[] stackTrace); } diff --git a/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java b/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java index f75d67adbbb..235797f66e3 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java +++ b/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java @@ -551,6 +551,7 @@ public abstract sealed class AbstractMemorySegmentImpl unsafeGetOffset() == that.unsafeGetOffset(); } + @ForceInline @Override public String getString(long offset, Charset charset, long byteLength) { Utils.checkNonNegativeArgument(byteLength, "byteLength"); diff --git a/src/java.base/share/classes/jdk/internal/io/JdkConsoleImpl.java b/src/java.base/share/classes/jdk/internal/io/JdkConsoleImpl.java index a6f4174324e..06aafaabe88 100644 --- a/src/java.base/share/classes/jdk/internal/io/JdkConsoleImpl.java +++ b/src/java.base/share/classes/jdk/internal/io/JdkConsoleImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. * 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,6 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.PrintWriter; import java.io.Reader; -import java.io.Writer; import java.nio.charset.Charset; import java.util.Arrays; import java.util.Formatter; @@ -84,18 +83,14 @@ public final class JdkConsoleImpl implements JdkConsole { @Override public String readLine(Locale locale, String format, Object ... args) { String line = null; - synchronized (writeLock) { - synchronized(readLock) { - if (!format.isEmpty()) - pw.format(locale, format, args); - try { - char[] ca = readline(false); - if (ca != null) - line = new String(ca); - } catch (IOException x) { - throw new IOError(x); - } - } + if (!format.isEmpty()) + pw.format(locale, format, args); + try { + char[] ca = readline(false); + if (ca != null) + line = new String(ca); + } catch (IOException x) { + throw new IOError(x); } return line; } @@ -116,24 +111,24 @@ public final class JdkConsoleImpl implements JdkConsole { // it should call this method to obtain a JdkConsoleImpl. This ensures only one Console // instance exists in the Java runtime. private static final LazyConstant> PASSWORD_CONSOLE = LazyConstant.of( - new Supplier>() { - @Override - public Optional get() { - if (System.console() != null) { - throw new IllegalStateException("Can’t create a dedicated password " + - "console since a real console already exists"); - } - - // If stdin is NOT redirected, return an Optional containing a JdkConsoleImpl - // instance, otherwise an empty Optional. - return SharedSecrets.getJavaIOAccess().isStdinTty() ? - Optional.of( - new JdkConsoleImpl( - Charset.forName(StaticProperty.stdinEncoding(), UTF_8.INSTANCE), - Charset.forName(StaticProperty.stdoutEncoding(), UTF_8.INSTANCE))) : - Optional.empty(); + new Supplier>() { + @Override + public Optional get() { + if (System.console() != null) { + throw new IllegalStateException("Can’t create a dedicated password " + + "console since a real console already exists"); } + + // If stdin is NOT redirected, return an Optional containing a JdkConsoleImpl + // instance, otherwise an empty Optional. + return SharedSecrets.getJavaIOAccess().isStdinTty() ? + Optional.of( + new JdkConsoleImpl( + Charset.forName(StaticProperty.stdinEncoding(), UTF_8.INSTANCE), + Charset.forName(StaticProperty.stdoutEncoding(), UTF_8.INSTANCE))) : + Optional.empty(); } + } ); public static Optional passwordConsole() { @@ -149,54 +144,51 @@ public final class JdkConsoleImpl implements JdkConsole { private char[] readPassword0(boolean noNewLine, Locale locale, String format, Object ... args) { char[] passwd = null; - synchronized (writeLock) { - synchronized(readLock) { - installShutdownHook(); - try { - synchronized(restoreEchoLock) { - restoreEcho = echo(false); - } - } catch (IOException x) { - throw new IOError(x); - } - IOError ioe = null; - try { - if (!format.isEmpty()) - pw.format(locale, format, args); - passwd = readline(true); - } catch (IOException x) { - ioe = new IOError(x); - } finally { - try { - synchronized(restoreEchoLock) { - if (restoreEcho) { - restoreEcho = echo(true); - } - } - } catch (IOException x) { - if (ioe == null) - ioe = new IOError(x); - else - ioe.addSuppressed(x); - } - if (ioe != null) { - if (passwd != null) { - Arrays.fill(passwd, ' '); - } - try { - if (reader instanceof LineReader lr) { - lr.zeroOut(); - } - } catch (IOException _) { - // ignore - } - throw ioe; - } - } - if (!noNewLine) { - pw.println(); - } + + installShutdownHook(); + try { + synchronized(restoreEchoLock) { + restoreEcho = echo(false); } + } catch (IOException x) { + throw new IOError(x); + } + IOError ioe = null; + try { + if (!format.isEmpty()) + pw.format(locale, format, args); + passwd = readline(true); + } catch (IOException x) { + ioe = new IOError(x); + } finally { + try { + synchronized(restoreEchoLock) { + if (restoreEcho) { + restoreEcho = echo(true); + } + } + } catch (IOException x) { + if (ioe == null) + ioe = new IOError(x); + else + ioe.addSuppressed(x); + } + if (ioe != null) { + if (passwd != null) { + Arrays.fill(passwd, ' '); + } + try { + if (reader instanceof LineReader lr) { + lr.zeroOut(); + } + } catch (IOException _) { + // ignore + } + throw ioe; + } + } + if (!noNewLine) { + pw.println(); } return passwd; } @@ -243,14 +235,11 @@ public final class JdkConsoleImpl implements JdkConsole { return outCharset; } - private final Charset inCharset; private final Charset outCharset; private final Object readLock; - private final Object writeLock; // Must not block while holding this. It is used in the shutdown hook. private final Object restoreEchoLock; private final Reader reader; - private final Writer out; private final PrintWriter pw; private final Formatter formatter; private char[] rcb; @@ -417,12 +406,11 @@ public final class JdkConsoleImpl implements JdkConsole { public JdkConsoleImpl(Charset inCharset, Charset outCharset) { Objects.requireNonNull(inCharset); Objects.requireNonNull(outCharset); - this.inCharset = inCharset; this.outCharset = outCharset; readLock = new Object(); - writeLock = new Object(); + var writeLock = new Object(); restoreEchoLock = new Object(); - out = StreamEncoder.forOutputStreamWriter( + var out = StreamEncoder.forOutputStreamWriter( new FileOutputStream(FileDescriptor.out), writeLock, outCharset); diff --git a/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java b/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java index 3504ce7e8b3..90771575657 100644 --- a/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java +++ b/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,6 @@ import java.net.URLStreamHandler; import java.net.URLStreamHandlerFactory; import java.security.CodeSigner; import java.security.cert.Certificate; -import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -98,11 +97,20 @@ public class URLClassPath { DEBUG_CP_URL_CHECK = p != null ? p.equals("true") || p.isEmpty() : false; } - /* The original search path of URLs. */ - private final ArrayList path; + /* Search path of URLs passed to the constructor or by calls to addURL. + * Access is guarded by a monitor on 'searchPath' itself + */ + private final ArrayList searchPath; - /* The deque of unopened URLs */ - private final ArrayDeque unopenedUrls; + /* Index of the next URL in the search path to process. + * Access is guarded by a monitor on 'searchPath' + */ + private int nextURL = 0; + + /* List of URLs found during expansion of JAR 'Class-Path' attributes. + * Access is guarded by a monitor on 'searchPath' + */ + private final ArrayList manifestClassPath = new ArrayList<>(); /* The resulting search path of Loaders */ private final ArrayList loaders = new ArrayList<>(); @@ -128,14 +136,8 @@ public class URLClassPath { */ public URLClassPath(URL[] urls, URLStreamHandlerFactory factory) { - ArrayList path = new ArrayList<>(urls.length); - ArrayDeque unopenedUrls = new ArrayDeque<>(urls.length); - for (URL url : urls) { - path.add(url); - unopenedUrls.add(url); - } - this.path = path; - this.unopenedUrls = unopenedUrls; + // Reject null URL array or any null element in the array + this.searchPath = new ArrayList<>(List.of(urls)); if (factory != null) { jarHandler = factory.createURLStreamHandler("jar"); @@ -174,16 +176,7 @@ public class URLClassPath { off = next + 1; } while (next != -1); } - - // can't use ArrayDeque#addAll or new ArrayDeque(Collection); - // it's too early in the bootstrap to trigger use of lambdas - int size = path.size(); - ArrayDeque unopenedUrls = new ArrayDeque<>(size); - for (int i = 0; i < size; i++) - unopenedUrls.add(path.get(i)); - - this.unopenedUrls = unopenedUrls; - this.path = path; + this.searchPath = path; // 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(); @@ -215,10 +208,9 @@ public class URLClassPath { public synchronized void addURL(URL url) { if (closed || url == null) return; - synchronized (unopenedUrls) { - if (! path.contains(url)) { - unopenedUrls.addLast(url); - path.add(url); + synchronized (searchPath) { + if (! searchPath.contains(url)) { + searchPath.add(url); } } } @@ -249,8 +241,8 @@ public class URLClassPath { * Returns the original search path of URLs. */ public URL[] getURLs() { - synchronized (unopenedUrls) { - return path.toArray(new URL[0]); + synchronized (searchPath) { + return searchPath.toArray(new URL[0]); } } @@ -379,6 +371,23 @@ public class URLClassPath { }; } + /* + * Returns the next URL to process or null if finished + */ + private URL nextURL() { + synchronized (searchPath) { + // Check paths discovered during 'Class-Path' expansion first + if (!manifestClassPath.isEmpty()) { + return manifestClassPath.removeLast(); + } + // Check the regular search path + if (nextURL < searchPath.size()) { + return searchPath.get(nextURL++); + } + // All paths exhausted + return null; + } + } /* * Returns the Loader at the specified position in the URL search * path. The URLs are opened and expanded as needed. Returns null @@ -389,14 +398,13 @@ public class URLClassPath { return null; } // Expand URL search path until the request can be satisfied - // or unopenedUrls is exhausted. + // or all paths are exhausted. while (loaders.size() < index + 1) { - final URL url; - synchronized (unopenedUrls) { - url = unopenedUrls.pollFirst(); - if (url == null) - return null; + final URL url = nextURL(); + if (url == null) { + return null; } + // Skip this URL if it already has a Loader. String urlNoFragString = URLUtil.urlNoFragString(url); if (lmap.containsKey(urlNoFragString)) { @@ -422,7 +430,7 @@ public class URLClassPath { continue; } if (loaderClassPathURLs != null) { - push(loaderClassPathURLs); + addManifestClassPaths(loaderClassPathURLs); } // Finally, add the Loader to the search path. loaders.add(loader); @@ -475,13 +483,12 @@ public class URLClassPath { } /* - * Pushes the specified URLs onto the head of unopened URLs. + * Adds the specified URLs to the list of 'Class-Path' expanded URLs */ - private void push(URL[] urls) { - synchronized (unopenedUrls) { - for (int i = urls.length - 1; i >= 0; --i) { - unopenedUrls.addFirst(urls[i]); - } + private void addManifestClassPaths(URL[] urls) { + synchronized (searchPath) { + // Adding in reversed order since manifestClassPath is consumed tail-first + manifestClassPath.addAll(Arrays.asList(urls).reversed()); } } diff --git a/src/java.base/share/classes/jdk/internal/misc/X-ScopedMemoryAccess.java.template b/src/java.base/share/classes/jdk/internal/misc/X-ScopedMemoryAccess.java.template index b594aca7a05..a04fea67b88 100644 --- a/src/java.base/share/classes/jdk/internal/misc/X-ScopedMemoryAccess.java.template +++ b/src/java.base/share/classes/jdk/internal/misc/X-ScopedMemoryAccess.java.template @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -326,7 +326,7 @@ public final class ScopedMemoryAccess { @ForceInline public static , E, S extends VectorSupport.VectorSpecies> - V loadFromMemorySegment(Class vmClass, Class e, int length, + V loadFromMemorySegment(Class vmClass, int laneType, int length, AbstractMemorySegmentImpl msp, long offset, S s, VectorSupport.LoadOperation defaultImpl) { @@ -334,7 +334,7 @@ public final class ScopedMemoryAccess { try { return loadFromMemorySegmentScopedInternal( msp.sessionImpl(), - vmClass, e, length, + vmClass, laneType, length, msp, offset, s, defaultImpl); @@ -348,14 +348,14 @@ public final class ScopedMemoryAccess { private static , E, S extends VectorSupport.VectorSpecies> V loadFromMemorySegmentScopedInternal(MemorySessionImpl session, - Class vmClass, Class e, int length, + Class vmClass, int laneType, int length, AbstractMemorySegmentImpl msp, long offset, S s, VectorSupport.LoadOperation defaultImpl) { try { session.checkValidStateRaw(); - return VectorSupport.load(vmClass, e, length, + return VectorSupport.load(vmClass, laneType, length, msp.unsafeGetBase(), msp.unsafeGetOffset() + offset, true, msp, offset, s, defaultImpl); @@ -368,14 +368,14 @@ public final class ScopedMemoryAccess { public static , E, S extends VectorSupport.VectorSpecies, M extends VectorSupport.VectorMask> - V loadFromMemorySegmentMasked(Class vmClass, Class maskClass, Class e, + V loadFromMemorySegmentMasked(Class vmClass, Class maskClass, int laneType, int length, AbstractMemorySegmentImpl msp, long offset, M m, S s, int offsetInRange, VectorSupport.LoadVectorMaskedOperation defaultImpl) { try { return loadFromMemorySegmentMaskedScopedInternal( msp.sessionImpl(), - vmClass, maskClass, e, length, + vmClass, maskClass, laneType, length, msp, offset, m, s, offsetInRange, defaultImpl); @@ -390,14 +390,14 @@ public final class ScopedMemoryAccess { , E, S extends VectorSupport.VectorSpecies, M extends VectorSupport.VectorMask> V loadFromMemorySegmentMaskedScopedInternal(MemorySessionImpl session, Class vmClass, - Class maskClass, Class e, int length, + Class maskClass, int laneType, int length, AbstractMemorySegmentImpl msp, long offset, M m, S s, int offsetInRange, VectorSupport.LoadVectorMaskedOperation defaultImpl) { try { session.checkValidStateRaw(); - return VectorSupport.loadMasked(vmClass, maskClass, e, length, + return VectorSupport.loadMasked(vmClass, maskClass, laneType, length, msp.unsafeGetBase(), msp.unsafeGetOffset() + offset, true, m, offsetInRange, msp, offset, s, defaultImpl); @@ -409,7 +409,7 @@ public final class ScopedMemoryAccess { @ForceInline public static , E> - void storeIntoMemorySegment(Class vmClass, Class e, int length, + void storeIntoMemorySegment(Class vmClass, int laneType, int length, V v, AbstractMemorySegmentImpl msp, long offset, VectorSupport.StoreVectorOperation defaultImpl) { @@ -417,7 +417,7 @@ public final class ScopedMemoryAccess { try { storeIntoMemorySegmentScopedInternal( msp.sessionImpl(), - vmClass, e, length, + vmClass, laneType, length, v, msp, offset, defaultImpl); @@ -431,14 +431,14 @@ public final class ScopedMemoryAccess { private static , E> void storeIntoMemorySegmentScopedInternal(MemorySessionImpl session, - Class vmClass, Class e, int length, + Class vmClass, int laneType, int length, V v, AbstractMemorySegmentImpl msp, long offset, VectorSupport.StoreVectorOperation defaultImpl) { try { session.checkValidStateRaw(); - VectorSupport.store(vmClass, e, length, + VectorSupport.store(vmClass, laneType, length, msp.unsafeGetBase(), msp.unsafeGetOffset() + offset, true, v, msp, offset, @@ -451,15 +451,15 @@ public final class ScopedMemoryAccess { @ForceInline public static , E, M extends VectorSupport.VectorMask> - void storeIntoMemorySegmentMasked(Class vmClass, Class maskClass, Class e, - int length, V v, M m, + void storeIntoMemorySegmentMasked(Class vmClass, Class maskClass, + int laneType, int length, V v, M m, AbstractMemorySegmentImpl msp, long offset, VectorSupport.StoreVectorMaskedOperation defaultImpl) { try { storeIntoMemorySegmentMaskedScopedInternal( msp.sessionImpl(), - vmClass, maskClass, e, length, + vmClass, maskClass, laneType, length, v, m, msp, offset, defaultImpl); @@ -474,13 +474,13 @@ public final class ScopedMemoryAccess { , E, M extends VectorSupport.VectorMask> void storeIntoMemorySegmentMaskedScopedInternal(MemorySessionImpl session, Class vmClass, Class maskClass, - Class e, int length, V v, M m, + int laneType, int length, V v, M m, AbstractMemorySegmentImpl msp, long offset, VectorSupport.StoreVectorMaskedOperation defaultImpl) { try { session.checkValidStateRaw(); - VectorSupport.storeMasked(vmClass, maskClass, e, length, + VectorSupport.storeMasked(vmClass, maskClass, laneType, length, msp.unsafeGetBase(), msp.unsafeGetOffset() + offset, true, v, m, msp, offset, diff --git a/src/java.base/share/classes/jdk/internal/vm/ThreadSnapshot.java b/src/java.base/share/classes/jdk/internal/vm/ThreadSnapshot.java index 357d38008d1..e84027764f1 100644 --- a/src/java.base/share/classes/jdk/internal/vm/ThreadSnapshot.java +++ b/src/java.base/share/classes/jdk/internal/vm/ThreadSnapshot.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. * 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,11 +26,14 @@ package jdk.internal.vm; import java.util.Arrays; import java.util.stream.Stream; +import jdk.internal.access.JavaLangAccess; +import jdk.internal.access.SharedSecrets; /** * Represents a snapshot of information about a Thread. */ class ThreadSnapshot { + private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); private static final StackTraceElement[] EMPTY_STACK = new StackTraceElement[0]; private static final ThreadLock[] EMPTY_LOCKS = new ThreadLock[0]; @@ -54,16 +57,16 @@ class ThreadSnapshot { /** * Take a snapshot of a Thread to get all information about the thread. - * Return null if a ThreadSnapshot is not created, for example if the - * thread has terminated. - * @throws UnsupportedOperationException if not supported by VM + * @return the snapshot or {@code null} if the thread is not alive */ static ThreadSnapshot of(Thread thread) { - ThreadSnapshot snapshot = create(thread); + ThreadSnapshot snapshot = thread.isAlive() ? create(thread) : null; if (snapshot == null) { - return null; // thread terminated + return null; // thread not alive } - if (snapshot.stackTrace == null) { + if (snapshot.stackTrace != null) { + JLA.finishInit(snapshot.stackTrace); + } else { snapshot.stackTrace = EMPTY_STACK; } if (snapshot.locks != null) { diff --git a/src/java.base/share/classes/jdk/internal/vm/annotation/TrustFinalFields.java b/src/java.base/share/classes/jdk/internal/vm/annotation/TrustFinalFields.java new file mode 100644 index 00000000000..a94f58159a2 --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/vm/annotation/TrustFinalFields.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.internal.vm.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/// Indicates all instance final fields declared in the annotated class should +/// be trusted as constants by compilers in `ciField::is_constant`. +/// +/// The compiler already treats static final fields and instance final fields in +/// record classes and hidden classes as constant. All classes in select +/// packages (Defined in `trust_final_non_static_fields` in `ciField.cpp`) in +/// the boot class loader also have their instance final fields trusted. This +/// annotation is not necessary in these cases. +/// +/// The [Stable] annotation treats fields as constants once they are not the +/// zero or null value. In comparison, a non-stable final instance field +/// trusted by this annotation can treat zero and null values as constants. +/// +/// This annotation is suitable when constant treatment of final fields is +/// performance sensitive, yet package-wide final field constant treatment may +/// be at risk from final field modifications such as serialization. +/// +/// This annotation is only recognized on classes from the boot and platform +/// class loaders and is ignored elsewhere. +/// +/// @since 26 +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface TrustFinalFields { +} diff --git a/src/java.base/share/classes/jdk/internal/vm/vector/VectorSupport.java b/src/java.base/share/classes/jdk/internal/vm/vector/VectorSupport.java index d3705a279ca..03f95222a52 100644 --- a/src/java.base/share/classes/jdk/internal/vm/vector/VectorSupport.java +++ b/src/java.base/share/classes/jdk/internal/vm/vector/VectorSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -149,14 +149,14 @@ public class VectorSupport { public static final int MODE_BROADCAST = 0; public static final int MODE_BITS_COERCED_LONG_TO_MASK = 1; - // BasicType codes, for primitives only: + // Values correspond to jdk.incubator.vector.LaneType ordinals public static final int - T_FLOAT = 6, - T_DOUBLE = 7, - T_BYTE = 8, - T_SHORT = 9, - T_INT = 10, - T_LONG = 11; + LT_FLOAT = 0, + LT_DOUBLE = 1, + LT_BYTE = 2, + LT_SHORT = 3, + LT_INT = 4, + LT_LONG = 5; /* ============================================================================ */ @@ -203,7 +203,7 @@ public class VectorSupport { , E> - VM fromBitsCoerced(Class vmClass, Class eClass, + VM fromBitsCoerced(Class vmClass, int laneType, int length, long bits, int mode, S s, FromBitsCoercedOperation defaultImpl) { @@ -221,7 +221,7 @@ public class VectorSupport { public static > - M indexPartiallyInUpperRange(Class mClass, Class eClass, + M indexPartiallyInUpperRange(Class mClass, int laneType, int length, long offset, long limit, IndexPartiallyInUpperRangeOperation defaultImpl) { assert isNonCapturingLambda(defaultImpl) : defaultImpl; @@ -239,7 +239,7 @@ public class VectorSupport { , E, S extends VectorSpecies> - V indexVector(Class vClass, Class eClass, + V indexVector(Class vClass, int laneType, int length, V v, int step, S s, IndexOperation defaultImpl) { @@ -260,7 +260,7 @@ public class VectorSupport { M extends VectorMask, E> long reductionCoerced(int oprId, - Class vClass, Class mClass, Class eClass, + Class vClass, Class mClass, int laneType, int length, V v, M m, ReductionOperation defaultImpl) { @@ -279,7 +279,7 @@ public class VectorSupport { public static - long extract(Class vClass, Class eClass, + long extract(Class vClass, int laneType, int length, VM vm, int i, VecExtractOp defaultImpl) { @@ -297,7 +297,7 @@ public class VectorSupport { public static , E> - V insert(Class vClass, Class eClass, + V insert(Class vClass, int laneType, int length, V v, int i, long val, VecInsertOp defaultImpl) { @@ -318,7 +318,7 @@ public class VectorSupport { M extends VectorMask, E> V unaryOp(int oprId, - Class vClass, Class mClass, Class eClass, + Class vClass, Class mClass, int laneType, int length, V v, M m, UnaryOperation defaultImpl) { @@ -356,7 +356,7 @@ public class VectorSupport { M extends VectorMask, E> VM binaryOp(int oprId, - Class vmClass, Class mClass, Class eClass, + Class vmClass, Class mClass, int laneType, int length, VM v1, VM v2, M m, BinaryOperation defaultImpl) { @@ -391,7 +391,7 @@ public class VectorSupport { public static , E> - V selectFromTwoVectorOp(Class vClass, Class eClass, int length, + V selectFromTwoVectorOp(Class vClass, int laneType, int length, V v1, V v2, V v3, SelectFromTwoVector defaultImpl) { assert isNonCapturingLambda(defaultImpl) : defaultImpl; @@ -413,7 +413,7 @@ public class VectorSupport { M extends VectorMask, E> V ternaryOp(int oprId, - Class vClass, Class mClass, Class eClass, + Class vClass, Class mClass, int laneType, int length, V v1, V v2, V v3, M m, TernaryOperation defaultImpl) { @@ -437,7 +437,7 @@ public class VectorSupport { VM extends VectorPayload, E, S extends VectorSpecies> - VM load(Class vmClass, Class eClass, + VM load(Class vmClass, int laneType, int length, Object base, long offset, boolean fromSegment, C container, long index, S s, @@ -462,7 +462,7 @@ public class VectorSupport { E, S extends VectorSpecies, M extends VectorMask> - V loadMasked(Class vClass, Class mClass, Class eClass, + V loadMasked(Class vClass, Class mClass, int laneType, int length, Object base, long offset, boolean fromSegment, M m, int offsetInRange, C container, long index, S s, @@ -488,7 +488,7 @@ public class VectorSupport { S extends VectorSpecies, M extends VectorMask, E> - V loadWithMap(Class vClass, Class mClass, Class eClass, + V loadWithMap(Class vClass, Class mClass, int laneType, int length, Class> vectorIndexClass, int indexLength, Object base, long offset, @@ -510,7 +510,7 @@ public class VectorSupport { public static - void store(Class vClass, Class eClass, + void store(Class vClass, int laneType, int length, Object base, long offset, boolean fromSegment, V v, C container, long index, @@ -531,7 +531,7 @@ public class VectorSupport { V extends Vector, M extends VectorMask, E> - void storeMasked(Class vClass, Class mClass, Class eClass, + void storeMasked(Class vClass, Class mClass, int laneType, int length, Object base, long offset, boolean fromSegment, V v, M m, C container, long index, @@ -555,7 +555,7 @@ public class VectorSupport { W extends Vector, M extends VectorMask, E> - void storeWithMap(Class vClass, Class mClass, Class eClass, + void storeWithMap(Class vClass, Class mClass, int laneType, int length, Class> vectorIndexClass, int indexLength, Object base, long offset, @@ -573,7 +573,7 @@ public class VectorSupport { , E> boolean test(int cond, - Class mClass, Class eClass, + Class mClass, int laneType, int length, M m1, M m2, BiFunction defaultImpl) { @@ -594,7 +594,7 @@ public class VectorSupport { M extends VectorMask, E> M compare(int cond, - Class vectorClass, Class mClass, Class eClass, + Class vectorClass, Class mClass, int laneType, int length, V v1, V v2, M m, VectorCompareOp defaultImpl) { @@ -615,7 +615,7 @@ public class VectorSupport { SH extends VectorShuffle, M extends VectorMask, E> - V rearrangeOp(Class vClass, Class shClass, Class mClass, Class eClass, + V rearrangeOp(Class vClass, Class shClass, Class mClass, int laneType, int length, V v, SH sh, M m, VectorRearrangeOp defaultImpl) { @@ -633,7 +633,7 @@ public class VectorSupport { , M extends VectorMask, E> - V selectFromOp(Class vClass, Class mClass, Class eClass, + V selectFromOp(Class vClass, Class mClass, int laneType, int length, V v1, V v2, M m, VectorSelectFromOp defaultImpl) { assert isNonCapturingLambda(defaultImpl) : defaultImpl; @@ -652,7 +652,7 @@ public class VectorSupport { , M extends VectorMask, E> - V blend(Class vClass, Class mClass, Class eClass, + V blend(Class vClass, Class mClass, int laneType, int length, V v1, V v2, M m, VectorBlendOp defaultImpl) { @@ -673,7 +673,7 @@ public class VectorSupport { M extends VectorMask, E> V broadcastInt(int opr, - Class vClass, Class mClass, Class eClass, + Class vClass, Class mClass, int laneType, int length, V v, int n, M m, VectorBroadcastIntOp defaultImpl) { @@ -698,8 +698,8 @@ public class VectorSupport { VIN extends VectorPayload, S extends VectorSpecies> VOUT convert(int oprId, - Class fromVectorClass, Class fromeClass, int fromVLen, - Class toVectorClass, Class toeClass, int toVLen, + Class fromVectorClass, int fromLaneType, int fromVLen, + Class toVectorClass, int toLaneType, int toVLen, VIN v, S s, VectorConvertOp defaultImpl) { assert isNonCapturingLambda(defaultImpl) : defaultImpl; @@ -719,7 +719,7 @@ public class VectorSupport { M extends VectorMask, E> VectorPayload compressExpandOp(int opr, - Class vClass, Class mClass, Class eClass, + Class vClass, Class mClass, int laneType, int length, V v, M m, CompressExpandOperation defaultImpl) { assert isNonCapturingLambda(defaultImpl) : defaultImpl; @@ -748,7 +748,7 @@ public class VectorSupport { , E> long maskReductionCoerced(int oper, - Class mClass, Class eClass, + Class mClass, int laneType, int length, M m, VectorMaskOp defaultImpl) { diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java index 89ad0cc48ed..3a915cf96df 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java +++ b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1677,11 +1677,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { if (method.equals("HEAD") || cl == 0 || respCode == HTTP_NOT_MODIFIED || respCode == HTTP_NO_CONTENT) { - - http.finished(); - http = null; - inputStream = new EmptyInputStream(); - connected = false; + noResponseBody(); } if (respCode == 200 || respCode == 203 || respCode == 206 || @@ -1763,6 +1759,24 @@ public class HttpURLConnection extends java.net.HttpURLConnection { } } + /** + * This method is called when a response with no response + * body is received, and arrange for the http client to + * be returned to the pool (or released) immediately when + * possible. + * @apiNote Used by {@link sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection} + * to preserve the TLS information after receiving an empty body. + * @implSpec + * Subclasses that override this method should call the super class + * implementation. + */ + protected void noResponseBody() { + http.finished(); + http = null; + inputStream = new EmptyInputStream(); + connected = false; + } + /* * Creates a chained exception that has the same type as * original exception and with the same message. Right now, diff --git a/src/java.base/share/classes/sun/net/www/protocol/https/AbstractDelegateHttpsURLConnection.java b/src/java.base/share/classes/sun/net/www/protocol/https/AbstractDelegateHttpsURLConnection.java index 7bf8280a7ad..1415658e34d 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/https/AbstractDelegateHttpsURLConnection.java +++ b/src/java.base/share/classes/sun/net/www/protocol/https/AbstractDelegateHttpsURLConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,6 +51,7 @@ import sun.net.www.protocol.http.HttpCallerInfo; public abstract class AbstractDelegateHttpsURLConnection extends HttpURLConnection { + private SSLSession savedSession = null; protected AbstractDelegateHttpsURLConnection(URL url, sun.net.www.protocol.http.Handler handler) throws IOException { this(url, null, handler); @@ -92,6 +93,7 @@ public abstract class AbstractDelegateHttpsURLConnection extends public void setNewClient (URL url, boolean useCache) throws IOException { int readTimeout = getReadTimeout(); + savedSession = null; http = HttpsClient.New (getSSLSocketFactory(), url, getHostnameVerifier(), @@ -184,6 +186,7 @@ public abstract class AbstractDelegateHttpsURLConnection extends if (!http.isCachedConnection() && http.needsTunneling()) { doTunneling(); } + savedSession = null; ((HttpsClient)http).afterConnect(); } @@ -204,6 +207,19 @@ public abstract class AbstractDelegateHttpsURLConnection extends useCache, connectTimeout, this); } + @Override + protected void noResponseBody() { + savedSession = ((HttpsClient)http).getSSLSession(); + super.noResponseBody(); + } + + private SSLSession session() { + if (http instanceof HttpsClient https) { + return https.getSSLSession(); + } + return savedSession; + } + /** * Returns the cipher suite in use on this connection. */ @@ -211,11 +227,12 @@ public abstract class AbstractDelegateHttpsURLConnection extends if (cachedResponse != null) { return ((SecureCacheResponse)cachedResponse).getCipherSuite(); } - if (http == null) { + + var session = session(); + if (session == null) { throw new IllegalStateException("connection not yet open"); - } else { - return ((HttpsClient)http).getCipherSuite (); } + return session.getCipherSuite(); } /** @@ -231,11 +248,12 @@ public abstract class AbstractDelegateHttpsURLConnection extends return l.toArray(new java.security.cert.Certificate[0]); } } - if (http == null) { + + var session = session(); + if (session == null) { throw new IllegalStateException("connection not yet open"); - } else { - return (((HttpsClient)http).getLocalCertificates ()); } + return session.getLocalCertificates(); } /** @@ -256,11 +274,11 @@ public abstract class AbstractDelegateHttpsURLConnection extends } } - if (http == null) { + var session = session(); + if (session == null) { throw new IllegalStateException("connection not yet open"); - } else { - return (((HttpsClient)http).getServerCertificates ()); } + return session.getPeerCertificates(); } /** @@ -274,11 +292,11 @@ public abstract class AbstractDelegateHttpsURLConnection extends return ((SecureCacheResponse)cachedResponse).getPeerPrincipal(); } - if (http == null) { + var session = session(); + if (session == null) { throw new IllegalStateException("connection not yet open"); - } else { - return (((HttpsClient)http).getPeerPrincipal()); } + return getPeerPrincipal(session); } /** @@ -291,11 +309,11 @@ public abstract class AbstractDelegateHttpsURLConnection extends return ((SecureCacheResponse)cachedResponse).getLocalPrincipal(); } - if (http == null) { + var session = session(); + if (session == null) { throw new IllegalStateException("connection not yet open"); - } else { - return (((HttpsClient)http).getLocalPrincipal()); } + return getLocalPrincipal(session); } SSLSession getSSLSession() { @@ -307,11 +325,12 @@ public abstract class AbstractDelegateHttpsURLConnection extends } } - if (http == null) { + var session = session(); + if (session == null) { throw new IllegalStateException("connection not yet open"); } - return ((HttpsClient)http).getSSLSession(); + return session; } /* @@ -354,7 +373,7 @@ public abstract class AbstractDelegateHttpsURLConnection extends } HttpsClient https = (HttpsClient)http; try { - Certificate[] certs = https.getServerCertificates(); + Certificate[] certs = https.getSSLSession().getPeerCertificates(); if (certs[0] instanceof X509Certificate x509Cert) { return new HttpCallerInfo(url, proxy, port, x509Cert, authenticator); } @@ -372,7 +391,7 @@ public abstract class AbstractDelegateHttpsURLConnection extends } HttpsClient https = (HttpsClient)http; try { - Certificate[] certs = https.getServerCertificates(); + Certificate[] certs = https.getSSLSession().getPeerCertificates(); if (certs[0] instanceof X509Certificate x509Cert) { return new HttpCallerInfo(url, x509Cert, authenticator); } @@ -381,4 +400,58 @@ public abstract class AbstractDelegateHttpsURLConnection extends } return super.getHttpCallerInfo(url, authenticator); } + + @Override + public void disconnect() { + super.disconnect(); + savedSession = null; + } + + /** + * Returns the principal with which the server authenticated + * itself, or throw a SSLPeerUnverifiedException if the + * server did not authenticate. + * @param session The {@linkplain #getSSLSession() SSL session} + */ + private static Principal getPeerPrincipal(SSLSession session) + throws SSLPeerUnverifiedException + { + Principal principal; + try { + principal = session.getPeerPrincipal(); + } catch (AbstractMethodError e) { + // if the provider does not support it, fallback to peer certs. + // return the X500Principal of the end-entity cert. + java.security.cert.Certificate[] certs = + session.getPeerCertificates(); + principal = ((X509Certificate)certs[0]).getSubjectX500Principal(); + } + return principal; + } + + /** + * Returns the principal the client sent to the + * server, or null if the client did not authenticate. + * @param session The {@linkplain #getSSLSession() SSL session} + */ + private static Principal getLocalPrincipal(SSLSession session) + { + Principal principal; + try { + principal = session.getLocalPrincipal(); + } catch (AbstractMethodError e) { + principal = null; + // if the provider does not support it, fallback to local certs. + // return the X500Principal of the end-entity cert. + java.security.cert.Certificate[] certs = + session.getLocalCertificates(); + if (certs != null) { + principal = ((X509Certificate)certs[0]).getSubjectX500Principal(); + } + } + return principal; + } + + + } diff --git a/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java b/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java index 9f1d7b07021..f5804cd83bd 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java +++ b/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -599,75 +599,6 @@ final class HttpsClient extends HttpClient } } - /** - * Returns the cipher suite in use on this connection. - */ - String getCipherSuite() { - return session.getCipherSuite(); - } - - /** - * Returns the certificate chain the client sent to the - * server, or null if the client did not authenticate. - */ - public java.security.cert.Certificate [] getLocalCertificates() { - return session.getLocalCertificates(); - } - - /** - * Returns the certificate chain with which the server - * authenticated itself, or throw a SSLPeerUnverifiedException - * if the server did not authenticate. - */ - java.security.cert.Certificate [] getServerCertificates() - throws SSLPeerUnverifiedException - { - return session.getPeerCertificates(); - } - - /** - * Returns the principal with which the server authenticated - * itself, or throw a SSLPeerUnverifiedException if the - * server did not authenticate. - */ - Principal getPeerPrincipal() - throws SSLPeerUnverifiedException - { - Principal principal; - try { - principal = session.getPeerPrincipal(); - } catch (AbstractMethodError e) { - // if the provider does not support it, fallback to peer certs. - // return the X500Principal of the end-entity cert. - java.security.cert.Certificate[] certs = - session.getPeerCertificates(); - principal = ((X509Certificate)certs[0]).getSubjectX500Principal(); - } - return principal; - } - - /** - * Returns the principal the client sent to the - * server, or null if the client did not authenticate. - */ - Principal getLocalPrincipal() - { - Principal principal; - try { - principal = session.getLocalPrincipal(); - } catch (AbstractMethodError e) { - principal = null; - // if the provider does not support it, fallback to local certs. - // return the X500Principal of the end-entity cert. - java.security.cert.Certificate[] certs = - session.getLocalCertificates(); - if (certs != null) { - principal = ((X509Certificate)certs[0]).getSubjectX500Principal(); - } - } - return principal; - } - /** * Returns the {@code SSLSession} in use on this connection. */ diff --git a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java index afb312ed722..f5002e8b716 100644 --- a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java @@ -134,9 +134,9 @@ class DatagramChannelImpl private static final int ST_CLOSED = 3; private int state; - // IDs of native threads doing reads and writes, for signalling - private long readerThread; - private long writerThread; + // Threads doing reads and writes, for signalling + private Thread readerThread; + private Thread writerThread; // Local and remote (connected) address private InetSocketAddress localAddress; @@ -523,7 +523,7 @@ class DatagramChannelImpl if (localAddress == null) bindInternal(null); if (blocking) - readerThread = NativeThread.current(); + readerThread = NativeThread.threadToSignal(); } return remote; } @@ -538,7 +538,7 @@ class DatagramChannelImpl { if (blocking) { synchronized (stateLock) { - readerThread = 0; + readerThread = null; if (state == ST_CLOSING) { tryFinishClose(); } @@ -1030,7 +1030,7 @@ class DatagramChannelImpl if (localAddress == null) bindInternal(null); if (blocking) - writerThread = NativeThread.current(); + writerThread = NativeThread.threadToSignal(); } return remote; } @@ -1045,7 +1045,7 @@ class DatagramChannelImpl { if (blocking) { synchronized (stateLock) { - writerThread = 0; + writerThread = null; if (state == ST_CLOSING) { tryFinishClose(); } @@ -1714,7 +1714,7 @@ class DatagramChannelImpl */ private boolean tryClose() throws IOException { assert Thread.holdsLock(stateLock) && state == ST_CLOSING; - if ((readerThread == 0) && (writerThread == 0) && !isRegistered()) { + if ((readerThread == null) && (writerThread == null) && !isRegistered()) { state = ST_CLOSED; try { // close socket diff --git a/src/java.base/share/classes/sun/nio/ch/IOUtil.java b/src/java.base/share/classes/sun/nio/ch/IOUtil.java index 45f8cb2e588..df6677ab94d 100644 --- a/src/java.base/share/classes/sun/nio/ch/IOUtil.java +++ b/src/java.base/share/classes/sun/nio/ch/IOUtil.java @@ -587,9 +587,11 @@ public final class IOUtil { */ static native int drain1(int fd) throws IOException; - public static native void configureBlocking(FileDescriptor fd, - boolean blocking) - throws IOException; + static native void configureBlocking(int fd, boolean blocking) throws IOException; + + public static void configureBlocking(FileDescriptor fd, boolean blocking) throws IOException { + configureBlocking(fdVal(fd), blocking); + } public static native int fdVal(FileDescriptor fd); diff --git a/src/java.base/share/classes/sun/nio/ch/NativeDispatcher.java b/src/java.base/share/classes/sun/nio/ch/NativeDispatcher.java index 9b65310784a..63009b407ac 100644 --- a/src/java.base/share/classes/sun/nio/ch/NativeDispatcher.java +++ b/src/java.base/share/classes/sun/nio/ch/NativeDispatcher.java @@ -27,8 +27,6 @@ package sun.nio.ch; import java.io.FileDescriptor; import java.io.IOException; -import jdk.internal.access.JavaIOFileDescriptorAccess; -import jdk.internal.access.SharedSecrets; /** * Allows different platforms to call different native methods @@ -36,7 +34,6 @@ import jdk.internal.access.SharedSecrets; */ abstract class NativeDispatcher { - private static final JavaIOFileDescriptorAccess JIOFDA = SharedSecrets.getJavaIOFileDescriptorAccess(); abstract int read(FileDescriptor fd, long address, int len) throws IOException; @@ -78,12 +75,17 @@ abstract class NativeDispatcher { * if a platform thread is blocked on the file descriptor then the file descriptor is * dup'ed to a special fd and the thread signalled so that the syscall fails with EINTR. */ - final void preClose(FileDescriptor fd, long reader, long writer) throws IOException { - if (NativeThread.isVirtualThread(reader) || NativeThread.isVirtualThread(writer)) { - int fdVal = JIOFDA.get(fd); - Poller.stopPoll(fdVal); + final void preClose(FileDescriptor fd, Thread reader, Thread writer) throws IOException { + if (reader != null && reader.isVirtual()) { + NativeThread.signal(reader); // unparks virtual thread + reader = null; } - if (NativeThread.isNativeThread(reader) || NativeThread.isNativeThread(writer)) { + if (writer != null && writer.isVirtual()) { + NativeThread.signal(writer); // unparks virtual thread + writer = null; + } + // dup2 and signal platform threads + if (reader != null || writer != null) { implPreClose(fd, reader, writer); } } @@ -92,8 +94,7 @@ abstract class NativeDispatcher { * This method does nothing by default. On Unix systems the file descriptor is dup'ed * to a special fd and native threads signalled. */ - - void implPreClose(FileDescriptor fd, long reader, long writer) throws IOException { + void implPreClose(FileDescriptor fd, Thread reader, Thread writer) throws IOException { // Do nothing by default; this is only needed on Unix } diff --git a/src/java.base/share/classes/sun/nio/ch/NativeThreadSet.java b/src/java.base/share/classes/sun/nio/ch/NativeThreadSet.java index 079291572a8..c5423141789 100644 --- a/src/java.base/share/classes/sun/nio/ch/NativeThreadSet.java +++ b/src/java.base/share/classes/sun/nio/ch/NativeThreadSet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,9 +31,9 @@ class NativeThreadSet { private static final int OTHER_THREAD_INDEX = -99; private final int initialCapacity; - private long[] threads; // array of thread handles, created lazily - private int used; // number of thread handles in threads array - private int otherThreads; // count of threads without a native thread handle + private Thread[] threads; // array of platform threads, created lazily + private int used; // number of elements in threads array + private int otherThreads; // additional threads that can't be signalled private boolean waitingToEmpty; NativeThreadSet(int n) { @@ -45,28 +45,28 @@ class NativeThreadSet { * it can efficiently be removed later. */ int add() { - long th = NativeThread.current(); synchronized (this) { - if (!NativeThread.isNativeThread(th)) { + final Thread t = NativeThread.threadToSignal(); + if (t == null || t.isVirtual()) { otherThreads++; return OTHER_THREAD_INDEX; } - // add native thread handle to array, creating or growing array if needed + // add platform threads to array, creating or growing array if needed int start = 0; if (threads == null) { - threads = new long[initialCapacity]; + threads = new Thread[initialCapacity]; } else if (used >= threads.length) { int on = threads.length; int nn = on * 2; - long[] nthreads = new long[nn]; + Thread[] nthreads = new Thread[nn]; System.arraycopy(threads, 0, nthreads, 0, on); threads = nthreads; start = on; } for (int i = start; i < threads.length; i++) { - if (threads[i] == 0) { - threads[i] = th; + if (threads[i] == null) { + threads[i] = t; used++; return i; } @@ -81,8 +81,7 @@ class NativeThreadSet { void remove(int i) { synchronized (this) { if (i >= 0) { - assert threads[i] == NativeThread.current(); - threads[i] = 0; + threads[i] = null; used--; } else if (i == OTHER_THREAD_INDEX) { otherThreads--; @@ -104,9 +103,9 @@ class NativeThreadSet { while (used > 0 || otherThreads > 0) { int u = used, i = 0; while (u > 0 && i < threads.length) { - long th = threads[i]; - if (th != 0) { - NativeThread.signal(th); + Thread t = threads[i]; + if (t != null) { + NativeThread.signal(t); u--; } i++; diff --git a/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java b/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java index 01f894be227..58b3bc7aaba 100644 --- a/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java @@ -103,8 +103,8 @@ public final class NioSocketImpl extends SocketImpl implements PlatformSocketImp private volatile boolean nonBlocking; // used by connect/read/write/accept, protected by stateLock - private long readerThread; - private long writerThread; + private Thread readerThread; + private Thread writerThread; // used when SO_REUSEADDR is emulated, protected by stateLock private boolean isReuseAddress; @@ -218,7 +218,7 @@ public final class NioSocketImpl extends SocketImpl implements PlatformSocketImp private FileDescriptor beginRead() throws SocketException { synchronized (stateLock) { ensureOpenAndConnected(); - readerThread = NativeThread.current(); + readerThread = NativeThread.threadToSignal(); return fd; } } @@ -229,7 +229,7 @@ public final class NioSocketImpl extends SocketImpl implements PlatformSocketImp */ private void endRead(boolean completed) throws SocketException { synchronized (stateLock) { - readerThread = 0; + readerThread = null; int state = this.state; if (state == ST_CLOSING) tryFinishClose(); @@ -370,7 +370,7 @@ public final class NioSocketImpl extends SocketImpl implements PlatformSocketImp private FileDescriptor beginWrite() throws SocketException { synchronized (stateLock) { ensureOpenAndConnected(); - writerThread = NativeThread.current(); + writerThread = NativeThread.threadToSignal(); return fd; } } @@ -381,7 +381,7 @@ public final class NioSocketImpl extends SocketImpl implements PlatformSocketImp */ private void endWrite(boolean completed) throws SocketException { synchronized (stateLock) { - writerThread = 0; + writerThread = null; int state = this.state; if (state == ST_CLOSING) tryFinishClose(); @@ -511,7 +511,7 @@ public final class NioSocketImpl extends SocketImpl implements PlatformSocketImp this.address = address; this.port = port; - readerThread = NativeThread.current(); + readerThread = NativeThread.threadToSignal(); return fd; } } @@ -522,7 +522,7 @@ public final class NioSocketImpl extends SocketImpl implements PlatformSocketImp */ private void endConnect(FileDescriptor fd, boolean completed) throws IOException { synchronized (stateLock) { - readerThread = 0; + readerThread = null; int state = this.state; if (state == ST_CLOSING) tryFinishClose(); @@ -666,7 +666,7 @@ public final class NioSocketImpl extends SocketImpl implements PlatformSocketImp ensureOpen(); if (localport == 0) throw new SocketException("Not bound"); - readerThread = NativeThread.current(); + readerThread = NativeThread.threadToSignal(); return fd; } } @@ -678,7 +678,7 @@ public final class NioSocketImpl extends SocketImpl implements PlatformSocketImp private void endAccept(boolean completed) throws SocketException { synchronized (stateLock) { int state = this.state; - readerThread = 0; + readerThread = null; if (state == ST_CLOSING) tryFinishClose(); if (!completed && state >= ST_CLOSING) @@ -844,7 +844,7 @@ public final class NioSocketImpl extends SocketImpl implements PlatformSocketImp */ private boolean tryClose() throws IOException { assert Thread.holdsLock(stateLock) && state == ST_CLOSING; - if (readerThread == 0 && writerThread == 0) { + if (readerThread == null && writerThread == null) { try { cleaner.clean(); } catch (UncheckedIOException ioe) { @@ -1143,8 +1143,8 @@ public final class NioSocketImpl extends SocketImpl implements PlatformSocketImp ensureOpenAndConnected(); if (!isInputClosed) { Net.shutdown(fd, Net.SHUT_RD); - if (NativeThread.isVirtualThread(readerThread)) { - Poller.stopPoll(fdVal(fd), Net.POLLIN); + if (readerThread != null && readerThread.isVirtual()) { + Poller.stopPoll(readerThread); } isInputClosed = true; } @@ -1157,8 +1157,8 @@ public final class NioSocketImpl extends SocketImpl implements PlatformSocketImp ensureOpenAndConnected(); if (!isOutputClosed) { Net.shutdown(fd, Net.SHUT_WR); - if (NativeThread.isVirtualThread(writerThread)) { - Poller.stopPoll(fdVal(fd), Net.POLLOUT); + if (writerThread != null && writerThread.isVirtual()) { + Poller.stopPoll(writerThread); } isOutputClosed = true; } diff --git a/src/java.base/share/classes/sun/nio/ch/Poller.java b/src/java.base/share/classes/sun/nio/ch/Poller.java index 4a2cb4d8fdf..9360bcc8327 100644 --- a/src/java.base/share/classes/sun/nio/ch/Poller.java +++ b/src/java.base/share/classes/sun/nio/ch/Poller.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,61 +25,107 @@ package sun.nio.ch; import java.io.IOException; +import java.io.UncheckedIOException; +import java.lang.ref.Reference; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; import java.util.concurrent.locks.LockSupport; import java.util.function.BooleanSupplier; +import jdk.internal.access.JavaLangAccess; +import jdk.internal.access.SharedSecrets; import jdk.internal.misc.InnocuousThread; +import jdk.internal.misc.TerminatingThreadLocal; +import jdk.internal.vm.Continuation; +import jdk.internal.vm.ContinuationSupport; import jdk.internal.vm.annotation.Stable; /** - * Polls file descriptors. Virtual threads invoke the poll method to park - * until a given file descriptor is ready for I/O. + * I/O poller to allow virtual threads park until a file descriptor is ready for I/O. */ public abstract class Poller { - private static final Pollers POLLERS; - static { - try { - var pollers = new Pollers(); - pollers.start(); - POLLERS = pollers; - } catch (IOException ioe) { - throw new ExceptionInInitializerError(ioe); - } - } + private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); - // the poller or sub-poller thread + // the poller group for the I/O pollers and poller threads + private static final PollerGroup POLLER_GROUP = createPollerGroup(); + + // the poller or sub-poller thread (used for observability only) private @Stable Thread owner; // maps file descriptors to parked Thread private final Map map = new ConcurrentHashMap<>(); + // shutdown (if supported by poller group) + private volatile boolean shutdown; + /** * Poller mode. */ enum Mode { /** - * ReadPoller and WritePoller are dedicated platform threads that block waiting - * for events and unpark virtual threads when file descriptors are ready for I/O. + * Read and write pollers are platform threads that block waiting for events and + * unpark virtual threads when file descriptors are ready for I/O. */ SYSTEM_THREADS, /** - * ReadPoller and WritePoller threads are virtual threads that poll for events, - * yielding between polls and unparking virtual threads when file descriptors are + * Read and write pollers are virtual threads that poll for events, yielding + * between polls and unparking virtual threads when file descriptors are * ready for I/O. If there are no events then the poller threads park until there * are I/O events to poll. This mode helps to integrate polling with virtual * thread scheduling. The approach is similar to the default scheme in "User-level * Threading: Have Your Cake and Eat It Too" by Karsten and Barghi 2020 * (https://dl.acm.org/doi/10.1145/3379483). */ - VTHREAD_POLLERS + VTHREAD_POLLERS, + + /** + * Read pollers are per-carrier virtual threads that poll for events, yielding + * between polls and unparking virtual threads when file descriptors are ready + * for I/O. If there are no events then the poller threads park until there + * are I/O events to poll. The write poller is a system-wide platform thread. + */ + POLLER_PER_CARRIER + } + + /** + * Create and return the PollerGroup. + */ + private static PollerGroup createPollerGroup() { + try { + PollerProvider provider; + if (System.getProperty("jdk.pollerMode") instanceof String s) { + Mode mode = switch (s) { + case "1" -> Mode.SYSTEM_THREADS; + case "2" -> Mode.VTHREAD_POLLERS; + case "3" -> Mode.POLLER_PER_CARRIER; + default -> { + throw new RuntimeException(s + " is not a valid polling mode"); + } + }; + provider = PollerProvider.createProvider(mode); + } else { + provider = PollerProvider.createProvider(); + } + + int readPollers = pollerCount("jdk.readPollers", provider.defaultReadPollers()); + int writePollers = pollerCount("jdk.writePollers", provider.defaultWritePollers()); + PollerGroup group = switch (provider.pollerMode()) { + case SYSTEM_THREADS -> new SystemThreadsPollerGroup(provider, readPollers, writePollers); + case VTHREAD_POLLERS -> new VThreadsPollerGroup(provider, readPollers, writePollers); + case POLLER_PER_CARRIER -> new PollerPerCarrierPollerGroup(provider, writePollers); + }; + group.start(); + return group; + } catch (IOException ioe) { + throw new UncheckedIOException(ioe); + } } /** @@ -89,9 +135,34 @@ public abstract class Poller { } /** - * Returns the poller's file descriptor, used when the read and write poller threads - * are virtual threads. - * + * Closes the poller and release resources. This method can only be used to cleanup + * when creating a poller group fails. + */ + abstract void close() throws IOException; + + /** + * Sets the poller's thread owner. + */ + private void setOwner() { + owner = Thread.currentThread(); + } + + /** + * Returns true if this poller is marked for shutdown. + */ + boolean isShutdown() { + return shutdown; + } + + /** + * Marks this poller for shutdown. + */ + private void setShutdown() { + shutdown = true; + } + + /** + * Returns the poller's file descriptor to use when polling with the master poller. * @throws UnsupportedOperationException if not supported */ int fdVal() { @@ -99,16 +170,18 @@ public abstract class Poller { } /** - * Register the file descriptor. The registration is "one shot", meaning it should - * be polled at most once. + * Register the file descriptor with the I/O event management facility so that it is + * polled when the file descriptor is ready for I/O. The registration is "one shot", + * meaning it should be polled at most once. */ - abstract void implRegister(int fdVal) throws IOException; + abstract void implStartPoll(int fdVal) throws IOException; /** - * Deregister the file descriptor. + * Deregister a file descriptor from the I/O event management facility. This may be + * a no-op in some implementations when the file descriptor has already been polled. * @param polled true if the file descriptor has already been polled */ - abstract void implDeregister(int fdVal, boolean polled); + abstract void implStopPoll(int fdVal, boolean polled) throws IOException; /** * Poll for events. The {@link #polled(int)} method is invoked for each @@ -116,15 +189,26 @@ public abstract class Poller { * * @param timeout if positive then block for up to {@code timeout} milliseconds, * if zero then don't block, if -1 then block indefinitely - * @return the number of file descriptors polled + * @return >0 if file descriptors are polled, 0 if no file descriptor polled */ abstract int poll(int timeout) throws IOException; + /** + * Wakeup the poller thread if blocked in poll so it can shutdown. + * @throws UnsupportedOperationException if not supported + */ + void wakeupPoller() throws IOException { + throw new UnsupportedOperationException(); + } + /** * Callback by the poll method when a file descriptor is polled. */ final void polled(int fdVal) { - wakeup(fdVal); + Thread t = map.remove(fdVal); + if (t != null) { + LockSupport.unpark(t); + } } /** @@ -132,19 +216,10 @@ public abstract class Poller { * @param fdVal the file descriptor * @param event POLLIN or POLLOUT * @param nanos the waiting time or 0 to wait indefinitely - * @param supplier supplies a boolean to indicate if the enclosing object is open + * @param isOpen supplies a boolean to indicate if the enclosing object is open */ - static void poll(int fdVal, int event, long nanos, BooleanSupplier supplier) - throws IOException - { - assert nanos >= 0L; - if (event == Net.POLLIN) { - POLLERS.readPoller(fdVal).poll(fdVal, nanos, supplier); - } else if (event == Net.POLLOUT) { - POLLERS.writePoller(fdVal).poll(fdVal, nanos, supplier); - } else { - assert false; - } + public static void poll(int fdVal, int event, long nanos, BooleanSupplier isOpen) throws IOException { + POLLER_GROUP.poll(fdVal, event, nanos, isOpen); } /** @@ -152,45 +227,24 @@ public abstract class Poller { * @param fdVal the Selector's file descriptor * @param nanos the waiting time or 0 to wait indefinitely */ - static void pollSelector(int fdVal, long nanos) throws IOException { - assert nanos >= 0L; - Poller poller = POLLERS.masterPoller(); - if (poller == null) { - poller = POLLERS.readPoller(fdVal); - } - poller.poll(fdVal, nanos, () -> true); + public static void pollSelector(int fdVal, long nanos) throws IOException { + POLLER_GROUP.pollSelector(fdVal, nanos); } /** - * If there is a thread polling the given file descriptor for the given event then - * the thread is unparked. + * Unpark the given thread so that it stops polling. */ - static void stopPoll(int fdVal, int event) { - if (event == Net.POLLIN) { - POLLERS.readPoller(fdVal).wakeup(fdVal); - } else if (event == Net.POLLOUT) { - POLLERS.writePoller(fdVal).wakeup(fdVal); - } else { - throw new IllegalArgumentException(); - } - } - - /** - * If there are any threads polling the given file descriptor then they are unparked. - */ - static void stopPoll(int fdVal) { - stopPoll(fdVal, Net.POLLIN); - stopPoll(fdVal, Net.POLLOUT); + public static void stopPoll(Thread thread) { + LockSupport.unpark(thread); } /** * Parks the current thread until a file descriptor is ready. */ - private void poll(int fdVal, long nanos, BooleanSupplier supplier) throws IOException { - register(fdVal); + private void poll(int fdVal, long nanos, BooleanSupplier isOpen) throws IOException { + startPoll(fdVal); try { - boolean isOpen = supplier.getAsBoolean(); - if (isOpen) { + if (isOpen.getAsBoolean() && !isShutdown()) { if (nanos > 0) { LockSupport.parkNanos(nanos); } else { @@ -198,42 +252,38 @@ public abstract class Poller { } } } finally { - deregister(fdVal); + stopPoll(fdVal); } } /** - * Registers the file descriptor to be polled at most once when the file descriptor - * is ready for I/O. + * Register a file descriptor with the I/O event management facility so that it is + * polled when the file descriptor is ready for I/O. */ - private void register(int fdVal) throws IOException { + private void startPoll(int fdVal) throws IOException { Thread previous = map.put(fdVal, Thread.currentThread()); assert previous == null; try { - implRegister(fdVal); + implStartPoll(fdVal); } catch (Throwable t) { map.remove(fdVal); throw t; + } finally { + Reference.reachabilityFence(this); } } /** - * Deregister the file descriptor so that the file descriptor is not polled. + * Deregister a file descriptor from the I/O event management facility. */ - private void deregister(int fdVal) { + private void stopPoll(int fdVal) throws IOException { Thread previous = map.remove(fdVal); boolean polled = (previous == null); assert polled || previous == Thread.currentThread(); - implDeregister(fdVal, polled); - } - - /** - * Unparks any thread that is polling the given file descriptor. - */ - private void wakeup(int fdVal) { - Thread t = map.remove(fdVal); - if (t != null) { - LockSupport.unpark(t); + try { + implStopPoll(fdVal, polled); + } finally { + Reference.reachabilityFence(this); } } @@ -242,9 +292,9 @@ public abstract class Poller { * descriptor that is polled. */ private void pollerLoop() { - owner = Thread.currentThread(); + setOwner(); try { - for (;;) { + while (!isShutdown()) { poll(-1); } } catch (Exception e) { @@ -263,10 +313,10 @@ public abstract class Poller { */ private void subPollerLoop(Poller masterPoller) { assert Thread.currentThread().isVirtual(); - owner = Thread.currentThread(); + setOwner(); try { int polled = 0; - for (;;) { + while (!isShutdown()) { if (polled == 0) { masterPoller.poll(fdVal(), 0, () -> true); // park } else { @@ -280,194 +330,463 @@ public abstract class Poller { } /** - * Returns the number I/O operations currently registered with this poller. + * Unparks all threads waiting on a file descriptor registered with this poller. */ - public int registered() { - return map.size(); + private void wakeupAll() { + map.values().forEach(LockSupport::unpark); } @Override public String toString() { return String.format("%s [registered = %d, owner = %s]", - Objects.toIdentityString(this), registered(), owner); + Objects.toIdentityString(this), map.size(), owner); } /** - * The Pollers used for read and write events. + * A group of poller threads that support virtual threads polling file descriptors. */ - private static class Pollers { + private static abstract class PollerGroup { private final PollerProvider provider; - private final Poller.Mode pollerMode; - private final Poller masterPoller; - private final Poller[] readPollers; - private final Poller[] writePollers; - - // used by start method to executor is kept alive - private Executor executor; - - /** - * Creates the Poller instances based on configuration. - */ - Pollers() throws IOException { - PollerProvider provider = PollerProvider.provider(); - Poller.Mode mode; - String s = System.getProperty("jdk.pollerMode"); - if (s != null) { - if (s.equalsIgnoreCase(Mode.SYSTEM_THREADS.name()) || s.equals("1")) { - mode = Mode.SYSTEM_THREADS; - } else if (s.equalsIgnoreCase(Mode.VTHREAD_POLLERS.name()) || s.equals("2")) { - mode = Mode.VTHREAD_POLLERS; - } else { - throw new RuntimeException("Can't parse '" + s + "' as polling mode"); - } - } else { - mode = provider.defaultPollerMode(); - } - - // vthread poller mode needs a master poller - Poller masterPoller = (mode == Mode.VTHREAD_POLLERS) - ? provider.readPoller(false) - : null; - - // read pollers (or sub-pollers) - int readPollerCount = pollerCount("jdk.readPollers", provider.defaultReadPollers(mode)); - Poller[] readPollers = new Poller[readPollerCount]; - for (int i = 0; i < readPollerCount; i++) { - readPollers[i] = provider.readPoller(mode == Mode.VTHREAD_POLLERS); - } - - // write pollers (or sub-pollers) - int writePollerCount = pollerCount("jdk.writePollers", provider.defaultWritePollers(mode)); - Poller[] writePollers = new Poller[writePollerCount]; - for (int i = 0; i < writePollerCount; i++) { - writePollers[i] = provider.writePoller(mode == Mode.VTHREAD_POLLERS); - } + PollerGroup(PollerProvider provider) { this.provider = provider; - this.pollerMode = mode; - this.masterPoller = masterPoller; - this.readPollers = readPollers; - this.writePollers = writePollers; + } + + final PollerProvider provider() { + return provider; } /** - * Starts the Poller threads. + * Starts the poller group and any system-wide poller threads. */ - void start() { - if (pollerMode == Mode.VTHREAD_POLLERS) { - startPlatformThread("MasterPoller", masterPoller::pollerLoop); - ThreadFactory factory = Thread.ofVirtual() - .inheritInheritableThreadLocals(false) - .name("SubPoller-", 0) - .uncaughtExceptionHandler((t, e) -> e.printStackTrace()) - .factory(); - executor = Executors.newThreadPerTaskExecutor(factory); - Arrays.stream(readPollers).forEach(p -> { - executor.execute(() -> p.subPollerLoop(masterPoller)); - }); - Arrays.stream(writePollers).forEach(p -> { - executor.execute(() -> p.subPollerLoop(masterPoller)); - }); - } else { - Arrays.stream(readPollers).forEach(p -> { - startPlatformThread("Read-Poller", p::pollerLoop); - }); - Arrays.stream(writePollers).forEach(p -> { - startPlatformThread("Write-Poller", p::pollerLoop); - }); - } - } + abstract void start(); /** - * Returns the master poller, or null if there is no master poller. + * Parks the current thread until a file descriptor is ready for the given op. */ - Poller masterPoller() { - return masterPoller; - } + abstract void poll(int fdVal, int event, long nanos, BooleanSupplier isOpen) throws IOException; /** - * Returns the read poller for the given file descriptor. + * Parks the current thread until a Selector's file descriptor is ready. */ - Poller readPoller(int fdVal) { - int index = provider.fdValToIndex(fdVal, readPollers.length); - return readPollers[index]; - } - - /** - * Returns the write poller for the given file descriptor. - */ - Poller writePoller(int fdVal) { - int index = provider.fdValToIndex(fdVal, writePollers.length); - return writePollers[index]; - } - - /** - * Return the list of read pollers. - */ - List readPollers() { - return List.of(readPollers); - } - - /** - * Return the list of write pollers. - */ - List writePollers() { - return List.of(writePollers); - } - - - /** - * Reads the given property name to get the poller count. If the property is - * set then the value must be a power of 2. Returns 1 if the property is not - * set. - * @throws IllegalArgumentException if the property is set to a value that - * is not a power of 2. - */ - private static int pollerCount(String propName, int defaultCount) { - String s = System.getProperty(propName); - int count = (s != null) ? Integer.parseInt(s) : defaultCount; - - // check power of 2 - if (count != Integer.highestOneBit(count)) { - String msg = propName + " is set to a value that is not a power of 2"; - throw new IllegalArgumentException(msg); - } - return count; + void pollSelector(int fdVal, long nanos) throws IOException { + poll(fdVal, Net.POLLIN, nanos, () -> true); } /** * Starts a platform thread to run the given task. */ - private void startPlatformThread(String name, Runnable task) { - try { - Thread thread = InnocuousThread.newSystemThread(name, task); - thread.setDaemon(true); - thread.setUncaughtExceptionHandler((t, e) -> e.printStackTrace()); - thread.start(); - } catch (Exception e) { - throw new InternalError(e); + protected final void startPlatformThread(String name, Runnable task) { + Thread thread = InnocuousThread.newSystemThread(name, task); + thread.setDaemon(true); + thread.setUncaughtExceptionHandler((t, e) -> e.printStackTrace()); + thread.start(); + } + + /** + * Return the master poller, or null if no master poller. + */ + abstract Poller masterPoller(); + + /** + * Return the read pollers. + */ + abstract List readPollers(); + + /** + * Return the write pollers. + */ + abstract List writePollers(); + + /** + * Close the given pollers. + */ + static void closeAll(Poller... pollers) { + for (Poller poller : pollers) { + if (poller != null) { + try { + poller.close(); + } catch (IOException _) { } + } } } } + /** + * SYSTEM_THREADS poller group. The read and write pollers are system-wide platform threads. + */ + private static class SystemThreadsPollerGroup extends PollerGroup { + // system-wide read and write pollers + private final Poller[] readPollers; + private final Poller[] writePollers; + + SystemThreadsPollerGroup(PollerProvider provider, + int readPollerCount, + int writePollerCount) throws IOException { + super(provider); + Poller[] readPollers = new Poller[readPollerCount]; + Poller[] writePollers = new Poller[writePollerCount]; + try { + for (int i = 0; i < readPollerCount; i++) { + readPollers[i] = provider.readPoller(false); + } + for (int i = 0; i < writePollerCount; i++) { + writePollers[i] = provider.writePoller(false); + } + } catch (Throwable e) { + closeAll(readPollers); + closeAll(writePollers); + throw e; + } + + this.readPollers = readPollers; + this.writePollers = writePollers; + } + + @Override + void start() { + Arrays.stream(readPollers).forEach(p -> { + startPlatformThread("Read-Poller", p::pollerLoop); + }); + Arrays.stream(writePollers).forEach(p -> { + startPlatformThread("Write-Poller", p::pollerLoop); + }); + } + + private Poller readPoller(int fdVal) { + int index = provider().fdValToIndex(fdVal, readPollers.length); + return readPollers[index]; + } + + private Poller writePoller(int fdVal) { + int index = provider().fdValToIndex(fdVal, writePollers.length); + return writePollers[index]; + } + + @Override + void poll(int fdVal, int event, long nanos, BooleanSupplier isOpen) throws IOException { + Poller poller = (event == Net.POLLIN) + ? readPoller(fdVal) + : writePoller(fdVal); + poller.poll(fdVal, nanos, isOpen); + } + + @Override + Poller masterPoller() { + return null; + } + + @Override + List readPollers() { + return List.of(readPollers); + } + + @Override + List writePollers() { + return List.of(writePollers); + } + } + + /** + * VTHREAD_POLLERS poller group. The read and write pollers are virtual threads. + * When read and write pollers need to block then they register with a system-wide + * "master poller" that runs in a dedicated platform thread. + */ + private static class VThreadsPollerGroup extends PollerGroup { + private final Poller masterPoller; + private final Poller[] readPollers; + private final Poller[] writePollers; + + // keep virtual thread pollers alive + private final Executor executor; + + VThreadsPollerGroup(PollerProvider provider, + int readPollerCount, + int writePollerCount) throws IOException { + super(provider); + Poller masterPoller = provider.readPoller(false); + Poller[] readPollers = new Poller[readPollerCount]; + Poller[] writePollers = new Poller[writePollerCount]; + + try { + for (int i = 0; i < readPollerCount; i++) { + readPollers[i] = provider.readPoller(true); + } + for (int i = 0; i < writePollerCount; i++) { + writePollers[i] = provider.writePoller(true); + } + } catch (Throwable e) { + masterPoller.close(); + closeAll(readPollers); + closeAll(writePollers); + throw e; + } + + this.masterPoller = masterPoller; + this.readPollers = readPollers; + this.writePollers = writePollers; + + ThreadFactory factory = Thread.ofVirtual() + .inheritInheritableThreadLocals(false) + .name("SubPoller-", 0) + .uncaughtExceptionHandler((_, e) -> e.printStackTrace()) + .factory(); + this.executor = Executors.newThreadPerTaskExecutor(factory); + } + + @Override + void start() { + startPlatformThread("Master-Poller", masterPoller::pollerLoop); + Arrays.stream(readPollers).forEach(p -> { + executor.execute(() -> p.subPollerLoop(masterPoller)); + }); + Arrays.stream(writePollers).forEach(p -> { + executor.execute(() -> p.subPollerLoop(masterPoller)); + }); + } + + private Poller readPoller(int fdVal) { + int index = provider().fdValToIndex(fdVal, readPollers.length); + return readPollers[index]; + } + + private Poller writePoller(int fdVal) { + int index = provider().fdValToIndex(fdVal, writePollers.length); + return writePollers[index]; + } + + @Override + void poll(int fdVal, int event, long nanos, BooleanSupplier isOpen) throws IOException { + Poller poller = (event == Net.POLLIN) + ? readPoller(fdVal) + : writePoller(fdVal); + poller.poll(fdVal, nanos, isOpen); + } + + @Override + void pollSelector(int fdVal, long nanos) throws IOException { + masterPoller.poll(fdVal, nanos, () -> true); + } + + @Override + Poller masterPoller() { + return masterPoller; + } + + @Override + List readPollers() { + return List.of(readPollers); + } + + @Override + List writePollers() { + return List.of(writePollers); + } + } + + /** + * POLLER_PER_CARRIER poller group. The read poller is a per-carrier virtual thread. + * When a virtual thread polls a file descriptor for POLLIN, then it will use (almost + * always, not guaranteed) the read poller for its carrier. When a read poller needs + * to block then it registers with a system-wide "master poller" that runs in a + * dedicated platform thread. The read poller terminates if the carrier terminates. + * The write pollers are system-wide platform threads (usually one). + */ + private static class PollerPerCarrierPollerGroup extends PollerGroup { + private record CarrierPoller(PollerPerCarrierPollerGroup group, Poller readPoller) { } + private static final TerminatingThreadLocal CARRIER_POLLER = + new TerminatingThreadLocal<>() { + @Override + protected void threadTerminated(CarrierPoller carrierPoller) { + Poller readPoller = carrierPoller.readPoller(); + carrierPoller.group().carrierTerminated(readPoller); + } + }; + + private final Poller masterPoller; + private final Set readPollers; + private final Poller[] writePollers; + + /** + * Create a PollerPerCarrierPollerGroup with the given number of write pollers. + */ + PollerPerCarrierPollerGroup(PollerProvider provider, + int writePollerCount) throws IOException { + super(provider); + Poller masterPoller = provider.readPoller(false); + Poller[] writePollers = new Poller[writePollerCount]; + try { + for (int i = 0; i < writePollerCount; i++) { + writePollers[i] = provider.writePoller(false); + } + } catch (Throwable e) { + masterPoller.close(); + closeAll(writePollers); + throw e; + } + this.masterPoller = masterPoller; + this.readPollers = ConcurrentHashMap.newKeySet();; + this.writePollers = writePollers; + } + + @Override + void start() { + startPlatformThread("Master-Poller", masterPoller::pollerLoop); + Arrays.stream(writePollers).forEach(p -> { + startPlatformThread("Write-Poller", p::pollerLoop); + }); + } + + private Poller writePoller(int fdVal) { + int index = provider().fdValToIndex(fdVal, writePollers.length); + return writePollers[index]; + } + + /** + * Starts a read sub-poller in a virtual thread. + */ + private Poller startReadPoller() throws IOException { + assert Thread.currentThread().isVirtual() && ContinuationSupport.isSupported(); + + // create read sub-poller + Poller readPoller = provider().readPoller(true); + readPollers.add(readPoller); + + // start virtual thread to execute sub-polling loop + Thread carrier = JLA.currentCarrierThread(); + Thread.ofVirtual() + .inheritInheritableThreadLocals(false) + .name(carrier.getName() + "-Read-Poller") + .uncaughtExceptionHandler((_, e) -> e.printStackTrace()) + .start(() -> subPollerLoop(readPoller)); + return readPoller; + } + + /** + * Returns the read poller for the current carrier, starting it if required. + */ + private Poller readPoller() throws IOException { + assert Thread.currentThread().isVirtual() && ContinuationSupport.isSupported(); + Continuation.pin(); + try { + CarrierPoller carrierPoller = CARRIER_POLLER.get(); + if (carrierPoller != null) { + return carrierPoller.readPoller(); + } else { + // first poll on this carrier will start poller + Poller readPoller = startReadPoller(); + CARRIER_POLLER.set(new CarrierPoller(this, readPoller)); + return readPoller; + } + } finally { + Continuation.unpin(); + } + } + + @Override + void poll(int fdVal, int event, long nanos, BooleanSupplier isOpen) throws IOException { + // for POLLIN, get the read poller for this carrier + if (event == Net.POLLIN + && Thread.currentThread().isVirtual() + && ContinuationSupport.isSupported()) { + readPoller().poll(fdVal, nanos, isOpen); + return; + } + + // -XX:-VMContinuations or POLLIN from platform thread does master poller + if (event == Net.POLLIN) { + masterPoller.poll(fdVal, nanos, isOpen); + } else { + writePoller(fdVal).poll(fdVal, nanos, isOpen); + } + } + + @Override + void pollSelector(int fdVal, long nanos) throws IOException { + masterPoller.poll(fdVal, nanos, () -> true); + } + + /** + * Sub-poller polling loop. + */ + private void subPollerLoop(Poller readPoller) { + try { + readPoller.subPollerLoop(masterPoller); + } finally { + // wakeup all threads waiting on file descriptors registered with the + // read poller, these I/O operation will migrate to another carrier. + readPoller.wakeupAll(); + + // remove from serviceability view + readPollers.remove(readPoller); + } + } + + /** + * Invoked by the carrier thread before it terminates. + */ + private void carrierTerminated(Poller readPoller) { + readPoller.setShutdown(); + try { + readPoller.wakeupPoller(); + } catch (Throwable e) { + e.printStackTrace(); + } + } + + @Override + Poller masterPoller() { + return masterPoller; + } + + @Override + List readPollers() { + return readPollers.stream().toList(); + } + + @Override + List writePollers() { + return List.of(writePollers); + } + } + + /** + * Reads the given property name to get the poller count. If the property is + * set then the value must be a power of 2. Returns 1 if the property is not + * set. + * @throws IllegalArgumentException if the property is set to a value that + * is not a power of 2. + */ + private static int pollerCount(String propName, int defaultCount) { + String s = System.getProperty(propName); + int count = (s != null) ? Integer.parseInt(s) : defaultCount; + + // check power of 2 + if (count != Integer.highestOneBit(count)) { + String msg = propName + " is set to a value that is not a power of 2"; + throw new IllegalArgumentException(msg); + } + return count; + } + /** * Return the master poller or null if there is no master poller. */ public static Poller masterPoller() { - return POLLERS.masterPoller(); + return POLLER_GROUP.masterPoller(); } /** * Return the list of read pollers. */ public static List readPollers() { - return POLLERS.readPollers(); + return POLLER_GROUP.readPollers(); } /** * Return the list of write pollers. */ public static List writePollers() { - return POLLERS.writePollers(); + return POLLER_GROUP.writePollers(); } } diff --git a/src/java.base/share/classes/sun/nio/ch/PollerProvider.java b/src/java.base/share/classes/sun/nio/ch/PollerProvider.java index b10ec309265..7d19b72d2fc 100644 --- a/src/java.base/share/classes/sun/nio/ch/PollerProvider.java +++ b/src/java.base/share/classes/sun/nio/ch/PollerProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,38 +30,43 @@ import java.io.IOException; * Provider class for Poller implementations. */ abstract class PollerProvider { - private static final PollerProvider INSTANCE = new DefaultPollerProvider(); + private final Poller.Mode mode; - PollerProvider() { } + PollerProvider(Poller.Mode mode) { + this.mode = mode; + } - /** - * Returns the system-wide PollerProvider. - */ - static PollerProvider provider() { - return INSTANCE; + final Poller.Mode pollerMode() { + return mode; } /** - * Returns the default poller mode. - * @implSpec The default implementation uses system threads. + * Creates a PollerProvider that uses its preferred/default poller mode. */ - Poller.Mode defaultPollerMode() { - return Poller.Mode.SYSTEM_THREADS; + static PollerProvider createProvider() { + return new DefaultPollerProvider(); } /** - * Default number of read pollers for the given mode. The count must be a power of 2. + * Creates a PollerProvider that uses the given poller mode. + */ + static PollerProvider createProvider(Poller.Mode mode) { + return new DefaultPollerProvider(mode); + } + + /** + * Default number of read pollers. The count must be a power of 2. * @implSpec The default implementation returns 1. */ - int defaultReadPollers(Poller.Mode mode) { + int defaultReadPollers() { return 1; } /** - * Default number of write pollers for the given mode. The count must be a power of 2. + * Default number of write pollers. The count must be a power of 2. * @implSpec The default implementation returns 1. */ - int defaultWritePollers(Poller.Mode mode) { + int defaultWritePollers() { return 1; } @@ -74,13 +79,13 @@ abstract class PollerProvider { } /** - * Creates a Poller for read ops. + * Creates a Poller for POLLIN polling. * @param subPoller true to create a sub-poller */ abstract Poller readPoller(boolean subPoller) throws IOException; /** - * Creates a Poller for write ops. + * Creates a Poller for POLLOUT polling. * @param subPoller true to create a sub-poller */ abstract Poller writePoller(boolean subPoller) throws IOException; diff --git a/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java b/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java index e75110a76ad..98f79e6671b 100644 --- a/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java @@ -90,8 +90,8 @@ class ServerSocketChannelImpl private static final int ST_CLOSED = 2; private int state; - // ID of native thread currently blocked in this channel, for signalling - private long thread; + // Thread currently blocked in this channel, for signalling + private Thread thread; // Binding private SocketAddress localAddress; // null => unbound @@ -349,7 +349,7 @@ class ServerSocketChannelImpl if (localAddress == null) throw new NotYetBoundException(); if (blocking) - thread = NativeThread.current(); + thread = NativeThread.threadToSignal(); } } @@ -364,7 +364,7 @@ class ServerSocketChannelImpl { if (blocking) { synchronized (stateLock) { - thread = 0; + thread = null; if (state == ST_CLOSING) { tryFinishClose(); } @@ -551,7 +551,7 @@ class ServerSocketChannelImpl */ private boolean tryClose() throws IOException { assert Thread.holdsLock(stateLock) && state == ST_CLOSING; - if ((thread == 0) && !isRegistered()) { + if ((thread == null) && !isRegistered()) { state = ST_CLOSED; nd.close(fd); return true; @@ -583,7 +583,7 @@ class ServerSocketChannelImpl assert state < ST_CLOSING; state = ST_CLOSING; if (!tryClose()) { - nd.preClose(fd, thread, 0); + nd.preClose(fd, thread, null); } } } diff --git a/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java b/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java index 868ed3b64bc..010b1832190 100644 --- a/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java @@ -113,9 +113,9 @@ class SocketChannelImpl private static final int ST_CLOSED = 4; private volatile int state; // need stateLock to change - // IDs of native threads doing reads and writes, for signalling - private long readerThread; - private long writerThread; + // Threads doing reads and writes, for signalling + private Thread readerThread; + private Thread writerThread; // Binding private SocketAddress localAddress; @@ -368,7 +368,7 @@ class SocketChannelImpl synchronized (stateLock) { ensureOpen(); // record thread so it can be signalled if needed - readerThread = NativeThread.current(); + readerThread = NativeThread.threadToSignal(); } } } @@ -384,7 +384,7 @@ class SocketChannelImpl { if (blocking) { synchronized (stateLock) { - readerThread = 0; + readerThread = null; if (state == ST_CLOSING) { tryFinishClose(); } @@ -522,7 +522,7 @@ class SocketChannelImpl if (isOutputClosed) throw new ClosedChannelException(); // record thread so it can be signalled if needed - writerThread = NativeThread.current(); + writerThread = NativeThread.threadToSignal(); } } } @@ -538,7 +538,7 @@ class SocketChannelImpl { if (blocking) { synchronized (stateLock) { - writerThread = 0; + writerThread = null; if (state == ST_CLOSING) { tryFinishClose(); } @@ -673,7 +673,7 @@ class SocketChannelImpl ensureOpenAndConnected(); if (isOutputClosed) throw new ClosedChannelException(); - writerThread = NativeThread.current(); + writerThread = NativeThread.threadToSignal(); completed = true; } } finally { @@ -689,7 +689,7 @@ class SocketChannelImpl */ void afterTransferTo(boolean completed) throws AsynchronousCloseException { synchronized (stateLock) { - writerThread = 0; + writerThread = null; if (state == ST_CLOSING) { tryFinishClose(); } @@ -874,7 +874,7 @@ class SocketChannelImpl if (blocking) { // record thread so it can be signalled if needed - readerThread = NativeThread.current(); + readerThread = NativeThread.threadToSignal(); } } } @@ -993,7 +993,7 @@ class SocketChannelImpl throw new NoConnectionPendingException(); if (blocking) { // record thread so it can be signalled if needed - readerThread = NativeThread.current(); + readerThread = NativeThread.threadToSignal(); } } } @@ -1072,7 +1072,7 @@ class SocketChannelImpl */ private boolean tryClose() throws IOException { assert Thread.holdsLock(stateLock) && state == ST_CLOSING; - if ((readerThread == 0) && (writerThread == 0) && !isRegistered()) { + if ((readerThread == null) && (writerThread == null) && !isRegistered()) { state = ST_CLOSED; nd.close(fd); return true; @@ -1215,11 +1215,8 @@ class SocketChannelImpl throw new NotYetConnectedException(); if (!isInputClosed) { Net.shutdown(fd, Net.SHUT_RD); - long reader = readerThread; - if (NativeThread.isVirtualThread(reader)) { - Poller.stopPoll(fdVal, Net.POLLIN); - } else if (NativeThread.isNativeThread(reader)) { - NativeThread.signal(reader); + if (readerThread != null && readerThread.isVirtual()) { + Poller.stopPoll(readerThread); } isInputClosed = true; } @@ -1235,11 +1232,8 @@ class SocketChannelImpl throw new NotYetConnectedException(); if (!isOutputClosed) { Net.shutdown(fd, Net.SHUT_WR); - long writer = writerThread; - if (NativeThread.isVirtualThread(writer)) { - Poller.stopPoll(fdVal, Net.POLLOUT); - } else if (NativeThread.isNativeThread(writer)) { - NativeThread.signal(writer); + if (writerThread != null && writerThread.isVirtual()) { + Poller.stopPoll(writerThread); } isOutputClosed = true; } diff --git a/src/java.base/share/classes/sun/nio/cs/CESU_8.java b/src/java.base/share/classes/sun/nio/cs/CESU_8.java index 11f21f56139..7093e0fecb2 100644 --- a/src/java.base/share/classes/sun/nio/cs/CESU_8.java +++ b/src/java.base/share/classes/sun/nio/cs/CESU_8.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -445,7 +445,7 @@ class CESU_8 extends Unicode int dl = dst.arrayOffset() + dst.limit(); // Handle ASCII-only prefix - int n = JLA.uncheckedEncodeASCII(sa, sp, da, dp, Math.min(sl - sp, dl - dp)); + int n = JLA.encodeASCII(sa, sp, da, dp, Math.min(sl - sp, dl - dp)); sp += n; dp += n; diff --git a/src/java.base/share/classes/sun/nio/cs/DoubleByte.java b/src/java.base/share/classes/sun/nio/cs/DoubleByte.java index 2a4dbdc95ed..edad4a1f67b 100644 --- a/src/java.base/share/classes/sun/nio/cs/DoubleByte.java +++ b/src/java.base/share/classes/sun/nio/cs/DoubleByte.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -583,6 +583,16 @@ public class DoubleByte { return encodeChar(c) != UNMAPPABLE_ENCODING; } + public boolean canEncode(CharSequence cs) { + int length = cs.length(); + for (int i = 0; i < length; i++) { + if (!canEncode(cs.charAt(i))) { + return false; + } + } + return true; + } + protected Surrogate.Parser sgp() { if (sgp == null) sgp = new Surrogate.Parser(); @@ -600,7 +610,7 @@ public class DoubleByte { try { if (isASCIICompatible) { - int n = JLA.uncheckedEncodeASCII(sa, sp, da, dp, Math.min(dl - dp, sl - sp)); + int n = JLA.encodeASCII(sa, sp, da, dp, Math.min(dl - dp, sl - sp)); sp += n; dp += n; } diff --git a/src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java b/src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java index 39215bfa93d..036aaece9ab 100644 --- a/src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java +++ b/src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,6 @@ import java.util.Objects; import jdk.internal.access.JavaLangAccess; import jdk.internal.access.SharedSecrets; -import jdk.internal.util.Preconditions; import jdk.internal.vm.annotation.IntrinsicCandidate; public class ISO_8859_1 @@ -136,26 +135,50 @@ public class ISO_8859_1 return c <= '\u00FF'; } + public boolean canEncode(CharSequence cs) { + int length = cs.length(); + for (int i = 0; i < length; i++) { + if (!canEncode(cs.charAt(i))) { + return false; + } + } + return true; + } + public boolean isLegalReplacement(byte[] repl) { return true; // we accept any byte value } private final Surrogate.Parser sgp = new Surrogate.Parser(); - // Method possible replaced with a compiler intrinsic. + /** + * Encodes as many ISO-8859-1 codepoints as possible from the source + * character array into the destination byte array, assuming that + * the encoding is ISO-8859-1 compatible. + * + * @param sa the source character array + * @param sp the index of the source array to start reading from + * @param da the target byte array + * @param dp the index of the target array to start writing to + * @param len the maximum number of characters to be encoded + * @return the total number of characters successfully encoded + * @throws NullPointerException if any of the provided arrays is null + */ private static int encodeISOArray(char[] sa, int sp, byte[] da, int dp, int len) { - if (len <= 0) { + // This method should tolerate invalid arguments, matching the lenient behavior of the VM intrinsic. + // Hence, using operator expressions instead of `Preconditions`, which throw on failure. + if ((sp | dp | len) < 0 || + sp >= sa.length || // Implicit null check on `sa` + dp >= da.length) { // Implicit null check on `da` return 0; } - encodeISOArrayCheck(sa, sp, da, dp, len); - return implEncodeISOArray(sa, sp, da, dp, len); + int minLen = Math.min(len, Math.min(sa.length - sp, da.length - dp)); + return encodeISOArray0(sa, sp, da, dp, minLen); } @IntrinsicCandidate - private static int implEncodeISOArray(char[] sa, int sp, - byte[] da, int dp, int len) - { + private static int encodeISOArray0(char[] sa, int sp, byte[] da, int dp, int len) { int i = 0; for (; i < len; i++) { char c = sa[sp++]; @@ -166,17 +189,6 @@ public class ISO_8859_1 return i; } - private static void encodeISOArrayCheck(char[] sa, int sp, - byte[] da, int dp, int len) { - Objects.requireNonNull(sa); - Objects.requireNonNull(da); - Preconditions.checkIndex(sp, sa.length, Preconditions.AIOOBE_FORMATTER); - Preconditions.checkIndex(dp, da.length, Preconditions.AIOOBE_FORMATTER); - - Preconditions.checkIndex(sp + len - 1, sa.length, Preconditions.AIOOBE_FORMATTER); - Preconditions.checkIndex(dp + len - 1, da.length, Preconditions.AIOOBE_FORMATTER); - } - private CoderResult encodeArrayLoop(CharBuffer src, ByteBuffer dst) { diff --git a/src/java.base/share/classes/sun/nio/cs/SingleByte.java b/src/java.base/share/classes/sun/nio/cs/SingleByte.java index 59887b944d3..dad89b4ebd3 100644 --- a/src/java.base/share/classes/sun/nio/cs/SingleByte.java +++ b/src/java.base/share/classes/sun/nio/cs/SingleByte.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -201,6 +201,16 @@ public class SingleByte return encode(c) != UNMAPPABLE_ENCODING; } + public boolean canEncode(CharSequence cs) { + int length = cs.length(); + for (int i = 0; i < length; i++) { + if (!canEncode(cs.charAt(i))) { + return false; + } + } + return true; + } + public boolean isLegalReplacement(byte[] repl) { return ((repl.length == 1 && repl[0] == (byte)'?') || super.isLegalReplacement(repl)); @@ -217,7 +227,7 @@ public class SingleByte int len = Math.min(dl - dp, sl - sp); if (isASCIICompatible) { - int n = JLA.uncheckedEncodeASCII(sa, sp, da, dp, len); + int n = JLA.encodeASCII(sa, sp, da, dp, len); sp += n; dp += n; len -= n; diff --git a/src/java.base/share/classes/sun/nio/cs/US_ASCII.java b/src/java.base/share/classes/sun/nio/cs/US_ASCII.java index bb84ab1bd4b..dabe843c809 100644 --- a/src/java.base/share/classes/sun/nio/cs/US_ASCII.java +++ b/src/java.base/share/classes/sun/nio/cs/US_ASCII.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -139,6 +139,16 @@ public class US_ASCII return c < 0x80; } + public boolean canEncode(CharSequence cs) { + int length = cs.length(); + for (int i = 0; i < length; i++) { + if (!canEncode(cs.charAt(i))) { + return false; + } + } + return true; + } + public boolean isLegalReplacement(byte[] repl) { return (repl.length == 1 && repl[0] >= 0) || super.isLegalReplacement(repl); @@ -159,7 +169,7 @@ public class US_ASCII assert (dp <= dl); dp = (dp <= dl ? dp : dl); - int n = JLA.uncheckedEncodeASCII(sa, sp, da, dp, Math.min(sl - sp, dl - dp)); + int n = JLA.encodeASCII(sa, sp, da, dp, Math.min(sl - sp, dl - dp)); sp += n; dp += n; diff --git a/src/java.base/share/classes/sun/nio/cs/UTF_8.java b/src/java.base/share/classes/sun/nio/cs/UTF_8.java index 54e479f838a..2928ae6d509 100644 --- a/src/java.base/share/classes/sun/nio/cs/UTF_8.java +++ b/src/java.base/share/classes/sun/nio/cs/UTF_8.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -452,7 +452,7 @@ public final class UTF_8 extends Unicode { int dl = dst.arrayOffset() + dst.limit(); // Handle ASCII-only prefix - int n = JLA.uncheckedEncodeASCII(sa, sp, da, dp, Math.min(sl - sp, dl - dp)); + int n = JLA.encodeASCII(sa, sp, da, dp, Math.min(sl - sp, dl - dp)); sp += n; dp += n; diff --git a/src/java.base/share/classes/sun/security/pkcs/NamedPKCS8Key.java b/src/java.base/share/classes/sun/security/pkcs/NamedPKCS8Key.java index a748433da87..e1beb8b6b9b 100644 --- a/src/java.base/share/classes/sun/security/pkcs/NamedPKCS8Key.java +++ b/src/java.base/share/classes/sun/security/pkcs/NamedPKCS8Key.java @@ -25,11 +25,8 @@ package sun.security.pkcs; -import sun.security.util.DerInputStream; -import sun.security.util.DerValue; import sun.security.x509.AlgorithmId; -import javax.security.auth.DestroyFailedException; import java.io.IOException; import java.io.InvalidObjectException; import java.io.ObjectInputStream; @@ -39,6 +36,7 @@ import java.security.NoSuchAlgorithmException; import java.security.ProviderException; import java.security.spec.NamedParameterSpec; import java.util.Arrays; +import java.util.Objects; /// Represents a private key from an algorithm family that is specialized /// with a named parameter set. @@ -50,6 +48,28 @@ import java.util.Arrays; /// identifier in the PKCS #8 encoding of the key is always a single OID derived /// from the parameter set name. /// +/// Besides the existing [PKCS8Key#privKeyMaterial] field, this class optionally +/// supports an expanded format stored in [#expanded]. While `privKeyMaterial` +/// always represents the format used for encoding, `expanded` is always used +/// in computations. The expanded format must be self-sufficient for +/// cryptographic computations without requiring the encoding format. +/// +/// 1. If only `privKeyMaterial` is present, it's also the expanded format. +/// 2. If both `privKeyMaterial` and `expanded` are available, `privKeyMaterial` +/// is the encoding format, and `expanded` is the expanded format. +/// +/// If the two formats are the same, only `privKeyMaterial` is included, and +/// `expanded` must be `null`. Some implementations might be tempted to put the +/// same value into `privKeyMaterial` and `expanded`. However, problems can +/// arise if they happen to be the same object. To avoid ambiguity, always set +/// `expanded` to `null`. +/// +/// If the `expanded` field is required by the algorithm, it is either +/// [calculated from the PKCS #8 encoding][#NamedPKCS8Key(String, byte\[\], Expander)], +/// or [provided directly][#internalCreate(String, String, byte\[\], byte\[\])]. +/// In the latter case, the caller must ensure the consistency of the `encoded` +/// and `expanded` arguments. For example, seed and expanded key must match. +/// /// @see sun.security.provider.NamedKeyPairGenerator public final class NamedPKCS8Key extends PKCS8Key { @Serial @@ -57,42 +77,64 @@ public final class NamedPKCS8Key extends PKCS8Key { private final String fname; private final transient NamedParameterSpec paramSpec; - private final byte[] rawBytes; + private final transient byte[] expanded; private transient boolean destroyed = false; - /// Ctor from family name, parameter set name, raw key bytes. - /// Key bytes won't be cloned, caller must relinquish ownership - public NamedPKCS8Key(String fname, String pname, byte[] rawBytes) { + /// Creates a `NamedPKCS8Key` from raw components. + /// + /// @param fname family name + /// @param pname parameter set name + /// @param encoded raw key bytes, not null + /// @param expanded expanded key format, can be `null`. + private NamedPKCS8Key(String fname, String pname, byte[] encoded, byte[] expanded) { this.fname = fname; this.paramSpec = new NamedParameterSpec(pname); + this.expanded = expanded; + this.privKeyMaterial = Objects.requireNonNull(encoded); try { this.algid = AlgorithmId.get(pname); } catch (NoSuchAlgorithmException e) { throw new ProviderException(e); } - this.rawBytes = rawBytes; - - DerValue val = new DerValue(DerValue.tag_OctetString, rawBytes); - try { - this.privKeyMaterial = val.toByteArray(); - } finally { - val.clear(); - } } - /// Ctor from family name, and PKCS #8 bytes - public NamedPKCS8Key(String fname, byte[] encoded) throws InvalidKeyException { + /// Creates a `NamedPKCS8Key` from raw components. + /// + /// `encoded` and `expanded` won't be cloned, caller must relinquish + /// ownership. This caller must ensure `encoded` and `expanded` match + /// each other and `encoded` is valid and internally-consistent. + /// + /// @param fname family name + /// @param pname parameter set name + /// @param encoded raw key bytes, not null + /// @param expanded expanded key format, can be `null`. + public static NamedPKCS8Key internalCreate(String fname, String pname, + byte[] encoded, byte[] expanded) { + return new NamedPKCS8Key(fname, pname, encoded, expanded); + } + + /// Creates a `NamedPKCS8Key` from family name and PKCS #8 encoding. + /// + /// @param fname family name + /// @param encoded PKCS #8 encoding. It is copied so caller can modify + /// it after the method call. + /// @param expander a function that is able to calculate the expanded + /// format from the encoding format inside `encoded`. If it recognizes + /// the input already in expanded format, it must return `null`. + /// This argument must be `null` if the algorithm's expanded format + /// is always the same as its encoding format. Whatever the case, the + /// ownership of the result is fully granted to this object. + public NamedPKCS8Key(String fname, byte[] encoded, Expander expander) + throws InvalidKeyException { super(encoded); this.fname = fname; - try { - paramSpec = new NamedParameterSpec(algid.getName()); - if (algid.getEncodedParams() != null) { - throw new InvalidKeyException("algorithm identifier has params"); - } - rawBytes = new DerInputStream(privKeyMaterial).getOctetString(); - } catch (IOException e) { - throw new InvalidKeyException("Cannot parse input", e); + this.expanded = expander == null + ? null + : expander.expand(algid.getName(), this.privKeyMaterial); + paramSpec = new NamedParameterSpec(algid.getName()); + if (algid.getEncodedParams() != null) { + throw new InvalidKeyException("algorithm identifier has params"); } } @@ -104,9 +146,15 @@ public final class NamedPKCS8Key extends PKCS8Key { } /// Returns the reference to the internal key. Caller must not modify - /// the content or keep a reference. + /// the content or pass the reference to untrusted application code. public byte[] getRawBytes() { - return rawBytes; + return privKeyMaterial; + } + + /// Returns the reference to the key in expanded format. Caller must not + /// modify the content or pass the reference to untrusted application code. + public byte[] getExpanded() { + return expanded == null ? privKeyMaterial : expanded; } @Override @@ -127,9 +175,11 @@ public final class NamedPKCS8Key extends PKCS8Key { } @Override - public void destroy() throws DestroyFailedException { - Arrays.fill(rawBytes, (byte)0); + public void destroy() { Arrays.fill(privKeyMaterial, (byte)0); + if (expanded != null) { + Arrays.fill(expanded, (byte)0); + } if (encodedKey != null) { Arrays.fill(encodedKey, (byte)0); } @@ -140,4 +190,17 @@ public final class NamedPKCS8Key extends PKCS8Key { public boolean isDestroyed() { return destroyed; } + + /// Expands from encoding format to expanded format. + @FunctionalInterface + public interface Expander { + /// The expand method + /// + /// @param pname parameter set name + /// @param input input encoding + /// @return the expanded key, `null` if `input` is already in expanded + /// @throws InvalidKeyException if `input` is invalid, for example, + /// wrong encoding, or internal inconsistency + byte[] expand(String pname, byte[] input) throws InvalidKeyException; + } } diff --git a/src/java.base/share/classes/sun/security/provider/ML_DSA.java b/src/java.base/share/classes/sun/security/provider/ML_DSA.java index 6a578427e51..1e27349a5d0 100644 --- a/src/java.base/share/classes/sun/security/provider/ML_DSA.java +++ b/src/java.base/share/classes/sun/security/provider/ML_DSA.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -568,6 +568,54 @@ public class ML_DSA { return new ML_DSA_KeyPair(sk, pk); } + private static int[][] deepClone(int[][] array) { + int[][] clone = new int[array.length][]; + for (int i = 0; i < array.length; i++) { + clone[i] = array[i].clone(); + } + return clone; + } + + // This is similar to the generateKeyPairInternal method. Instead of + // generating from a seed, it uses stored fields inside the private key + // to calculate the public key. It performs several checks during the + // calculation to make sure the private key is a valid one. Otherwise, + // an IllegalArgumentException is thrown. + public ML_DSA_PublicKey privKeyToPubKey(ML_DSA_PrivateKey sk) { + // Sample A + int[][][] keygenA = generateA(sk.rho); //A is in NTT domain + + // Compute t and tr + // make a copy of sk.s1 and modify it. Although we can also + // take it out of NTT domain later, it was modified for a while. + var s1 = deepClone(sk.s1); + mlDsaVectorNtt(s1); //s1 now in NTT domain + int[][] As1 = integerMatrixAlloc(mlDsa_k, ML_DSA_N); + matrixVectorPointwiseMultiply(As1, keygenA, s1); + + mlDsaVectorInverseNtt(As1); + int[][] t = vectorAddPos(As1, sk.s2); + int[][] t0 = integerMatrixAlloc(mlDsa_k, ML_DSA_N); + int[][] t1 = integerMatrixAlloc(mlDsa_k, ML_DSA_N); + power2Round(t, t0, t1); + if (!Arrays.deepEquals(t0, sk.t0)) { + throw new IllegalArgumentException("t0 does not patch"); + } + + var crHash = new SHAKE256(TR_LEN); + + ML_DSA_PublicKey pk = new ML_DSA_PublicKey(sk.rho, t1); + byte[] publicKeyBytes = pkEncode(pk); + crHash.update(publicKeyBytes); + byte[] tr = crHash.digest(); + if (!Arrays.equals(tr, sk.tr)) { + throw new IllegalArgumentException("tr does not patch"); + } + + //Encode PK + return new ML_DSA_PublicKey(sk.rho, t1); + } + public ML_DSA_Signature signInternal(byte[] message, byte[] rnd, byte[] skBytes) { //Decode private key and initialize hash function ML_DSA_PrivateKey sk = skDecode(skBytes); diff --git a/src/java.base/share/classes/sun/security/provider/ML_DSA_Impls.java b/src/java.base/share/classes/sun/security/provider/ML_DSA_Impls.java index dffe7c5cdb1..730e253f407 100644 --- a/src/java.base/share/classes/sun/security/provider/ML_DSA_Impls.java +++ b/src/java.base/share/classes/sun/security/provider/ML_DSA_Impls.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,12 +26,35 @@ package sun.security.provider; import sun.security.jca.JCAUtil; +import sun.security.pkcs.NamedPKCS8Key; +import sun.security.util.KeyChoices; +import sun.security.x509.NamedX509Key; + import java.security.*; import java.security.SecureRandom; import java.util.Arrays; public class ML_DSA_Impls { + private static final int SEED_LEN = 32; + + public static byte[] seedToExpanded(String pname, byte[] seed) { + var impl = new ML_DSA(name2int(pname)); + var sk = impl.generateKeyPairInternal(seed).privateKey(); + try { + return impl.skEncode(sk); + } finally { + sk.destroy(); + } + } + + public static NamedX509Key privKeyToPubKey(NamedPKCS8Key npk) { + var dsa = new ML_DSA(name2int(npk.getParams().getName())); + return new NamedX509Key(npk.getAlgorithm(), + npk.getParams().getName(), + dsa.pkEncode(dsa.privKeyToPubKey(dsa.skDecode(npk.getExpanded())))); + } + public enum Version { DRAFT, FINAL } @@ -43,16 +66,16 @@ public class ML_DSA_Impls { // --add-exports java.base/sun.security.provider=ALL-UNNAMED public static Version version = Version.FINAL; - static int name2int(String name) { - if (name.endsWith("44")) { + static int name2int(String pname) { + if (pname.endsWith("44")) { return 2; - } else if (name.endsWith("65")) { + } else if (pname.endsWith("65")) { return 3; - } else if (name.endsWith("87")) { + } else if (pname.endsWith("87")) { return 5; } else { // should not happen - throw new ProviderException("Unknown name " + name); + throw new ProviderException("Unknown name " + pname); } } @@ -69,20 +92,26 @@ public class ML_DSA_Impls { } @Override - protected byte[][] implGenerateKeyPair(String name, SecureRandom sr) { - byte[] seed = new byte[32]; - var r = sr != null ? sr : JCAUtil.getDefSecureRandom(); + protected byte[][] implGenerateKeyPair(String pname, SecureRandom random) { + byte[] seed = new byte[SEED_LEN]; + var r = random != null ? random : JCAUtil.getDefSecureRandom(); r.nextBytes(seed); - ML_DSA mlDsa = new ML_DSA(name2int(name)); + + ML_DSA mlDsa = new ML_DSA(name2int(pname)); ML_DSA.ML_DSA_KeyPair kp = mlDsa.generateKeyPairInternal(seed); + var expanded = mlDsa.skEncode(kp.privateKey()); + try { return new byte[][]{ mlDsa.pkEncode(kp.publicKey()), - mlDsa.skEncode(kp.privateKey()) + KeyChoices.writeToChoice( + KeyChoices.getPreferred("mldsa"), + seed, expanded), + expanded }; } finally { kp.privateKey().destroy(); - Arrays.fill(seed, (byte)0); + Arrays.fill(seed, (byte) 0); } } } @@ -109,8 +138,39 @@ public class ML_DSA_Impls { public KF() { super("ML-DSA", "ML-DSA-44", "ML-DSA-65", "ML-DSA-87"); } - public KF(String name) { - super("ML-DSA", name); + public KF(String pname) { + super("ML-DSA", pname); + } + + @Override + protected byte[] implExpand(String pname, byte[] input) + throws InvalidKeyException { + return KeyChoices.choiceToExpanded(pname, SEED_LEN, input, + ML_DSA_Impls::seedToExpanded); + } + + @Override + protected Key engineTranslateKey(Key key) throws InvalidKeyException { + var nk = toNamedKey(key); + if (nk instanceof NamedPKCS8Key npk) { + var type = KeyChoices.getPreferred("mldsa"); + if (KeyChoices.typeOfChoice(npk.getRawBytes()) != type) { + var encoding = KeyChoices.choiceToChoice( + type, + npk.getParams().getName(), + SEED_LEN, npk.getRawBytes(), + ML_DSA_Impls::seedToExpanded); + nk = NamedPKCS8Key.internalCreate( + npk.getAlgorithm(), + npk.getParams().getName(), + encoding, + npk.getExpanded().clone()); + if (npk != key) { // npk is neither input or output + npk.destroy(); + } + } + } + return nk; } } @@ -134,16 +194,16 @@ public class ML_DSA_Impls { public sealed static class SIG extends NamedSignature permits SIG2, SIG3, SIG5 { public SIG() { - super("ML-DSA", "ML-DSA-44", "ML-DSA-65", "ML-DSA-87"); + super("ML-DSA", new KF()); } - public SIG(String name) { - super("ML-DSA", name); + public SIG(String pname) { + super("ML-DSA", new KF(pname)); } @Override - protected byte[] implSign(String name, byte[] skBytes, + protected byte[] implSign(String pname, byte[] skBytes, Object sk2, byte[] msg, SecureRandom sr) { - var size = name2int(name); + var size = name2int(pname); var r = sr != null ? sr : JCAUtil.getDefSecureRandom(); byte[] rnd = new byte[32]; r.nextBytes(rnd); @@ -160,10 +220,10 @@ public class ML_DSA_Impls { } @Override - protected boolean implVerify(String name, byte[] pkBytes, + protected boolean implVerify(String pname, byte[] pkBytes, Object pk2, byte[] msg, byte[] sigBytes) throws SignatureException { - var size = name2int(name); + var size = name2int(pname); var mlDsa = new ML_DSA(size); if (version == Version.FINAL) { // FIPS 204 Algorithm 3 ML-DSA.Verify prepend {0, len(ctx)} @@ -176,18 +236,18 @@ public class ML_DSA_Impls { } @Override - protected Object implCheckPublicKey(String name, byte[] pk) + protected Object implCheckPublicKey(String pname, byte[] pk) throws InvalidKeyException { - ML_DSA mlDsa = new ML_DSA(name2int(name)); + ML_DSA mlDsa = new ML_DSA(name2int(pname)); return mlDsa.checkPublicKey(pk); } @Override - protected Object implCheckPrivateKey(String name, byte[] sk) + protected Object implCheckPrivateKey(String pname, byte[] sk) throws InvalidKeyException { - ML_DSA mlDsa = new ML_DSA(name2int(name)); + ML_DSA mlDsa = new ML_DSA(name2int(pname)); return mlDsa.checkPrivateKey(sk); } } diff --git a/src/java.base/share/classes/sun/security/provider/NamedKEM.java b/src/java.base/share/classes/sun/security/provider/NamedKEM.java index 2731b3460af..60449396d4d 100644 --- a/src/java.base/share/classes/sun/security/provider/NamedKEM.java +++ b/src/java.base/share/classes/sun/security/provider/NamedKEM.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,6 @@ import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.NamedParameterSpec; import java.util.Arrays; -import java.util.Objects; /// A base class for all `KEM` implementations that can be /// configured with a named parameter set. See [NamedKeyPairGenerator] @@ -50,21 +49,19 @@ import java.util.Objects; public abstract class NamedKEM implements KEMSpi { private final String fname; // family name - private final String[] pnames; // allowed parameter set name (at least one) + private final NamedKeyFactory fac; /// Creates a new `NamedKEM` object. /// /// @param fname the family name - /// @param pnames the standard parameter set names, at least one is needed. - protected NamedKEM(String fname, String... pnames) { + /// @param fac the `KeyFactory` used to translate foreign keys and + /// perform key validation + protected NamedKEM(String fname, NamedKeyFactory fac) { if (fname == null) { throw new AssertionError("fname cannot be null"); } - if (pnames == null || pnames.length == 0) { - throw new AssertionError("pnames cannot be null or empty"); - } this.fname = fname; - this.pnames = pnames; + this.fac = fac; } @Override @@ -76,8 +73,7 @@ public abstract class NamedKEM implements KEMSpi { "The " + fname + " algorithm does not take any parameters"); } // translate also check the key - var nk = (NamedX509Key) new NamedKeyFactory(fname, pnames) - .engineTranslateKey(publicKey); + var nk = (NamedX509Key) fac.toNamedKey(publicKey); var pk = nk.getRawBytes(); return getKeyConsumerImpl(this, nk.getParams(), pk, implCheckPublicKey(nk.getParams().getName(), pk), secureRandom); @@ -92,16 +88,15 @@ public abstract class NamedKEM implements KEMSpi { "The " + fname + " algorithm does not take any parameters"); } // translate also check the key - var nk = (NamedPKCS8Key) new NamedKeyFactory(fname, pnames) - .engineTranslateKey(privateKey); - var sk = nk.getRawBytes(); + var nk = (NamedPKCS8Key) fac.toNamedKey(privateKey); + var sk = nk.getExpanded(); return getKeyConsumerImpl(this, nk.getParams(), sk, implCheckPrivateKey(nk.getParams().getName(), sk), null); } // We don't have a flag on whether key is public key or private key. // The correct method should always be called. - private record KeyConsumerImpl(NamedKEM kem, String name, int sslen, + private record KeyConsumerImpl(NamedKEM kem, String pname, int sslen, int clen, byte[] key, Object k2, SecureRandom sr) implements KEMSpi.EncapsulatorSpi, KEMSpi.DecapsulatorSpi { @Override @@ -110,7 +105,7 @@ public abstract class NamedKEM implements KEMSpi { if (encapsulation.length != clen) { throw new DecapsulateException("Invalid key encapsulation message length"); } - var ss = kem.implDecapsulate(name, key, k2, encapsulation); + var ss = kem.implDecapsulate(pname, key, k2, encapsulation); try { return new SecretKeySpec(ss, from, to - from, algorithm); @@ -121,7 +116,7 @@ public abstract class NamedKEM implements KEMSpi { @Override public KEM.Encapsulated engineEncapsulate(int from, int to, String algorithm) { - var enc = kem.implEncapsulate(name, key, k2, sr); + var enc = kem.implEncapsulate(pname, key, k2, sr); try { return new KEM.Encapsulated( new SecretKeySpec(enc[1], @@ -146,46 +141,46 @@ public abstract class NamedKEM implements KEMSpi { private static KeyConsumerImpl getKeyConsumerImpl(NamedKEM kem, NamedParameterSpec nps, byte[] key, Object k2, SecureRandom sr) { - String name = nps.getName(); - return new KeyConsumerImpl(kem, name, kem.implSecretSize(name), kem.implEncapsulationSize(name), + String pname = nps.getName(); + return new KeyConsumerImpl(kem, pname, kem.implSecretSize(pname), kem.implEncapsulationSize(pname), key, k2, sr); } /// User-defined encap function. /// - /// @param name parameter name + /// @param pname parameter name /// @param pk public key in raw bytes /// @param pk2 parsed public key, `null` if none. See [#implCheckPublicKey]. /// @param sr SecureRandom object, `null` if not initialized /// @return the key encapsulation message and the shared key (in this order) /// @throws ProviderException if there is an internal error - protected abstract byte[][] implEncapsulate(String name, byte[] pk, Object pk2, SecureRandom sr); + protected abstract byte[][] implEncapsulate(String pname, byte[] pk, Object pk2, SecureRandom sr); /// User-defined decap function. /// - /// @param name parameter name + /// @param pname parameter name /// @param sk private key in raw bytes /// @param sk2 parsed private key, `null` if none. See [#implCheckPrivateKey]. /// @param encap the key encapsulation message /// @return the shared key /// @throws ProviderException if there is an internal error /// @throws DecapsulateException if there is another error - protected abstract byte[] implDecapsulate(String name, byte[] sk, Object sk2, byte[] encap) + protected abstract byte[] implDecapsulate(String pname, byte[] sk, Object sk2, byte[] encap) throws DecapsulateException; /// User-defined function returning shared secret key length. /// - /// @param name parameter name + /// @param pname parameter name /// @return shared secret key length /// @throws ProviderException if there is an internal error - protected abstract int implSecretSize(String name); + protected abstract int implSecretSize(String pname); /// User-defined function returning key encapsulation message length. /// - /// @param name parameter name + /// @param pname parameter name /// @return key encapsulation message length /// @throws ProviderException if there is an internal error - protected abstract int implEncapsulationSize(String name); + protected abstract int implEncapsulationSize(String pname); /// User-defined function to validate a public key. /// @@ -196,11 +191,11 @@ public abstract class NamedKEM implements KEMSpi { /// /// The default implementation returns `null`. /// - /// @param name parameter name + /// @param pname parameter name /// @param pk public key in raw bytes /// @return a parsed key, `null` if none. /// @throws InvalidKeyException if the key is invalid - protected Object implCheckPublicKey(String name, byte[] pk) throws InvalidKeyException { + protected Object implCheckPublicKey(String pname, byte[] pk) throws InvalidKeyException { return null; } @@ -213,11 +208,11 @@ public abstract class NamedKEM implements KEMSpi { /// /// The default implementation returns `null`. /// - /// @param name parameter name + /// @param pname parameter name /// @param sk private key in raw bytes /// @return a parsed key, `null` if none. /// @throws InvalidKeyException if the key is invalid - protected Object implCheckPrivateKey(String name, byte[] sk) throws InvalidKeyException { + protected Object implCheckPrivateKey(String pname, byte[] sk) throws InvalidKeyException { return null; } } diff --git a/src/java.base/share/classes/sun/security/provider/NamedKeyFactory.java b/src/java.base/share/classes/sun/security/provider/NamedKeyFactory.java index 727358dd074..9099f1446ff 100644 --- a/src/java.base/share/classes/sun/security/provider/NamedKeyFactory.java +++ b/src/java.base/share/classes/sun/security/provider/NamedKeyFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,6 @@ import java.security.spec.NamedParameterSpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Arrays; -import java.util.Objects; /// A base class for all `KeyFactory` implementations that can be /// configured with a named parameter set. See [NamedKeyPairGenerator] @@ -58,7 +57,7 @@ import java.util.Objects; /// /// When reading from a RAW format, it needs enough info to derive the /// parameter set name. -public class NamedKeyFactory extends KeyFactorySpi { +public abstract class NamedKeyFactory extends KeyFactorySpi { private final String fname; // family name private final String[] pnames; // allowed parameter set name (at least one) @@ -78,92 +77,110 @@ public class NamedKeyFactory extends KeyFactorySpi { this.pnames = pnames; } - private String checkName(String name) throws InvalidKeyException { - for (var pname : pnames) { - if (pname.equalsIgnoreCase(name)) { + private String checkName(String pname) throws InvalidKeyException { + for (var n : pnames) { + if (n.equalsIgnoreCase(pname)) { // return the stored standard name - return pname; + return n; } } - throw new InvalidKeyException("Unsupported parameter set name: " + name); + throw new InvalidKeyException("Unsupported parameter set name: " + pname); } @Override protected PublicKey engineGeneratePublic(KeySpec keySpec) throws InvalidKeySpecException { - if (keySpec instanceof X509EncodedKeySpec xspec) { - try { - return fromX509(xspec.getEncoded()); - } catch (InvalidKeyException e) { - throw new InvalidKeySpecException(e); + return switch (keySpec) { + case X509EncodedKeySpec xspec -> { + try { + yield fromX509(xspec.getEncoded()); + } catch (InvalidKeyException e) { + throw new InvalidKeySpecException(e); + } } - } else if (keySpec instanceof RawKeySpec rks) { - if (pnames.length == 1) { - return new NamedX509Key(fname, pnames[0], rks.getKeyArr()); - } else { - throw new InvalidKeySpecException("Parameter set name unavailable"); + case RawKeySpec rks -> { + if (pnames.length == 1) { + yield new NamedX509Key(fname, pnames[0], rks.getKeyArr()); + } else { + throw new InvalidKeySpecException("Parameter set name unavailable"); + } } - } else if (keySpec instanceof EncodedKeySpec espec - && espec.getFormat().equalsIgnoreCase("RAW")) { - if (pnames.length == 1) { - return new NamedX509Key(fname, pnames[0], espec.getEncoded()); - } else { - throw new InvalidKeySpecException("Parameter set name unavailable"); + case EncodedKeySpec espec when espec.getFormat().equalsIgnoreCase("RAW") -> { + if (pnames.length == 1) { + yield new NamedX509Key(fname, pnames[0], espec.getEncoded()); + } else { + throw new InvalidKeySpecException("Parameter set name unavailable"); + } } - } else { - throw new InvalidKeySpecException("Unsupported keyspec: " + keySpec); - } + case null -> throw new InvalidKeySpecException( + "keySpec must not be null"); + default -> + throw new InvalidKeySpecException(keySpec.getClass().getName() + + " not supported."); + }; } @Override protected PrivateKey engineGeneratePrivate(KeySpec keySpec) throws InvalidKeySpecException { - if (keySpec instanceof PKCS8EncodedKeySpec pspec) { - var bytes = pspec.getEncoded(); - try { - return fromPKCS8(bytes); - } catch (InvalidKeyException e) { - throw new InvalidKeySpecException(e); - } finally { - Arrays.fill(bytes, (byte) 0); - } - } else if (keySpec instanceof RawKeySpec rks) { - if (pnames.length == 1) { - var bytes = rks.getKeyArr(); + return switch (keySpec) { + case PKCS8EncodedKeySpec pspec -> { + var bytes = pspec.getEncoded(); try { - return new NamedPKCS8Key(fname, pnames[0], bytes); + yield fromPKCS8(bytes); + } catch (InvalidKeyException e) { + throw new InvalidKeySpecException(e); } finally { Arrays.fill(bytes, (byte) 0); } - } else { - throw new InvalidKeySpecException("Parameter set name unavailable"); } - } else if (keySpec instanceof EncodedKeySpec espec - && espec.getFormat().equalsIgnoreCase("RAW")) { - if (pnames.length == 1) { - var bytes = espec.getEncoded(); - try { - return new NamedPKCS8Key(fname, pnames[0], bytes); - } finally { - Arrays.fill(bytes, (byte) 0); + case RawKeySpec rks -> { + if (pnames.length == 1) { + var raw = rks.getKeyArr(); + try { + yield fromRaw(pnames[0], raw); + } catch (InvalidKeyException e) { + throw new InvalidKeySpecException("Invalid key input", e); + } + } else { + throw new InvalidKeySpecException("Parameter set name unavailable"); } - } else { - throw new InvalidKeySpecException("Parameter set name unavailable"); } - } else { - throw new InvalidKeySpecException("Unsupported keyspec: " + keySpec); - } + case EncodedKeySpec espec when espec.getFormat().equalsIgnoreCase("RAW") -> { + if (pnames.length == 1) { + var raw = espec.getEncoded(); + try { + yield fromRaw(pnames[0], raw); + } catch (InvalidKeyException e) { + throw new InvalidKeySpecException("Invalid key input", e); + } + } else { + throw new InvalidKeySpecException("Parameter set name unavailable"); + } + } + case null -> throw new InvalidKeySpecException( + "keySpec must not be null"); + default -> + throw new InvalidKeySpecException(keySpec.getClass().getName() + + " not supported."); + }; + } + + private PrivateKey fromRaw(String pname, byte[] raw) + throws InvalidKeyException { + return NamedPKCS8Key.internalCreate( + fname, pname, raw, implExpand(pname, raw)); } private PrivateKey fromPKCS8(byte[] bytes) - throws InvalidKeyException, InvalidKeySpecException { - var k = new NamedPKCS8Key(fname, bytes); + throws InvalidKeyException { + var k = new NamedPKCS8Key(fname, bytes, this::implExpand); checkName(k.getParams().getName()); return k; } private PublicKey fromX509(byte[] bytes) - throws InvalidKeyException, InvalidKeySpecException { + throws InvalidKeyException { var k = new NamedX509Key(fname, bytes); checkName(k.getParams().getName()); return k; @@ -184,7 +201,7 @@ public class NamedKeyFactory extends KeyFactorySpi { protected T engineGetKeySpec(Key key, Class keySpec) throws InvalidKeySpecException { try { - key = engineTranslateKey(key); + key = toNamedKey(key); } catch (InvalidKeyException e) { throw new InvalidKeySpecException(e); } @@ -225,6 +242,12 @@ public class NamedKeyFactory extends KeyFactorySpi { @Override protected Key engineTranslateKey(Key key) throws InvalidKeyException { + // The base toNamedKey only makes sure key is translated into a NamedKey. + // the key material is still the same as the input. + return toNamedKey(key); + } + + protected Key toNamedKey(Key key) throws InvalidKeyException { if (key == null) { throw new InvalidKeyException("Key must not be null"); } @@ -242,27 +265,28 @@ public class NamedKeyFactory extends KeyFactorySpi { } else if (format.equalsIgnoreCase("RAW")) { var kAlg = key.getAlgorithm(); if (key instanceof AsymmetricKey pk) { - String name; + String pname; // Three cases that we can find the parameter set name from a RAW key: // 1. getParams() returns one // 2. getAlgorithm() returns param set name (some provider does this) // 3. getAlgorithm() returns family name but this KF is for param set name if (pk.getParams() instanceof NamedParameterSpec nps) { - name = checkName(nps.getName()); + pname = checkName(nps.getName()); } else { if (kAlg.equalsIgnoreCase(fname)) { if (pnames.length == 1) { - name = pnames[0]; + pname = pnames[0]; } else { throw new InvalidKeyException("No parameter set info"); } } else { - name = checkName(kAlg); + pname = checkName(kAlg); } } + var raw = key.getEncoded(); return key instanceof PrivateKey - ? new NamedPKCS8Key(fname, name, key.getEncoded()) - : new NamedX509Key(fname, name, key.getEncoded()); + ? fromRaw(pname, raw) + : new NamedX509Key(fname, pname, raw); } else { throw new InvalidKeyException("Unsupported key type: " + key.getClass()); } @@ -270,19 +294,26 @@ public class NamedKeyFactory extends KeyFactorySpi { var bytes = key.getEncoded(); try { return fromPKCS8(bytes); - } catch (InvalidKeySpecException e) { - throw new InvalidKeyException("Invalid PKCS#8 key", e); } finally { Arrays.fill(bytes, (byte) 0); } } else if (format.equalsIgnoreCase("X.509") && key instanceof PublicKey) { - try { - return fromX509(key.getEncoded()); - } catch (InvalidKeySpecException e) { - throw new InvalidKeyException("Invalid X.509 key", e); - } + return fromX509(key.getEncoded()); } else { throw new InvalidKeyException("Unsupported key format: " + key.getFormat()); } } + + /// User-defined function to generate the expanded format of + /// a [NamedPKCS8Key] from its encoding format. + /// + /// This method is called when the key factory is constructing a private + /// key. The ownership of the result is fully granted to the caller. + /// + /// @param pname the parameter set name + /// @param input the encoding, could be any format + /// @return the expanded key, not null + /// @throws InvalidKeyException if `input` is invalid + protected abstract byte[] implExpand(String pname, byte[] input) + throws InvalidKeyException; } diff --git a/src/java.base/share/classes/sun/security/provider/NamedKeyPairGenerator.java b/src/java.base/share/classes/sun/security/provider/NamedKeyPairGenerator.java index 5be2b2b2a08..6b55924b0fe 100644 --- a/src/java.base/share/classes/sun/security/provider/NamedKeyPairGenerator.java +++ b/src/java.base/share/classes/sun/security/provider/NamedKeyPairGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,6 @@ import java.security.ProviderException; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.NamedParameterSpec; -import java.util.Objects; /// A base class for all `KeyPairGenerator` implementations that can be /// configured with a named parameter set. @@ -52,15 +51,21 @@ import java.util.Objects; /// with `getAlgorithm` returning the family name, and `getParams` returning /// the parameter set name as a [NamedParameterSpec] object. /// -/// An implementation must include a zero-argument public constructor that -/// calls `super(fname, pnames)`, where `fname` is the family name of the -/// algorithm and `pnames` are its supported parameter set names. `pnames` -/// must contain at least one element. For an implementation of -/// `NamedKeyPairGenerator`, the first element becomes its default parameter -/// set, i.e. the parameter set to be used in key pair generation unless +/// A `NamedKeyPairGenerator` or `NamedKeyFactory` implementation must include +/// a zero-argument public constructor that calls `super(fname, pnames)`, where +/// `fname` is the family name of the algorithm and `pnames` are its supported +/// parameter set names. `pnames` must contain at least one element. For an +/// implementation of `NamedKeyPairGenerator`, the first element becomes its +/// default parameter set, i.e. the parameter set used by generated keys unless /// [#initialize(AlgorithmParameterSpec, java.security.SecureRandom)] /// is called on a different parameter set. /// +/// A `NamedKEM` or `NamedSignature` implementation must include a zero-argument +/// public constructor that calls `super(fname, factory)`, where `fname` is the +/// family name of the algorithm and `factory` is the `NamedKeyFactory` object +/// that is used to translate foreign keys. `factory` only recognizes +/// parameter sets supported by this implementation. +/// /// An implementation must implement all abstract methods. For all these /// methods, the implementation must relinquish any "ownership" of any input /// and output array argument. Precisely, the implementation must not retain @@ -69,8 +74,8 @@ import java.util.Objects; /// array argument and must not retain any reference to an input array argument /// after the call. /// -/// Also, an implementation must not keep any extra copy of a private key. -/// For key generation, the only copy is the one returned in the +/// Also, an implementation must not keep any extra copy of a private key in +/// any format. For key generation, the only copy is the one returned in the /// [#implGenerateKeyPair] call. For all other methods, it must not make /// a copy of the input private key. A `KEM` implementation also must not /// keep a copy of the shared secret key, no matter if it's an encapsulator @@ -84,6 +89,34 @@ import java.util.Objects; /// (For example, `implSign`) later. An implementation must not retain /// a reference of the parsed key. /// +/// The private key, represented as a byte array when used in `NamedKEM` or +/// `NamedSignature`, is referred to as its expanded format. For some +/// algorithms, this format may differ from the +/// [key material][NamedPKCS8Key#getRawBytes()] inside a PKCS #8 file. For example, +/// [FIPS 204](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.204.pdf) +/// Table 2 defines the ML-DSA-65 private key as a 4032-byte array, which is +/// used in the ML-DSA.Sign function in Algorithm 2, representing the +/// expanded format. However, in +/// [RFC 9881](https://datatracker.ietf.org/doc/html/rfc9881#name-private-key-format), +/// a private key can be encoded into a CHOICE of three formats, none in the +/// same as the FIPS 204 format. The choices are defined in +/// [sun.security.util.KeyChoices]. A `NamedKeyPairGenerator` implementation +/// should return both the expanded key and a preferred encoding in its +/// [#implGenerateKeyPair] method. +/// +/// A `NamedKeyFactory` must override the `implExpand` method to derive +/// the expanded format from an encoding format, or return `null` if there +/// is no difference. +/// +/// Implementations may support multiple encoding formats. +/// +/// A `NamedKeyFactory` must not modify the encoding when generating a key +/// from a `KeySpec` object, ensuring that when re-encoded, the key retains +/// its original encoding format. +/// +/// A `NamedKeyFactory` can choose a different encoding format when +/// `translateKey` is called. +/// /// When constructing a [NamedX509Key] or [NamedPKCS8Key] object from raw key /// bytes, the key bytes are directly referenced within the object, so the /// caller must not modify them afterward. Similarly, the key's `getRawBytes` @@ -105,9 +138,9 @@ import java.util.Objects; public abstract class NamedKeyPairGenerator extends KeyPairGeneratorSpi { private final String fname; // family name - private final String[] pnames; // allowed parameter set name (at least one) + private final String[] pnames; // allowed parameter set names (at least one) - protected String name; // init as + protected String pname; // parameter set name, if can be determined private SecureRandom secureRandom; /// Creates a new `NamedKeyPairGenerator` object. @@ -126,22 +159,22 @@ public abstract class NamedKeyPairGenerator extends KeyPairGeneratorSpi { this.pnames = pnames; } - private String checkName(String name) throws InvalidAlgorithmParameterException { - for (var pname : pnames) { - if (pname.equalsIgnoreCase(name)) { - // return the stored standard name - return pname; + private String checkName(String pname) throws InvalidAlgorithmParameterException { + for (var n : pnames) { + if (n.equalsIgnoreCase(pname)) { + // return the stored standard pname + return n; } } throw new InvalidAlgorithmParameterException( - "Unsupported parameter set name: " + name); + "Unsupported parameter set name: " + pname); } @Override public void initialize(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { if (params instanceof NamedParameterSpec spec) { - name = checkName(spec.getName()); + pname = checkName(spec.getName()); } else { throw new InvalidAlgorithmParameterException( "Unsupported AlgorithmParameterSpec: " + params); @@ -161,17 +194,21 @@ public abstract class NamedKeyPairGenerator extends KeyPairGeneratorSpi { @Override public KeyPair generateKeyPair() { - String pname = name != null ? name : pnames[0]; - var keys = implGenerateKeyPair(pname, secureRandom); - return new KeyPair(new NamedX509Key(fname, pname, keys[0]), - new NamedPKCS8Key(fname, pname, keys[1])); + String tmpName = pname != null ? pname : pnames[0]; + var keys = implGenerateKeyPair(tmpName, secureRandom); + return new KeyPair(new NamedX509Key(fname, tmpName, keys[0]), + NamedPKCS8Key.internalCreate(fname, tmpName, keys[1], + keys.length == 2 ? null : keys[2])); } /// User-defined key pair generator. /// /// @param pname parameter set name /// @param sr `SecureRandom` object, `null` if not initialized - /// @return public key and private key (in this order) in raw bytes + /// @return the public key, the private key in its encoding format, and + /// the private key in its expanded format (in this order) in + /// raw bytes. If the expanded format of the private key is the + /// same as its encoding format, the 3rd element must be omitted. /// @throws ProviderException if there is an internal error protected abstract byte[][] implGenerateKeyPair(String pname, SecureRandom sr); } diff --git a/src/java.base/share/classes/sun/security/provider/NamedSignature.java b/src/java.base/share/classes/sun/security/provider/NamedSignature.java index 921a39cfc92..07d20828c3c 100644 --- a/src/java.base/share/classes/sun/security/provider/NamedSignature.java +++ b/src/java.base/share/classes/sun/security/provider/NamedSignature.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,6 @@ import java.security.SecureRandom; import java.security.SignatureException; import java.security.SignatureSpi; import java.security.spec.AlgorithmParameterSpec; -import java.util.Objects; /// A base class for all `Signature` implementations that can be /// configured with a named parameter set. See [NamedKeyPairGenerator] @@ -50,12 +49,12 @@ import java.util.Objects; public abstract class NamedSignature extends SignatureSpi { private final String fname; // family name - private final String[] pnames; // allowed parameter set name (at least one) + private final NamedKeyFactory fac; private final ByteArrayOutputStream bout = new ByteArrayOutputStream(); // init with... - private String name; + private String pname; private byte[] secKey; private byte[] pubKey; @@ -65,26 +64,23 @@ public abstract class NamedSignature extends SignatureSpi { /// Creates a new `NamedSignature` object. /// /// @param fname the family name - /// @param pnames the standard parameter set names, at least one is needed. - protected NamedSignature(String fname, String... pnames) { + /// @param fac the `KeyFactory` used to translate foreign keys and + /// perform key validation + protected NamedSignature(String fname, NamedKeyFactory fac) { if (fname == null) { throw new AssertionError("fname cannot be null"); } - if (pnames == null || pnames.length == 0) { - throw new AssertionError("pnames cannot be null or empty"); - } this.fname = fname; - this.pnames = pnames; + this.fac = fac; } @Override protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException { // translate also check the key - var nk = (NamedX509Key) new NamedKeyFactory(fname, pnames) - .engineTranslateKey(publicKey); - name = nk.getParams().getName(); + var nk = (NamedX509Key) fac.toNamedKey(publicKey); + pname = nk.getParams().getName(); pubKey = nk.getRawBytes(); - pk2 = implCheckPublicKey(name, pubKey); + pk2 = implCheckPublicKey(pname, pubKey); secKey = null; bout.reset(); } @@ -92,11 +88,10 @@ public abstract class NamedSignature extends SignatureSpi { @Override protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException { // translate also check the key - var nk = (NamedPKCS8Key) new NamedKeyFactory(fname, pnames) - .engineTranslateKey(privateKey); - name = nk.getParams().getName(); - secKey = nk.getRawBytes(); - sk2 = implCheckPrivateKey(name, secKey); + var nk = (NamedPKCS8Key) fac.toNamedKey(privateKey); + pname = nk.getParams().getName(); + secKey = nk.getExpanded(); + sk2 = implCheckPrivateKey(pname, secKey); pubKey = null; bout.reset(); } @@ -116,7 +111,7 @@ public abstract class NamedSignature extends SignatureSpi { if (secKey != null) { var msg = bout.toByteArray(); bout.reset(); - return implSign(name, secKey, sk2, msg, appRandom); + return implSign(pname, secKey, sk2, msg, appRandom); } else { throw new SignatureException("No private key"); } @@ -127,21 +122,21 @@ public abstract class NamedSignature extends SignatureSpi { if (pubKey != null) { var msg = bout.toByteArray(); bout.reset(); - return implVerify(name, pubKey, pk2, msg, sig); + return implVerify(pname, pubKey, pk2, msg, sig); } else { throw new SignatureException("No public key"); } } @Override - @SuppressWarnings("deprecation") + @Deprecated protected void engineSetParameter(String param, Object value) throws InvalidParameterException { throw new InvalidParameterException("setParameter() not supported"); } @Override - @SuppressWarnings("deprecation") + @Deprecated protected Object engineGetParameter(String param) throws InvalidParameterException { throw new InvalidParameterException("getParameter() not supported"); } @@ -162,7 +157,7 @@ public abstract class NamedSignature extends SignatureSpi { /// User-defined sign function. /// - /// @param name parameter name + /// @param pname parameter name /// @param sk private key in raw bytes /// @param sk2 parsed private key, `null` if none. See [#implCheckPrivateKey]. /// @param msg the message @@ -170,12 +165,12 @@ public abstract class NamedSignature extends SignatureSpi { /// @return the signature /// @throws ProviderException if there is an internal error /// @throws SignatureException if there is another error - protected abstract byte[] implSign(String name, byte[] sk, Object sk2, + protected abstract byte[] implSign(String pname, byte[] sk, Object sk2, byte[] msg, SecureRandom sr) throws SignatureException; /// User-defined verify function. /// - /// @param name parameter name + /// @param pname parameter name /// @param pk public key in raw bytes /// @param pk2 parsed public key, `null` if none. See [#implCheckPublicKey]. /// @param msg the message @@ -183,7 +178,7 @@ public abstract class NamedSignature extends SignatureSpi { /// @return true if verified /// @throws ProviderException if there is an internal error /// @throws SignatureException if there is another error - protected abstract boolean implVerify(String name, byte[] pk, Object pk2, + protected abstract boolean implVerify(String pname, byte[] pk, Object pk2, byte[] msg, byte[] sig) throws SignatureException; /// User-defined function to validate a public key. @@ -195,11 +190,11 @@ public abstract class NamedSignature extends SignatureSpi { /// /// The default implementation returns `null`. /// - /// @param name parameter name + /// @param pname parameter name /// @param pk public key in raw bytes /// @return a parsed key, `null` if none. /// @throws InvalidKeyException if the key is invalid - protected Object implCheckPublicKey(String name, byte[] pk) throws InvalidKeyException { + protected Object implCheckPublicKey(String pname, byte[] pk) throws InvalidKeyException { return null; } @@ -212,11 +207,11 @@ public abstract class NamedSignature extends SignatureSpi { /// /// The default implementation returns `null`. /// - /// @param name parameter name + /// @param pname parameter name /// @param sk private key in raw bytes /// @return a parsed key, `null` if none. /// @throws InvalidKeyException if the key is invalid - protected Object implCheckPrivateKey(String name, byte[] sk) throws InvalidKeyException { + protected Object implCheckPrivateKey(String pname, byte[] sk) throws InvalidKeyException { return null; } } diff --git a/src/java.base/share/classes/sun/security/util/CryptoAlgorithmConstraints.java b/src/java.base/share/classes/sun/security/util/CryptoAlgorithmConstraints.java index a8649106a38..ad3beab350f 100644 --- a/src/java.base/share/classes/sun/security/util/CryptoAlgorithmConstraints.java +++ b/src/java.base/share/classes/sun/security/util/CryptoAlgorithmConstraints.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -82,8 +82,10 @@ public class CryptoAlgorithmConstraints extends AbstractAlgorithmConstraints { CryptoAlgorithmConstraints(String propertyName) { super(null); disabledServices = getAlgorithms(propertyName, true); - debug("Before " + Arrays.deepToString(disabledServices.toArray())); - for (String dk : disabledServices) { + String[] entries = disabledServices.toArray(new String[0]); + debug("Before " + Arrays.deepToString(entries)); + + for (String dk : entries) { int idx = dk.indexOf("."); if (idx < 1 || idx == dk.length() - 1) { // wrong syntax: missing "." or empty service or algorithm diff --git a/src/java.base/share/classes/sun/security/util/KeyChoices.java b/src/java.base/share/classes/sun/security/util/KeyChoices.java new file mode 100644 index 00000000000..da3c611750e --- /dev/null +++ b/src/java.base/share/classes/sun/security/util/KeyChoices.java @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.security.util; + +import java.security.*; +import java.util.Arrays; +import java.util.Locale; +import java.util.function.BiFunction; + +/** + * The content of an ML-KEM or ML-DSA private key is defined as a CHOICE + * among three different representations. For example: + *

    + *  ML-KEM-1024-PrivateKey ::= CHOICE {
    + *       seed [0] OCTET STRING (SIZE (64)),
    + *       expandedKey OCTET STRING (SIZE (3168)),
    + *       both SEQUENCE {
    + *           seed OCTET STRING (SIZE (64)),
    + *           expandedKey OCTET STRING (SIZE (3168))
    + *           }
    + *       }
    + * 
    + * This class supports reading, writing, and converting between them. + *

    + * Current code follows draft-ietf-lamps-kyber-certificates-11 and RFC 9881. + */ +public final class KeyChoices { + + public enum Type { SEED, EXPANDED_KEY, BOTH } + + private record Choice(Type type, byte[] seed, byte[] expanded) {} + + /** + * Gets the preferred choice type for an algorithm, defined as an + * overridable security property "jdk..pkcs8.encoding". + * + * @param name "mlkem" or "mldsa". + * @throws IllegalArgumentException if property is invalid value + * @return the type + */ + public static Type getPreferred(String name) { + var prop = SecurityProperties.getOverridableProperty( + "jdk." + name + ".pkcs8.encoding"); + if (prop == null) { + return Type.SEED; + } + return switch (prop.toLowerCase(Locale.ROOT)) { + case "seed" -> Type.SEED; + case "expandedkey" -> Type.EXPANDED_KEY; + case "both" -> Type.BOTH; + default -> throw new IllegalArgumentException("Unknown format: " + prop); + }; + } + + /** + * Writes one of the ML-KEM or ML-DSA private key formats. + *

    + * This method does not check the length of the inputs or whether + * they match each other. The caller must make sure `seed` and/or + * `expanded` are provided if `type` requires any of them. + * + * @param type preferred output choice type + * @param seed the seed, could be null + * @param expanded the expanded key, could be null + * @return one of the choices + */ + public static byte[] writeToChoice(Type type, byte[] seed, byte[] expanded) { + byte[] skOctets; + // Ensures using one-byte len in DER + assert seed == null || seed.length < 128; + // Ensures using two-byte len in DER + assert expanded == null || expanded.length > 256 && expanded.length < 60000; + + return switch (type) { + case SEED -> { + assert seed != null; + skOctets = new byte[seed.length + 2]; + skOctets[0] = (byte)0x80; + skOctets[1] = (byte) seed.length; + System.arraycopy(seed, 0, skOctets, 2, seed.length); + yield skOctets; + } + case EXPANDED_KEY -> { + assert expanded != null; + skOctets = new byte[expanded.length + 4]; + skOctets[0] = 0x04; + writeShortLength(skOctets, 1, expanded.length); + System.arraycopy(expanded, 0, skOctets, 4, expanded.length); + yield skOctets; + } + case BOTH -> { + assert seed != null; + assert expanded != null; + skOctets = new byte[10 + seed.length + expanded.length]; + skOctets[0] = 0x30; + writeShortLength(skOctets, 1, 6 + seed.length + expanded.length); + skOctets[4] = 0x04; + skOctets[5] = (byte)seed.length; + System.arraycopy(seed, 0, skOctets, 6, seed.length); + skOctets[6 + seed.length] = 0x04; + writeShortLength(skOctets, 7 + seed.length, expanded.length); + System.arraycopy(expanded, 0, skOctets, 10 + seed.length, expanded.length); + yield skOctets; + } + }; + } + + /** + * Gets the type of input. + * + * @param input input bytes + * @return the type + * @throws InvalidKeyException if input is invalid + */ + public static Type typeOfChoice(byte[] input) throws InvalidKeyException { + if (input.length < 1) { + throw new InvalidKeyException("Empty key"); + } + return switch (input[0]) { + case (byte) 0x80 -> Type.SEED; + case 0x04 -> Type.EXPANDED_KEY; + case 0x30 -> Type.BOTH; + default -> throw new InvalidKeyException("Wrong tag: " + input[0]); + }; + } + + /** + * Splits one of the ML-KEM or ML-DSA private key formats into + * seed and expandedKey, if exists. + * + * @param seedLen correct seed length + * @param input input bytes + * @return a {@code Choice} object. Byte arrays inside are newly allocated + * @throws InvalidKeyException if input is invalid + */ + private static Choice readFromChoice(int seedLen, byte[] input) + throws InvalidKeyException { + if (input.length < seedLen + 2) { + throw new InvalidKeyException("Too short"); + } + return switch (input[0]) { + case (byte) 0x80 -> { + // 80 SEED_LEN + if (input[1] != seedLen && input.length != seedLen + 2) { + throw new InvalidKeyException("Invalid seed"); + } + yield new Choice(Type.SEED, + Arrays.copyOfRange(input, 2, seedLen + 2), null); + } + case 0x04 -> { + // 04 82 nn nn + if (readShortLength(input, 1) != input.length - 4) { + throw new InvalidKeyException("Invalid expandedKey"); + } + yield new Choice(Type.EXPANDED_KEY, + null, Arrays.copyOfRange(input, 4, input.length)); + } + case 0x30 -> { + // 30 82 mm mm 04 SEED_LEN 04 82 nn nn + if (input.length < 6 + seedLen + 4) { + throw new InvalidKeyException("Too short"); + } + if (readShortLength(input, 1) != input.length - 4 + || input[4] != 0x04 + || input[5] != (byte)seedLen + || input[seedLen + 6] != 0x04 + || readShortLength(input, seedLen + 7) + != input.length - 10 - seedLen) { + throw new InvalidKeyException("Invalid both"); + } + yield new Choice(Type.BOTH, + Arrays.copyOfRange(input, 6, 6 + seedLen), + Arrays.copyOfRange(input, seedLen + 10, input.length)); + } + default -> throw new InvalidKeyException("Wrong tag: " + input[0]); + }; + } + + /** + * Reads from any encoding and write to the specified type. + * + * @param type preferred output choice type + * @param pname parameter set name + * @param seedLen seed length + * @param input the input encoding + * @param expander function to calculate expanded from seed, could be null + * if there is already expanded in input + * @return the preferred encoding + * @throws InvalidKeyException if input is invalid or does not have enough + * information to generate the output + */ + public static byte[] choiceToChoice(Type type, String pname, + int seedLen, byte[] input, + BiFunction expander) + throws InvalidKeyException { + var choice = readFromChoice(seedLen, input); + try { + if (type != Type.EXPANDED_KEY && choice.type == Type.EXPANDED_KEY) { + throw new InvalidKeyException( + "key contains not enough info to translate"); + } + var expanded = (choice.expanded == null && type != Type.SEED) + ? expander.apply(pname, choice.seed) + : choice.expanded; + return writeToChoice(type, choice.seed, expanded); + } finally { + if (choice.seed != null) { + Arrays.fill(choice.seed, (byte) 0); + } + if (choice.expanded != null) { + Arrays.fill(choice.expanded, (byte) 0); + } + } + } + + /** + * Reads from any choice of encoding and return the expanded format. + * + * @param pname parameter set name + * @param seedLen seed length + * @param input input encoding + * @param expander function to calculate expanded from seed, could be null + * if there is already expanded in input + * @return the expanded key + * @throws InvalidKeyException if input is invalid + */ + public static byte[] choiceToExpanded(String pname, + int seedLen, byte[] input, + BiFunction expander) + throws InvalidKeyException { + var choice = readFromChoice(seedLen, input); + if (choice.type == Type.BOTH) { + var calculated = expander.apply(pname, choice.seed); + if (!Arrays.equals(choice.expanded, calculated)) { + throw new InvalidKeyException("seed and expandedKey do not match"); + } + Arrays.fill(calculated, (byte)0); + } + try { + if (choice.expanded != null) { + return choice.expanded; + } + return expander.apply(pname, choice.seed); + } finally { + if (choice.seed != null) { + Arrays.fill(choice.seed, (byte)0); + } + } + } + + // Reads a 2 bytes length from DER encoding + private static int readShortLength(byte[] input, int from) + throws InvalidKeyException { + if (input[from] != (byte)0x82) { + throw new InvalidKeyException("Unexpected length"); + } + return ((input[from + 1] & 0xff) << 8) + (input[from + 2] & 0xff); + } + + // Writes a 2 bytes length to DER encoding + private static void writeShortLength(byte[] input, int from, int value) { + input[from] = (byte)0x82; + input[from + 1] = (byte) (value >> 8); + input[from + 2] = (byte) (value); + } +} diff --git a/src/java.base/share/classes/sun/security/x509/NamedX509Key.java b/src/java.base/share/classes/sun/security/x509/NamedX509Key.java index dc36bd3b9b3..0c3fe2bf121 100644 --- a/src/java.base/share/classes/sun/security/x509/NamedX509Key.java +++ b/src/java.base/share/classes/sun/security/x509/NamedX509Key.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -71,7 +71,8 @@ public final class NamedX509Key extends X509Key { setKey(new BitArray(rawBytes.length * 8, rawBytes)); } - /// Ctor from family name, and X.509 bytes + /// Ctor from family name, and X.509 bytes. Input byte array + /// is copied. Caller can modify it after the method call. public NamedX509Key(String fname, byte[] encoded) throws InvalidKeyException { this.fname = fname; decode(encoded); diff --git a/src/java.base/share/conf/security/java.security b/src/java.base/share/conf/security/java.security index 9a81ba86268..ef4d7285f51 100644 --- a/src/java.base/share/conf/security/java.security +++ b/src/java.base/share/conf/security/java.security @@ -1700,3 +1700,28 @@ jdk.epkcs8.defaultAlgorithm=PBEWithHmacSHA256AndAES_128 # com.sun.security.allowedAIALocations=http://some.company.com/cacert \ # ldap://ldap.company.com/dc=company,dc=com?caCertificate;binary com.sun.security.allowedAIALocations= + +# +# PKCS #8 encoding format for newly created ML-KEM and ML-DSA private keys +# +# draft-ietf-lamps-kyber-certificates-11 and RFC 9881 define three possible formats for a private key: +# a seed (64 bytes for ML-KEM, 32 bytes for ML-DSA), an expanded private key, +# or a sequence containing both. +# +# The following security properties determine the encoding format used when a +# new keypair is generated with a KeyPairGenerator, and the output of the +# translateKey method on an existing key using a ML-KEM or ML-DSA KeyFactory. +# +# Valid values for these properties are "seed", "expandedKey", and "both" +# (case-insensitive). The default is "seed". +# +# If a system property of the same name is also specified, it supersedes the +# security property value defined here. +# +# Note: These properties are currently used by the SunJCE (for ML-KEM) and SUN +# (for ML-DSA) providers in the JDK Reference implementation. They are not +# guaranteed to be supported by other implementations or third-party security +# providers. +# +#jdk.mlkem.pkcs8.encoding = seed +#jdk.mldsa.pkcs8.encoding = seed diff --git a/src/java.base/share/man/keytool.md b/src/java.base/share/man/keytool.md index 19ba8c34912..1d70bd2f5f8 100644 --- a/src/java.base/share/man/keytool.md +++ b/src/java.base/share/man/keytool.md @@ -1,5 +1,5 @@ --- -# Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1998, 2026, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -211,7 +211,7 @@ perform. ## Commands for Creating or Adding Data to the Keystore -`-gencert` +[`-gencert`]{#command-gencert} : The following are the available options for the `-gencert` command: - {`-rfc`}: Output in RFC (Request For Comment) style @@ -328,7 +328,7 @@ perform. > `keytool -alias e1 -certreq | keytool -alias ca2 -gencert > e1.cert` -`-genkeypair` +[`-genkeypair`]{#option-genkeypair} : The following are the available options for the `-genkeypair` command: - {`-alias` *alias*}: Alias name of the entry to process @@ -478,7 +478,7 @@ perform. specified by `-startdate`, or the current date when `-startdate` isn't specified) for which the certificate should be considered valid. -`-genseckey` +[`-genseckey`]{#command-genseckey} : The following are the available options for the `-genseckey` command: - {`-alias` *alias*}: Alias name of the entry to process @@ -521,7 +521,7 @@ perform. the same password that is used for the `-keystore`. The `-keypass` value must contain at least six characters. -`-importcert` +[`-importcert`]{#command-importcert} : The following are the available options for the `-importcert` command: - {`-noprompt`}: Do not prompt @@ -586,7 +586,7 @@ perform. entry, then the `keytool` command assumes that you're importing a certificate reply. -`-importpass` +[`-importpass`]{#command-importpass} : The following are the available options for the `-importpass` command: - {`-alias` *alias*}: Alias name of the entry to process @@ -629,7 +629,7 @@ perform. ## Commands for Importing Contents from Another Keystore -`-importkeystore` +[`-importkeystore`]{#command-importkeystore} : The following are the available options for the `-importkeystore` command: - `-srckeystore` *keystore*: Source keystore name @@ -724,7 +724,7 @@ perform. ## Commands for Generating a Certificate Request -`-certreq` +[`-certreq`]{#command-certreq} : The following are the available options for the `-certreq` command: - {`-alias` *alias*}: Alias name of the entry to process @@ -786,7 +786,7 @@ perform. ## Commands for Exporting Data -`-exportcert` +[`-exportcert`]{#command-exportcert} : The following are the available options for the `-exportcert` command: - {`-rfc`}: Output in RFC style @@ -834,7 +834,7 @@ perform. ## Commands for Displaying Data -`-list` +[`-list`]{#command-list} : The following are the available options for the `-list` command: - {`-rfc`}: Output in RFC style @@ -881,7 +881,7 @@ perform. You can't specify both `-v` and `-rfc` in the same command. Otherwise, an error is reported. -`-printcert` +[`-printcert`]{#command-printcert} : The following are the available options for the `-printcert` command: - {`-rfc`}: Output in RFC style @@ -946,7 +946,7 @@ perform. trusted certificate in the user keystore (specified by `-keystore`) or in the `cacerts` keystore (if `-trustcacerts` is specified). -`-printcertreq` +[`-printcertreq`]{#command-printcertreq} : The following are the available options for the `-printcertreq` command: - {`-file` *file*}: Input file name @@ -958,7 +958,7 @@ perform. command. The command reads the request from file. If there is no file, then the request is read from the standard input. -`-printcrl` +[`-printcrl`]{#command-printcrl} : The following are the available options for the `-printcrl` command: - {`-file crl`}: Input file name @@ -999,7 +999,7 @@ perform. ## Commands for Managing the Keystore -`-storepasswd` +[`-storepasswd`]{#command-storepasswd} : The following are the available options for the `-storepasswd` command: - \[`-new` *arg*\]: New password @@ -1029,7 +1029,7 @@ perform. integrity of the keystore contents. The new password is set by `-new` *arg* and must contain at least six characters. -`-keypasswd` +[`-keypasswd`]{#command-keypasswd} : The following are the available options for the `-keypasswd` command: - {`-alias` *alias*}: Alias name of the entry to process @@ -1069,7 +1069,7 @@ perform. If the `-new` option isn't provided at the command line, then the user is prompted for it. -`-delete` +[`-delete`]{#command-delete} : The following are the available options for the `-delete` command: - \[`-alias` *alias*\]: Alias name of the entry to process @@ -1101,7 +1101,7 @@ perform. keystore. When not provided at the command line, the user is prompted for the `alias`. -`-changealias` +[`-changealias`]{#command-changealias} : The following are the available options for the `-changealias` command: - {`-alias` *alias*}: Alias name of the entry to process @@ -1143,7 +1143,7 @@ perform. ## Commands for Displaying Security-related Information -`-showinfo` +[`-showinfo`]{#command-showinfo} : The following are the available options for the `-showinfo` command: - {`-tls`}: Displays TLS configuration information @@ -1185,10 +1185,10 @@ environment or memory usage. For a list of possible interpreter options, enter These options can appear for all commands operating on a keystore: -`-storetype` *storetype* +[`-storetype`]{#option-storetype} *storetype* : This qualifier specifies the type of keystore to be instantiated. -`-keystore` *keystore* +[`-keystore`]{#option-keystore} *keystore* : The keystore location. If the JKS `storetype` is used and a keystore file doesn't yet exist, then @@ -1206,13 +1206,13 @@ These options can appear for all commands operating on a keystore: if the keystore isn't file-based. For example, when the keystore resides on a hardware token device. -`-cacerts` *cacerts* +[`-cacerts`]{#option-cacerts} *cacerts* : Operates on the *cacerts* keystore . This option is equivalent to `-keystore` *path\_to\_cacerts* `-storetype` *type\_of\_cacerts*. An error is reported if the `-keystore` or `-storetype` option is used with the `-cacerts` option. -`-storepass` \[`:env` \| `:file` \] *argument* +[`-storepass`]{#option-storepass} \[`:env` \| `:file` \] *argument* : The password that is used to protect the integrity of the keystore. If the modifier `env` or `file` isn't specified, then the password has the @@ -1237,22 +1237,22 @@ These options can appear for all commands operating on a keystore: a password is not specified, then the integrity of the retrieved information can't be verified and a warning is displayed. -`-providername` *name* +[`-providername`]{#option-providername} *name* : Used to identify a cryptographic service provider's name when listed in the security properties file. -`-addprovider` *name* +[`-addprovider`]{#option-addprovider} *name* : Used to add a security provider by name (such as SunPKCS11) . -`-providerclass` *class* +[`-providerclass`]{#option-providerclass} *class* : Used to specify the name of a cryptographic service provider's master class file when the service provider isn't listed in the security properties file. -`-providerpath` *list* +[`-providerpath`]{#option-providerpath} *list* : Used to specify the provider classpath. -`-providerarg` *arg* +[`-providerarg`]{#option-providerarg} *arg* : Used with the `-addprovider` or `-providerclass` option to represent an optional string input argument for the constructor of *class* name. @@ -1263,7 +1263,7 @@ These options can appear for all commands operating on a keystore: following two options, `-srcprotected` and `-destprotected`, are provided for the source keystore and the destination keystore respectively. -`-ext` {*name*{`:critical`} {`=`*value*}} +[`-ext`]{#option-ext} {*name*{`:critical`} {`=`*value*}} : Denotes an X.509 certificate extension. The option can be used in `-genkeypair` and `-gencert` to embed extensions into the generated certificate, or in `-certreq` to show what extensions are requested in the @@ -1276,7 +1276,7 @@ These options can appear for all commands operating on a keystore: `isCritical` attribute is `true`; otherwise, it is `false`. You can use `:c` in place of `:critical`. -`-conf` *file* +[`-conf`]{#option-conf} *file* : Specifies a pre-configured options file. ## Pre-configured options file diff --git a/src/java.base/share/native/libjava/Thread.c b/src/java.base/share/native/libjava/Thread.c index 4ac30638bc2..15e9614ae73 100644 --- a/src/java.base/share/native/libjava/Thread.c +++ b/src/java.base/share/native/libjava/Thread.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,7 @@ static JNINativeMethod methods[] = { {"holdsLock", "(" OBJ ")Z", (void *)&JVM_HoldsLock}, {"getThreads", "()[" THD, (void *)&JVM_GetAllThreads}, {"dumpThreads", "([" THD ")[[" STE, (void *)&JVM_DumpThreads}, - {"getStackTrace0", "()" OBJ, (void *)&JVM_GetStackTrace}, + {"getStackTrace0", "()[" STE, (void *)&JVM_GetStackTrace}, {"setNativeName", "(" STR ")V", (void *)&JVM_SetNativeThreadName}, {"scopedValueCache", "()[" OBJ, (void *)&JVM_ScopedValueCache}, {"setScopedValueCache", "([" OBJ ")V",(void *)&JVM_SetScopedValueCache}, diff --git a/src/java.base/share/native/libjimage/endian.cpp b/src/java.base/share/native/libjimage/endian.cpp index 5e13ffba34e..73d8aefe086 100644 --- a/src/java.base/share/native/libjimage/endian.cpp +++ b/src/java.base/share/native/libjimage/endian.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -104,6 +104,3 @@ void Endian::set_java(u1* p, u2 x) { p[1] = x & 0xff; } -Endian* Endian::get_native_handler() { - return NativeEndian::get_native(); -} diff --git a/src/java.base/share/native/libjimage/endian.hpp b/src/java.base/share/native/libjimage/endian.hpp index 42fbbb0e853..38e566b7524 100644 --- a/src/java.base/share/native/libjimage/endian.hpp +++ b/src/java.base/share/native/libjimage/endian.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -74,9 +74,6 @@ public: // Select an appropriate endian handler. static Endian* get_handler(bool big_endian); - // Return the native endian handler. - static Endian* get_native_handler(); - // get platform u2 from Java Big endian static u2 get_java(u1* x); // set platform u2 to Java Big endian diff --git a/src/java.base/share/native/libjimage/imageDecompressor.cpp b/src/java.base/share/native/libjimage/imageDecompressor.cpp index 748bbf8203f..4946e645c55 100644 --- a/src/java.base/share/native/libjimage/imageDecompressor.cpp +++ b/src/java.base/share/native/libjimage/imageDecompressor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -85,10 +85,6 @@ void ImageDecompressor::image_decompressor_init() { } } -void ImageDecompressor::image_decompressor_close() { - delete[] _decompressors; -} - /* * Locate decompressor. */ diff --git a/src/java.base/share/native/libjimage/imageDecompressor.hpp b/src/java.base/share/native/libjimage/imageDecompressor.hpp index 16f354935c3..709e1a3bb21 100644 --- a/src/java.base/share/native/libjimage/imageDecompressor.hpp +++ b/src/java.base/share/native/libjimage/imageDecompressor.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -105,12 +105,12 @@ private: protected: ImageDecompressor(const char* name) : _name(name) { } + virtual void decompress_resource(u1* data, u1* uncompressed, ResourceHeader* header, const ImageStrings* strings) = 0; public: static void image_decompressor_init(); - static void image_decompressor_close(); static ImageDecompressor* get_decompressor(const char * decompressor_name) ; static void decompress_resource(u1* compressed, u1* uncompressed, u8 uncompressed_size, const ImageStrings* strings, Endian* _endian); @@ -166,6 +166,6 @@ private: public: SharedStringDecompressor(const char* sym) : ImageDecompressor(sym){} void decompress_resource(u1* data, u1* uncompressed, ResourceHeader* header, - const ImageStrings* strings); + const ImageStrings* strings); }; #endif // LIBJIMAGE_IMAGEDECOMPRESSOR_HPP diff --git a/src/java.base/share/native/libjimage/imageFile.cpp b/src/java.base/share/native/libjimage/imageFile.cpp index d97a8f95a60..e2479ba2c9e 100644 --- a/src/java.base/share/native/libjimage/imageFile.cpp +++ b/src/java.base/share/native/libjimage/imageFile.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -180,16 +180,6 @@ void ImageFileReaderTable::remove(ImageFileReader* image) { } } -// Determine if image entry is in table. -bool ImageFileReaderTable::contains(ImageFileReader* image) { - for (u4 i = 0; i < _count; i++) { - if (_table[i] == image) { - return true; - } - } - return false; -} - // Table to manage multiple opens of an image file. ImageFileReaderTable ImageFileReader::_reader_table; @@ -261,25 +251,6 @@ void ImageFileReader::close(ImageFileReader *reader) { } } -// Return an id for the specified ImageFileReader. -u8 ImageFileReader::reader_to_ID(ImageFileReader *reader) { - // ID is just the cloaked reader address. - return (u8)reader; -} - -// Validate the image id. -bool ImageFileReader::id_check(u8 id) { - // Make sure the ID is a managed (_reader_table) reader. - SimpleCriticalSectionLock cs(&_reader_table_lock); - return _reader_table.contains((ImageFileReader*)id); -} - -// Return an id for the specified ImageFileReader. -ImageFileReader* ImageFileReader::id_to_reader(u8 id) { - assert(id_check(id) && "invalid image id"); - return (ImageFileReader*)id; -} - // Constructor initializes to a closed state. ImageFileReader::ImageFileReader(const char* name, bool big_endian) { // Copy the image file name. @@ -372,23 +343,6 @@ bool ImageFileReader::read_at(u1* data, u8 size, u8 offset) const { return (u8)osSupport::read(_fd, (char*)data, size, offset) == size; } -// Find the location attributes associated with the path. Returns true if -// the location is found, false otherwise. -bool ImageFileReader::find_location(const char* path, ImageLocation& location) const { - // Locate the entry in the index perfect hash table. - s4 index = ImageStrings::find(_endian, path, _redirect_table, table_length()); - // If is found. - if (index != ImageStrings::NOT_FOUND) { - // Get address of first byte of location attribute stream. - u1* data = get_location_data(index); - // Expand location attributes. - location.set_data(data); - // Make sure result is not a false positive. - return verify_location(location, path); - } - return false; -} - // Find the location index and size associated with the path. // Returns the location index and size if the location is found, 0 otherwise. u4 ImageFileReader::find_location_index(const char* path, u8 *size) const { diff --git a/src/java.base/share/native/libjimage/imageFile.hpp b/src/java.base/share/native/libjimage/imageFile.hpp index 5fb4ea3baaa..a4c8d159efa 100644 --- a/src/java.base/share/native/libjimage/imageFile.hpp +++ b/src/java.base/share/native/libjimage/imageFile.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -375,9 +375,6 @@ public: // Remove an image entry from the table. void remove(ImageFileReader* image); - - // Determine if image entry is in table. - bool contains(ImageFileReader* image); }; // Manage the image file. @@ -445,15 +442,6 @@ public: // Close an image file if the file is not in use elsewhere. static void close(ImageFileReader *reader); - // Return an id for the specified ImageFileReader. - static u8 reader_to_ID(ImageFileReader *reader); - - // Validate the image id. - static bool id_check(u8 id); - - // Return an id for the specified ImageFileReader. - static ImageFileReader* id_to_reader(u8 id); - // Open image file for read access. bool open(); @@ -545,10 +533,6 @@ public: return _endian->get(_offsets_table[index]); } - // Find the location attributes associated with the path. Returns true if - // the location is found, false otherwise. - bool find_location(const char* path, ImageLocation& location) const; - // Find the location index and size associated with the path. // Returns the location index and size if the location is found, // ImageFileReader::NOT_FOUND otherwise. diff --git a/src/java.base/unix/classes/sun/nio/ch/NativeThread.java b/src/java.base/unix/classes/sun/nio/ch/NativeThread.java index 8d0bcea48d9..75cf36d6d52 100644 --- a/src/java.base/unix/classes/sun/nio/ch/NativeThread.java +++ b/src/java.base/unix/classes/sun/nio/ch/NativeThread.java @@ -25,6 +25,9 @@ package sun.nio.ch; +import java.util.concurrent.locks.LockSupport; +import jdk.internal.access.JavaLangAccess; +import jdk.internal.access.SharedSecrets; // Signalling operations on native threads // @@ -37,45 +40,38 @@ package sun.nio.ch; // always returns -1 and the signal(long) method has no effect. public class NativeThread { - private static final long VIRTUAL_THREAD_ID = -1L; + private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); + + private NativeThread() { } /** - * Returns the id of the current native thread if the platform can signal - * native threads, 0 if the platform can not signal native threads, or - * -1L if the current thread is a virtual thread. - */ - public static long current() { - if (Thread.currentThread().isVirtual()) { - return VIRTUAL_THREAD_ID; - } else { - return current0(); - } - } - - /** - * Signals the given native thread. + * Returns the Thread to signal the current thread. * - * @throws IllegalArgumentException if tid is not a token to a native thread + * The first use of this method on a platform thread will capture the thread's + * native thread ID. */ - public static void signal(long tid) { - if (tid == 0 || tid == VIRTUAL_THREAD_ID) - throw new IllegalArgumentException(); - signal0(tid); + public static Thread threadToSignal() { + Thread t = Thread.currentThread(); + if (!t.isVirtual() && JLA.nativeThreadID(t) == 0) { + JLA.setThreadNativeID(current0()); + } + return t; } /** - * Returns true the tid is the id of a native thread. + * Signals the given thread. For a platform thread it sends a signal to the thread. + * For a virtual thread it just unparks it. + * @throws IllegalStateException if the thread is a platform thread that hasn't set its native ID */ - static boolean isNativeThread(long tid) { - return (tid != 0 && tid != VIRTUAL_THREAD_ID); - } - - /** - * Returns true if tid is -1L. - * @see #current() - */ - static boolean isVirtualThread(long tid) { - return (tid == VIRTUAL_THREAD_ID); + public static void signal(Thread thread) { + if (thread.isVirtual()) { + LockSupport.unpark(thread); + } else { + long id = JLA.nativeThreadID(thread); + if (id == 0) + throw new IllegalStateException("Native thread ID not set"); + signal0(id); + } } /** diff --git a/src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java b/src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java index b073c287bfb..09d280b370c 100644 --- a/src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java +++ b/src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java @@ -63,8 +63,8 @@ class SinkChannelImpl private static final int ST_CLOSED = 2; private int state; - // ID of native thread doing write, for signalling - private long thread; + // Thread doing write, for signalling + private Thread writerThread; // True if the channel's socket has been forced into non-blocking mode // by a virtual thread. It cannot be reset. When the channel is in @@ -120,7 +120,7 @@ class SinkChannelImpl */ private boolean tryClose() throws IOException { assert Thread.holdsLock(stateLock) && state == ST_CLOSING; - if (thread == 0 && !isRegistered()) { + if (writerThread == null && !isRegistered()) { state = ST_CLOSED; nd.close(fd); return true; @@ -152,7 +152,7 @@ class SinkChannelImpl assert state < ST_CLOSING; state = ST_CLOSING; if (!tryClose()) { - nd.preClose(fd, thread, 0); + nd.preClose(fd, null, writerThread); } } } @@ -270,7 +270,7 @@ class SinkChannelImpl synchronized (stateLock) { ensureOpen(); if (blocking) - thread = NativeThread.current(); + writerThread = NativeThread.threadToSignal(); } } @@ -285,7 +285,7 @@ class SinkChannelImpl { if (blocking) { synchronized (stateLock) { - thread = 0; + writerThread = null; if (state == ST_CLOSING) { tryFinishClose(); } diff --git a/src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java b/src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java index 571d7f483d2..52188c12b17 100644 --- a/src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java +++ b/src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java @@ -63,8 +63,8 @@ class SourceChannelImpl private static final int ST_CLOSED = 2; private int state; - // ID of native thread doing read, for signalling - private long thread; + // Thread doing read, for signalling + private Thread readerThread; // True if the channel's socket has been forced into non-blocking mode // by a virtual thread. It cannot be reset. When the channel is in @@ -120,7 +120,7 @@ class SourceChannelImpl */ private boolean tryClose() throws IOException { assert Thread.holdsLock(stateLock) && state == ST_CLOSING; - if (thread == 0 && !isRegistered()) { + if (readerThread == null && !isRegistered()) { state = ST_CLOSED; nd.close(fd); return true; @@ -152,7 +152,7 @@ class SourceChannelImpl assert state < ST_CLOSING; state = ST_CLOSING; if (!tryClose()) { - nd.preClose(fd, thread, 0); + nd.preClose(fd, readerThread, null); } } } @@ -269,8 +269,9 @@ class SourceChannelImpl } synchronized (stateLock) { ensureOpen(); - if (blocking) - thread = NativeThread.current(); + if (blocking) { + readerThread = NativeThread.threadToSignal(); + } } } @@ -285,7 +286,7 @@ class SourceChannelImpl { if (blocking) { synchronized (stateLock) { - thread = 0; + readerThread = null; if (state == ST_CLOSING) { tryFinishClose(); } diff --git a/src/java.base/unix/classes/sun/nio/ch/UnixDispatcher.java b/src/java.base/unix/classes/sun/nio/ch/UnixDispatcher.java index 4cdd0c400ec..3656b172822 100644 --- a/src/java.base/unix/classes/sun/nio/ch/UnixDispatcher.java +++ b/src/java.base/unix/classes/sun/nio/ch/UnixDispatcher.java @@ -36,15 +36,17 @@ abstract class UnixDispatcher extends NativeDispatcher { close0(fd); } - private void signalThreads(long reader, long writer) { - if (NativeThread.isNativeThread(reader)) + private void signalThreads(Thread reader, Thread writer) { + if (reader != null) { NativeThread.signal(reader); - if (NativeThread.isNativeThread(writer)) + } + if (writer != null) { NativeThread.signal(writer); + } } @Override - void implPreClose(FileDescriptor fd, long reader, long writer) throws IOException { + void implPreClose(FileDescriptor fd, Thread reader, Thread writer) throws IOException { if (SUPPORTS_PENDING_SIGNALS) { signalThreads(reader, writer); } diff --git a/src/java.base/unix/native/libnet/Inet4AddressImpl.c b/src/java.base/unix/native/libnet/Inet4AddressImpl.c index 9bddbcaede7..e99dfd89411 100644 --- a/src/java.base/unix/native/libnet/Inet4AddressImpl.c +++ b/src/java.base/unix/native/libnet/Inet4AddressImpl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -112,6 +112,8 @@ Java_java_net_Inet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this, error == EAI_SYSTEM && errno == EINTR); if (error) { + // capture the errno from getaddrinfo + const int sys_errno = errno; #if defined(MACOSX) // If getaddrinfo fails try getifaddrs, see bug 8170910. // java_net_spi_InetAddressResolver_LookupPolicy_IPV4_FIRST and no ordering is ok @@ -122,7 +124,7 @@ Java_java_net_Inet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this, } #endif // report error - NET_ThrowUnknownHostExceptionWithGaiError(env, hostname, error); + NET_ThrowUnknownHostExceptionWithGaiError(env, hostname, error, sys_errno); goto cleanupAndReturn; } else { int i = 0; diff --git a/src/java.base/unix/native/libnet/Inet6AddressImpl.c b/src/java.base/unix/native/libnet/Inet6AddressImpl.c index 8dce4f9cc6b..e0963c8dc3e 100644 --- a/src/java.base/unix/native/libnet/Inet6AddressImpl.c +++ b/src/java.base/unix/native/libnet/Inet6AddressImpl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -231,6 +231,8 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this, error == EAI_SYSTEM && errno == EINTR); if (error) { + // capture the errno from getaddrinfo + const int sys_errno = errno; #if defined(MACOSX) // if getaddrinfo fails try getifaddrs ret = lookupIfLocalhost(env, hostname, JNI_TRUE, characteristics); @@ -239,7 +241,7 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this, } #endif // report error - NET_ThrowUnknownHostExceptionWithGaiError(env, hostname, error); + NET_ThrowUnknownHostExceptionWithGaiError(env, hostname, error, sys_errno); goto cleanupAndReturn; } else { int i = 0, inetCount = 0, inet6Count = 0, inetIndex = 0, diff --git a/src/java.base/unix/native/libnet/net_util_md.c b/src/java.base/unix/native/libnet/net_util_md.c index 1496be5f5c6..f7b690f1032 100644 --- a/src/java.base/unix/native/libnet/net_util_md.c +++ b/src/java.base/unix/native/libnet/net_util_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * 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,13 +68,14 @@ NET_ThrowByNameWithLastError(JNIEnv *env, const char *name, void NET_ThrowNew(JNIEnv *env, int errorNumber, char *msg) { char fullMsg[512]; - if (!msg) { - msg = "no further information"; - } switch(errorNumber) { case EBADF: - jio_snprintf(fullMsg, sizeof(fullMsg), "socket closed: %s", msg); - JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", fullMsg); + if (msg == NULL) { + JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed"); + } else { + jio_snprintf(fullMsg, sizeof(fullMsg), "socket closed: %s", msg); + JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", fullMsg); + } break; default: errno = errorNumber; @@ -177,13 +178,21 @@ jint reuseport_supported(int ipv6_available) void NET_ThrowUnknownHostExceptionWithGaiError(JNIEnv *env, const char* hostname, - int gai_error) + int gai_error, + int sys_errno) { int size; char *buf; + const char *sys_errno_string = NULL; const char *error_string = gai_strerror(gai_error); - if (error_string == NULL) + if (error_string == NULL) { error_string = "unknown error"; + } + if (gai_error == EAI_SYSTEM) { + // EAI_SYSTEM implies that the actual error is stored in the system errno. + // Here we get the string representation of that errno. + sys_errno_string = strerror(sys_errno); + } int enhancedExceptions = getEnhancedExceptionsAllowed(env); if (enhancedExceptions == ENH_INIT_ERROR && (*env)->ExceptionCheck(env)) { return; @@ -194,16 +203,33 @@ void NET_ThrowUnknownHostExceptionWithGaiError(JNIEnv *env, } else { size = 0; } - size += strlen(error_string) + 3; - + if (sys_errno_string == NULL) { + // the 3 is for the additional 3 characters - colon, space and + // the NULL termination character, that we will include in the + // message of the Exception that we construct + size += strlen(error_string) + 3; + } else { + // the 5 is for the additional 5 characters - 2 colons, 2 spaces and + // the NULL termination character, that we will include in the + // message of the Exception that we construct + size += strlen(error_string) + strlen(sys_errno_string) + 5; + } buf = (char *) malloc(size); if (buf) { jstring s; int n; if (enhancedExceptions == ENH_ENABLED) { - n = snprintf(buf, size, "%s: %s", hostname, error_string); + if (sys_errno_string == NULL) { + n = snprintf(buf, size, "%s: %s", hostname, error_string); + } else { + n = snprintf(buf, size, "%s: %s: %s", hostname, error_string, sys_errno_string); + } } else { - n = snprintf(buf, size, " %s", error_string); + if (sys_errno_string == NULL) { + n = snprintf(buf, size, " %s", error_string); + } else { + n = snprintf(buf, size, " %s: %s", error_string, sys_errno_string); + } } if (n >= 0) { s = JNU_NewStringPlatform(env, buf); diff --git a/src/java.base/unix/native/libnet/net_util_md.h b/src/java.base/unix/native/libnet/net_util_md.h index dca6e97755a..639cf00515f 100644 --- a/src/java.base/unix/native/libnet/net_util_md.h +++ b/src/java.base/unix/native/libnet/net_util_md.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 +76,8 @@ typedef union { */ void NET_ThrowUnknownHostExceptionWithGaiError(JNIEnv *env, const char* hostname, - int gai_error); + int gai_error, + int sys_errno); void NET_ThrowByNameWithLastError(JNIEnv *env, const char *name, const char *defaultDetail); diff --git a/src/java.base/unix/native/libnio/ch/IOUtil.c b/src/java.base/unix/native/libnio/ch/IOUtil.c index dfa99658fa6..3a7693b2ee0 100644 --- a/src/java.base/unix/native/libnio/ch/IOUtil.c +++ b/src/java.base/unix/native/libnio/ch/IOUtil.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -77,10 +77,9 @@ configureBlocking(int fd, jboolean blocking) } JNIEXPORT void JNICALL -Java_sun_nio_ch_IOUtil_configureBlocking(JNIEnv *env, jclass clazz, - jobject fdo, jboolean blocking) +Java_sun_nio_ch_IOUtil_configureBlocking(JNIEnv *env, jclass clazz, jint fd, jboolean blocking) { - if (configureBlocking(fdval(env, fdo), blocking) < 0) + if (configureBlocking(fd, blocking) < 0) JNU_ThrowIOExceptionWithLastError(env, "Configure blocking failed"); } diff --git a/src/java.base/windows/classes/sun/nio/ch/DefaultPollerProvider.java b/src/java.base/windows/classes/sun/nio/ch/DefaultPollerProvider.java index abd2f34a229..d1af62fbd73 100644 --- a/src/java.base/windows/classes/sun/nio/ch/DefaultPollerProvider.java +++ b/src/java.base/windows/classes/sun/nio/ch/DefaultPollerProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,11 +30,19 @@ import java.io.IOException; * Default PollerProvider for Windows based on wepoll. */ class DefaultPollerProvider extends PollerProvider { - DefaultPollerProvider() { } + DefaultPollerProvider(Poller.Mode mode) { + if (mode != Poller.Mode.SYSTEM_THREADS) { + throw new UnsupportedOperationException(); + } + super(mode); + } + + DefaultPollerProvider() { + this(Poller.Mode.SYSTEM_THREADS); + } @Override - int defaultReadPollers(Poller.Mode mode) { - assert mode == Poller.Mode.SYSTEM_THREADS; + int defaultReadPollers() { int ncpus = Runtime.getRuntime().availableProcessors(); return Math.max(Integer.highestOneBit(ncpus / 8), 1); } @@ -46,13 +54,15 @@ class DefaultPollerProvider extends PollerProvider { @Override Poller readPoller(boolean subPoller) throws IOException { - assert !subPoller; + if (subPoller) + throw new UnsupportedOperationException(); return new WEPollPoller(true); } @Override Poller writePoller(boolean subPoller) throws IOException { - assert !subPoller; + if (subPoller) + throw new UnsupportedOperationException(); return new WEPollPoller(false); } } diff --git a/src/java.base/windows/classes/sun/nio/ch/NativeThread.java b/src/java.base/windows/classes/sun/nio/ch/NativeThread.java index 1870c95494f..28d8c6303d9 100644 --- a/src/java.base/windows/classes/sun/nio/ch/NativeThread.java +++ b/src/java.base/windows/classes/sun/nio/ch/NativeThread.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,47 +25,29 @@ package sun.nio.ch; - -// Signalling operations on native threads +import java.util.concurrent.locks.LockSupport; public class NativeThread { - private static final long VIRTUAL_THREAD_ID = -1L; + private NativeThread() { } /** - * Returns the id of the current native thread if the platform can signal - * native threads, 0 if the platform can not signal native threads, or - * -1L if the current thread is a virtual thread. + * Returns the Thread to signal the current thread or {@code null} if the current + * thread cannot be signalled. */ - public static long current() { - if (Thread.currentThread().isVirtual()) { - return VIRTUAL_THREAD_ID; + public static Thread threadToSignal() { + Thread thread = Thread.currentThread(); + return thread.isVirtual() ? thread : null; + } + + /** + * Signals the given thread. + * @throws UnsupportedOperationException is not supported + */ + public static void signal(Thread thread) { + if (thread.isVirtual()) { + LockSupport.unpark(thread); } else { - // no support for signalling threads on Windows - return 0; + throw new UnsupportedOperationException(); } } - - /** - * Signals the given native thread. - * - * @throws IllegalArgumentException if tid is not a token to a native thread - */ - static void signal(long tid) { - throw new UnsupportedOperationException(); - } - - /** - * Returns true the tid is the id of a native thread. - */ - static boolean isNativeThread(long tid) { - return false; - } - - /** - * Returns true if tid is -1L. - * @see #current() - */ - static boolean isVirtualThread(long tid) { - return (tid == VIRTUAL_THREAD_ID); - } } diff --git a/src/java.base/windows/classes/sun/nio/ch/WEPollPoller.java b/src/java.base/windows/classes/sun/nio/ch/WEPollPoller.java index 3db8d67acc6..9f575072f22 100644 --- a/src/java.base/windows/classes/sun/nio/ch/WEPollPoller.java +++ b/src/java.base/windows/classes/sun/nio/ch/WEPollPoller.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,27 +32,41 @@ import static sun.nio.ch.WEPoll.*; */ class WEPollPoller extends Poller { private static final int MAX_EVENTS_TO_POLL = 256; - private static final int ENOENT = 2; private final long handle; private final int event; private final long address; WEPollPoller(boolean read) throws IOException { - this.handle = WEPoll.create(); + long handle = WEPoll.create(); + long address; + try { + address = WEPoll.allocatePollArray(MAX_EVENTS_TO_POLL); + } catch (Throwable e) { + WEPoll.close(handle); + throw e; + } + this.event = (read) ? EPOLLIN : EPOLLOUT; - this.address = WEPoll.allocatePollArray(MAX_EVENTS_TO_POLL); + this.handle = handle; + this.address = address; } @Override - void implRegister(int fdVal) throws IOException { + void close() { + WEPoll.close(handle); + WEPoll.freePollArray(address); + } + + @Override + void implStartPoll(int fdVal) throws IOException { int err = WEPoll.ctl(handle, EPOLL_CTL_ADD, fdVal, (event | EPOLLONESHOT)); if (err != 0) throw new IOException("epoll_ctl failed: " + err); } @Override - void implDeregister(int fdVal, boolean polled) { + void implStopPoll(int fdVal, boolean polled) { WEPoll.ctl(handle, EPOLL_CTL_DEL, fdVal, 0); } diff --git a/src/java.base/windows/native/libnet/net_util_md.c b/src/java.base/windows/native/libnet/net_util_md.c index bac3d1438ab..5abdd8d4c2e 100644 --- a/src/java.base/windows/native/libnet/net_util_md.c +++ b/src/java.base/windows/native/libnet/net_util_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -139,13 +139,6 @@ NET_ThrowNew(JNIEnv *env, int errorNum, char *msg) return; } - /* - * Default message text if not provided - */ - if (!msg) { - msg = "no further information"; - } - /* * Check table for known winsock errors */ @@ -163,13 +156,22 @@ NET_ThrowNew(JNIEnv *env, int errorNum, char *msg) */ if (i < table_size) { excP = (char *)winsock_errors[i].exc; - jio_snprintf(fullMsg, sizeof(fullMsg), "%s: %s", - (char *)winsock_errors[i].errString, msg); + if (msg == NULL) { + jio_snprintf(fullMsg, sizeof(fullMsg), "%s", + (char *)winsock_errors[i].errString); + } else { + jio_snprintf(fullMsg, sizeof(fullMsg), "%s: %s", + (char *)winsock_errors[i].errString, msg); + } } else { - jio_snprintf(fullMsg, sizeof(fullMsg), - "Unrecognized Windows Sockets error: %d: %s", - errorNum, msg); - + if (msg == NULL) { + jio_snprintf(fullMsg, sizeof(fullMsg), + "Unrecognized Windows Sockets error: %d", errorNum); + } else { + jio_snprintf(fullMsg, sizeof(fullMsg), + "Unrecognized Windows Sockets error: %d: %s", + errorNum, msg); + } } /* diff --git a/src/java.base/windows/native/libnio/ch/IOUtil.c b/src/java.base/windows/native/libnio/ch/IOUtil.c index 850c237d9e9..a6b81b7afec 100644 --- a/src/java.base/windows/native/libnio/ch/IOUtil.c +++ b/src/java.base/windows/native/libnio/ch/IOUtil.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -134,11 +134,10 @@ Java_sun_nio_ch_IOUtil_setfdVal(JNIEnv *env, jclass clazz, jobject fdo, jint val JNIEXPORT void JNICALL Java_sun_nio_ch_IOUtil_configureBlocking(JNIEnv *env, jclass clazz, - jobject fdo, jboolean blocking) + jint fd, jboolean blocking) { u_long argp; int result = 0; - jint fd = fdval(env, fdo); if (blocking == JNI_FALSE) { argp = SET_NONBLOCKING; diff --git a/src/java.base/windows/native/libnio/ch/Net.c b/src/java.base/windows/native/libnio/ch/Net.c index 814f502c48a..adfd67b5017 100644 --- a/src/java.base/windows/native/libnio/ch/Net.c +++ b/src/java.base/windows/native/libnio/ch/Net.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -733,7 +733,7 @@ Java_sun_nio_ch_Net_pollConnect(JNIEnv* env, jclass this, jobject fdo, jlong tim NET_ThrowNew(env, lastError, "getsockopt"); } } else if (optError != NO_ERROR) { - NET_ThrowNew(env, optError, "getsockopt"); + NET_ThrowNew(env, optError, NULL); } return JNI_FALSE; } diff --git a/src/java.desktop/share/classes/com/sun/java/swing/SwingUtilities3.java b/src/java.desktop/share/classes/com/sun/java/swing/SwingUtilities3.java index 552ef870dbe..e4746d13dd9 100644 --- a/src/java.desktop/share/classes/com/sun/java/swing/SwingUtilities3.java +++ b/src/java.desktop/share/classes/com/sun/java/swing/SwingUtilities3.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,6 @@ import javax.swing.JComponent; import javax.swing.JMenu; import javax.swing.RepaintManager; -import sun.awt.AppContext; import sun.awt.SunToolkit; import sun.swing.MenuItemLayoutHelper; import sun.swing.SwingUtilities2; @@ -69,16 +68,17 @@ public class SwingUtilities3 { private static final Object DELEGATE_REPAINT_MANAGER_KEY = new StringBuilder("DelegateRepaintManagerKey"); + private static volatile boolean repaintDelegateSet; + /** * Registers delegate RepaintManager for {@code JComponent}. */ public static void setDelegateRepaintManager(JComponent component, RepaintManager repaintManager) { - /* setting up flag in AppContext to speed up lookups in case + /* setting up flag to speed up lookups in case * there are no delegate RepaintManagers used. */ - AppContext.getAppContext().put(DELEGATE_REPAINT_MANAGER_KEY, - Boolean.TRUE); + repaintDelegateSet = true; component.putClientProperty(DELEGATE_REPAINT_MANAGER_KEY, repaintManager); @@ -126,8 +126,7 @@ public class SwingUtilities3 { public static RepaintManager getDelegateRepaintManager(Component component) { RepaintManager delegate = null; - if (Boolean.TRUE == SunToolkit.targetToAppContext(component) - .get(DELEGATE_REPAINT_MANAGER_KEY)) { + if (repaintDelegateSet) { while (delegate == null && component != null) { while (component != null && ! (component instanceof JComponent)) { diff --git a/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java b/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java index 24a1997bdc1..5145779a493 100644 --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java +++ b/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java @@ -1421,6 +1421,8 @@ public class GTKLookAndFeel extends SynthLookAndFeel { return c.getComponentOrientation().isLeftToRight(); } + private native boolean applyThemeIfNeeded(); + /** * {@inheritDoc} */ @@ -1463,6 +1465,21 @@ public class GTKLookAndFeel extends SynthLookAndFeel { // By default mnemonics are hidden for GTK L&F MnemonicHandler.setMnemonicHidden(true); + + if (IS_3) { + boolean shouldApplyTheme = false; + if (toolkit instanceof UNIXToolkit unixToolkit) { + if ("gnome".equals(unixToolkit.getDesktop())) { + int gnomeShellVersion = unixToolkit.getGnomeShellMajorVersion(); + shouldApplyTheme = gnomeShellVersion >= 47; + } + } + + if (shouldApplyTheme && applyThemeIfNeeded()) { + GTKEngine.INSTANCE.themeChanged(); + GTKIconFactory.resetIcons(); + } + } } /** diff --git a/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKStyle.java b/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKStyle.java index baeb249eaa8..76d7abdbce6 100644 --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKStyle.java +++ b/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKStyle.java @@ -32,7 +32,6 @@ import javax.swing.*; import javax.swing.plaf.*; import javax.swing.plaf.synth.*; -import sun.awt.AppContext; import sun.awt.UNIXToolkit; import sun.swing.SwingUtilities2; import javax.swing.plaf.synth.SynthIcon; @@ -961,11 +960,11 @@ class GTKStyle extends SynthStyle implements GTKConstants { static class GTKStockIconInfo { private static Map ICON_TYPE_MAP; - private static final Object ICON_SIZE_KEY = new StringBuffer("IconSize"); + + private static Dimension[] iconSizesMap; private static Dimension[] getIconSizesMap() { - AppContext appContext = AppContext.getAppContext(); - Dimension[] iconSizes = (Dimension[])appContext.get(ICON_SIZE_KEY); + Dimension[] iconSizes = iconSizesMap; if (iconSizes == null) { iconSizes = new Dimension[7]; @@ -976,7 +975,7 @@ class GTKStyle extends SynthStyle implements GTKConstants { iconSizes[4] = new Dimension(20, 20); // GTK_ICON_SIZE_BUTTON iconSizes[5] = new Dimension(32, 32); // GTK_ICON_SIZE_DND iconSizes[6] = new Dimension(48, 48); // GTK_ICON_SIZE_DIALOG - appContext.put(ICON_SIZE_KEY, iconSizes); + iconSizesMap = iconSizes; } return iconSizes; } diff --git a/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifButtonUI.java b/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifButtonUI.java index 0e4c2e526ac..7a11e4a47e9 100644 --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifButtonUI.java +++ b/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifButtonUI.java @@ -42,8 +42,6 @@ import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicButtonListener; import javax.swing.plaf.basic.BasicButtonUI; -import sun.awt.AppContext; - /** * MotifButton implementation * @@ -55,20 +53,13 @@ public class MotifButtonUI extends BasicButtonUI { private boolean defaults_initialized = false; - private static final Object MOTIF_BUTTON_UI_KEY = new Object(); + private static final ComponentUI UI = new MotifButtonUI(); // ******************************** // Create PLAF // ******************************** public static ComponentUI createUI(JComponent c) { - AppContext appContext = AppContext.getAppContext(); - MotifButtonUI motifButtonUI = - (MotifButtonUI) appContext.get(MOTIF_BUTTON_UI_KEY); - if (motifButtonUI == null) { - motifButtonUI = new MotifButtonUI(); - appContext.put(MOTIF_BUTTON_UI_KEY, motifButtonUI); - } - return motifButtonUI; + return UI; } // ******************************** diff --git a/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifCheckBoxUI.java b/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifCheckBoxUI.java index 9e9f0008b07..7017eaf546c 100644 --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifCheckBoxUI.java +++ b/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifCheckBoxUI.java @@ -30,8 +30,6 @@ import javax.swing.JComponent; import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; -import sun.awt.AppContext; - /** * MotifCheckBox implementation * @@ -39,7 +37,7 @@ import sun.awt.AppContext; */ public class MotifCheckBoxUI extends MotifRadioButtonUI { - private static final Object MOTIF_CHECK_BOX_UI_KEY = new Object(); + private static final ComponentUI UI = new MotifCheckBoxUI(); private static final String propertyPrefix = "CheckBox" + "."; @@ -50,14 +48,7 @@ public class MotifCheckBoxUI extends MotifRadioButtonUI { // Create PLAF // ******************************** public static ComponentUI createUI(JComponent c) { - AppContext appContext = AppContext.getAppContext(); - MotifCheckBoxUI motifCheckBoxUI = - (MotifCheckBoxUI) appContext.get(MOTIF_CHECK_BOX_UI_KEY); - if (motifCheckBoxUI == null) { - motifCheckBoxUI = new MotifCheckBoxUI(); - appContext.put(MOTIF_CHECK_BOX_UI_KEY, motifCheckBoxUI); - } - return motifCheckBoxUI; + return UI; } @Override diff --git a/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifLabelUI.java b/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifLabelUI.java index f19a3c23cb5..89c2e309f9e 100644 --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifLabelUI.java +++ b/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifLabelUI.java @@ -29,8 +29,6 @@ import javax.swing.JComponent; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicLabelUI; -import sun.awt.AppContext; - /** * A Motif {@literal L&F} implementation of LabelUI. * This merely sets up new default values in MotifLookAndFeel. @@ -39,16 +37,9 @@ import sun.awt.AppContext; */ public class MotifLabelUI extends BasicLabelUI { - private static final Object MOTIF_LABEL_UI_KEY = new Object(); + private static final ComponentUI UI = new MotifLabelUI(); public static ComponentUI createUI(JComponent c) { - AppContext appContext = AppContext.getAppContext(); - MotifLabelUI motifLabelUI = - (MotifLabelUI) appContext.get(MOTIF_LABEL_UI_KEY); - if (motifLabelUI == null) { - motifLabelUI = new MotifLabelUI(); - appContext.put(MOTIF_LABEL_UI_KEY, motifLabelUI); - } - return motifLabelUI; + return UI; } } diff --git a/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifToggleButtonUI.java b/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifToggleButtonUI.java index 7997145e648..7956023ed06 100644 --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifToggleButtonUI.java +++ b/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifToggleButtonUI.java @@ -39,8 +39,6 @@ import javax.swing.plaf.ComponentUI; import javax.swing.plaf.UIResource; import javax.swing.plaf.basic.BasicToggleButtonUI; -import sun.awt.AppContext; - /** * BasicToggleButton implementation. * @@ -48,7 +46,7 @@ import sun.awt.AppContext; */ public class MotifToggleButtonUI extends BasicToggleButtonUI { - private static final Object MOTIF_TOGGLE_BUTTON_UI_KEY = new Object(); + private static final ComponentUI UI = new MotifToggleButtonUI(); protected Color selectColor; @@ -58,14 +56,7 @@ public class MotifToggleButtonUI extends BasicToggleButtonUI // Create PLAF // ******************************** public static ComponentUI createUI(JComponent b) { - AppContext appContext = AppContext.getAppContext(); - MotifToggleButtonUI motifToggleButtonUI = - (MotifToggleButtonUI) appContext.get(MOTIF_TOGGLE_BUTTON_UI_KEY); - if (motifToggleButtonUI == null) { - motifToggleButtonUI = new MotifToggleButtonUI(); - appContext.put(MOTIF_TOGGLE_BUTTON_UI_KEY, motifToggleButtonUI); - } - return motifToggleButtonUI; + return UI; } // ******************************** diff --git a/src/java.desktop/share/classes/java/awt/AWTKeyStroke.java b/src/java.desktop/share/classes/java/awt/AWTKeyStroke.java index fee1c9a4e19..395c000617b 100644 --- a/src/java.desktop/share/classes/java/awt/AWTKeyStroke.java +++ b/src/java.desktop/share/classes/java/awt/AWTKeyStroke.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 +36,6 @@ import java.util.HashMap; import java.util.Map; import java.util.StringTokenizer; -import sun.awt.AppContext; import sun.swing.SwingAccessor; /** @@ -80,11 +79,6 @@ public class AWTKeyStroke implements Serializable { */ private static VKCollection vks; - //A key for the collection of AWTKeyStrokes within AppContext. - private static Object APP_CONTEXT_CACHE_KEY = new Object(); - //A key within the cache - private static AWTKeyStroke APP_CONTEXT_KEYSTROKE_KEY = new AWTKeyStroke(); - /** * @serial The character value for a keyboard key. */ @@ -181,21 +175,19 @@ public class AWTKeyStroke implements Serializable { protected static void registerSubclass(Class subclass) { } + private static Map cache; + private static AWTKeyStroke cacheKey; + private static synchronized AWTKeyStroke getCachedStroke (char keyChar, int keyCode, int modifiers, boolean onKeyRelease) { - @SuppressWarnings("unchecked") - Map cache = (Map)AppContext.getAppContext().get(APP_CONTEXT_CACHE_KEY); - AWTKeyStroke cacheKey = (AWTKeyStroke)AppContext.getAppContext().get(APP_CONTEXT_KEYSTROKE_KEY); if (cache == null) { cache = new HashMap<>(); - AppContext.getAppContext().put(APP_CONTEXT_CACHE_KEY, cache); } if (cacheKey == null) { cacheKey = SwingAccessor.getKeyStrokeAccessor().create(); - AppContext.getAppContext().put(APP_CONTEXT_KEYSTROKE_KEY, cacheKey); } cacheKey.keyChar = keyChar; @@ -203,11 +195,16 @@ public class AWTKeyStroke implements Serializable { cacheKey.modifiers = mapNewModifiers(mapOldModifiers(modifiers)); cacheKey.onKeyRelease = onKeyRelease; + /* If there's no hit on the cache, then store this instance in the cache + * and null out the var so it isn't over-written. + * But if there's a hit, store it in cacheKey so it can be re-used + * next time this method is called. + */ AWTKeyStroke stroke = cache.get(cacheKey); if (stroke == null) { stroke = cacheKey; cache.put(stroke, stroke); - AppContext.getAppContext().remove(APP_CONTEXT_KEYSTROKE_KEY); + cacheKey = null; } return stroke; } diff --git a/src/java.desktop/share/classes/java/awt/image/ComponentSampleModel.java b/src/java.desktop/share/classes/java/awt/image/ComponentSampleModel.java index d15a8d214aa..4460b0fc101 100644 --- a/src/java.desktop/share/classes/java/awt/image/ComponentSampleModel.java +++ b/src/java.desktop/share/classes/java/awt/image/ComponentSampleModel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -503,7 +503,11 @@ public class ComponentSampleModel extends SampleModel } /** Returns the number of bits per sample for the specified band. - * @param band the specified band + *

    + * Since all bands of a {@code ComponentSampleModel} are the same + * size, this method ignores the {@code band} parameter and returns + * the size of the first (0th) band. + * @param band the specified band (ignored) * @return the number of bits per sample for the specified band. */ public final int getSampleSize(int band) { diff --git a/src/java.desktop/share/classes/java/awt/image/MultiPixelPackedSampleModel.java b/src/java.desktop/share/classes/java/awt/image/MultiPixelPackedSampleModel.java index a79ddf52cd9..d8f97562c6c 100644 --- a/src/java.desktop/share/classes/java/awt/image/MultiPixelPackedSampleModel.java +++ b/src/java.desktop/share/classes/java/awt/image/MultiPixelPackedSampleModel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -235,7 +235,11 @@ public class MultiPixelPackedSampleModel extends SampleModel /** * Returns the number of bits per sample for the specified band. - * @param band the specified band + *

    + * Since {@code MultiPixelPackedSampleModel} has only one band, + * this method ignores the {@code band} parameter and returns + * the sample size of the single band. + * @param band the specified band (ignored) * @return the number of bits per sample for the specified band. */ public int getSampleSize(int band) { diff --git a/src/java.desktop/share/classes/java/awt/image/Raster.java b/src/java.desktop/share/classes/java/awt/image/Raster.java index 053e7c1eec5..3312a39b693 100644 --- a/src/java.desktop/share/classes/java/awt/image/Raster.java +++ b/src/java.desktop/share/classes/java/awt/image/Raster.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -452,6 +452,9 @@ public class Raster { throw new IllegalArgumentException("Dimensions (width="+w+ " height="+h+") are too large"); } + if (scanlineStride < 0) { + throw new IllegalArgumentException("Scanline stride must be >= 0"); + } if (bankIndices == null) { throw new ArrayIndexOutOfBoundsException("Bank indices array is null"); diff --git a/src/java.desktop/share/classes/java/awt/image/SinglePixelPackedSampleModel.java b/src/java.desktop/share/classes/java/awt/image/SinglePixelPackedSampleModel.java index d12c151a8fd..2ab226ea227 100644 --- a/src/java.desktop/share/classes/java/awt/image/SinglePixelPackedSampleModel.java +++ b/src/java.desktop/share/classes/java/awt/image/SinglePixelPackedSampleModel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -250,7 +250,12 @@ public class SinglePixelPackedSampleModel extends SampleModel return bitSizes.clone(); } - /** Returns the number of bits per sample for the specified band. */ + /** Returns the number of bits per sample for the specified band. + * @param band the specified band + * @return the size of the samples of the specified band. + * @throws ArrayIndexOutOfBoundsException if the {@code band} index + * is less than zero or greater than or equal to {@code getNumBands()} + */ public int getSampleSize(int band) { return bitSizes[band]; } diff --git a/src/java.desktop/share/classes/javax/print/PrintServiceLookup.java b/src/java.desktop/share/classes/javax/print/PrintServiceLookup.java index 15a7fbbaa00..ee3f6a449b7 100644 --- a/src/java.desktop/share/classes/javax/print/PrintServiceLookup.java +++ b/src/java.desktop/share/classes/javax/print/PrintServiceLookup.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * 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,6 @@ import java.util.ServiceLoader; import javax.print.attribute.AttributeSet; -import sun.awt.AppContext; /** * Implementations of this class provide lookup services for print services @@ -58,35 +57,14 @@ public abstract class PrintServiceLookup { protected PrintServiceLookup() {} /** - * Contains a lists of services. + * The list of lookup services. */ - static class Services { - - /** - * The list of lookup services. - */ - private ArrayList listOfLookupServices = null; - - /** - * The list of registered services. - */ - private ArrayList registeredServices = null; - } + private static ArrayList listOfLookupServices = null; /** - * Returns the services from the current appcontext. - * - * @return the services + * The list of registered services. */ - private static Services getServicesForContext() { - Services services = - (Services)AppContext.getAppContext().get(Services.class); - if (services == null) { - services = new Services(); - AppContext.getAppContext().put(Services.class, services); - } - return services; - } + private static ArrayList registeredServices = null; /** * Returns the list of lookup services. @@ -94,7 +72,7 @@ public abstract class PrintServiceLookup { * @return the list of lookup services */ private static ArrayList getListOfLookupServices() { - return getServicesForContext().listOfLookupServices; + return listOfLookupServices; } /** @@ -103,8 +81,7 @@ public abstract class PrintServiceLookup { * @return the list of lookup services */ private static ArrayList initListOfLookupServices() { - ArrayList listOfLookupServices = new ArrayList<>(); - getServicesForContext().listOfLookupServices = listOfLookupServices; + listOfLookupServices = new ArrayList<>(); return listOfLookupServices; } @@ -114,7 +91,7 @@ public abstract class PrintServiceLookup { * @return the list of registered services */ private static ArrayList getRegisteredServices() { - return getServicesForContext().registeredServices; + return registeredServices; } /** @@ -123,8 +100,7 @@ public abstract class PrintServiceLookup { * @return the list of registered services */ private static ArrayList initRegisteredServices() { - ArrayList registeredServices = new ArrayList<>(); - getServicesForContext().registeredServices = registeredServices; + registeredServices = new ArrayList<>(); return registeredServices; } diff --git a/src/java.desktop/share/classes/javax/print/StreamPrintServiceFactory.java b/src/java.desktop/share/classes/javax/print/StreamPrintServiceFactory.java index 7d696f14a94..2667587e9b2 100644 --- a/src/java.desktop/share/classes/javax/print/StreamPrintServiceFactory.java +++ b/src/java.desktop/share/classes/javax/print/StreamPrintServiceFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,8 +33,6 @@ import java.util.ServiceLoader; import javax.print.attribute.PrintRequestAttributeSet; -import sun.awt.AppContext; - /** * A {@code StreamPrintServiceFactory} is the factory for * {@link StreamPrintService} instances, which can print to an output stream in @@ -63,24 +61,20 @@ public abstract class StreamPrintServiceFactory { static class Services { /** - * The list of factories which will be stored per appcontext. + * The list of factories. */ private ArrayList listOfFactories = null; } + private static final Services SERVICES = new Services(); + /** - * Returns the services from the current appcontext. + * Returns the singleton Services instance. * * @return the services */ private static Services getServices() { - Services services = - (Services)AppContext.getAppContext().get(Services.class); - if (services == null) { - services = new Services(); - AppContext.getAppContext().put(Services.class, services); - } - return services; + return SERVICES; } /** diff --git a/src/java.desktop/share/classes/javax/swing/ImageIcon.java b/src/java.desktop/share/classes/javax/swing/ImageIcon.java index aaaa2dfd4a4..ee6c08ebb15 100644 --- a/src/java.desktop/share/classes/javax/swing/ImageIcon.java +++ b/src/java.desktop/share/classes/javax/swing/ImageIcon.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,7 +54,6 @@ import javax.accessibility.AccessibleState; import javax.accessibility.AccessibleStateSet; import sun.awt.AWTAccessor; -import sun.awt.AppContext; /** * An implementation of the Icon interface that paints Icons @@ -110,18 +109,7 @@ public class ImageIcon implements Icon, Serializable, Accessible { * @deprecated since 1.8 */ @Deprecated - protected static final Component component = createComponent(); - - private static final Component createComponent() { - try { - Component component = new Component() {}; - // 6482575 - clear the appContext field so as not to leak it - AWTAccessor.getComponentAccessor().setAppContext(component, null); - return component; - } catch (Throwable t) { - return null; - } - } + protected static final Component component = new Component() {}; /** * Do not use this shared media tracker, which is used to load images. @@ -136,8 +124,6 @@ public class ImageIcon implements Icon, Serializable, Accessible { */ private static int mediaTrackerID; - private static final Object TRACKER_KEY = new StringBuilder("TRACKER_KEY"); - int width = -1; int height = -1; @@ -346,24 +332,12 @@ public class ImageIcon implements Icon, Serializable, Accessible { } } + private static final MediaTracker MEDIA_TRACKER = new MediaTracker(new Component() {}); /** - * Returns the MediaTracker for the current AppContext, creating a new - * MediaTracker if necessary. + * Returns the shared MediaTracker. */ private MediaTracker getTracker() { - Object trackerObj; - AppContext ac = AppContext.getAppContext(); - // Opt: Only synchronize if trackerObj comes back null? - // If null, synchronize, re-check for null, and put new tracker - synchronized(ac) { - trackerObj = ac.get(TRACKER_KEY); - if (trackerObj == null) { - Component comp = new Component() {}; - trackerObj = new MediaTracker(comp); - ac.put(TRACKER_KEY, trackerObj); - } - } - return (MediaTracker) trackerObj; + return MEDIA_TRACKER; } /** diff --git a/src/java.desktop/share/classes/javax/swing/JPopupMenu.java b/src/java.desktop/share/classes/javax/swing/JPopupMenu.java index 38bde1a97fa..1b04e8c6169 100644 --- a/src/java.desktop/share/classes/javax/swing/JPopupMenu.java +++ b/src/java.desktop/share/classes/javax/swing/JPopupMenu.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -960,7 +960,9 @@ public class JPopupMenu extends JComponent implements Accessible,MenuElement { if (oldInvoker != null) { oldInvoker.removePropertyChangeListener("ancestor", propListener); } - invoker.addPropertyChangeListener("ancestor", propListener); + if (invoker != null) { + invoker.addPropertyChangeListener("ancestor", propListener); + } ui.installUI(this); } invalidate(); diff --git a/src/java.desktop/share/classes/javax/swing/JTable.java b/src/java.desktop/share/classes/javax/swing/JTable.java index 6e64b216d58..f5c914135d1 100644 --- a/src/java.desktop/share/classes/javax/swing/JTable.java +++ b/src/java.desktop/share/classes/javax/swing/JTable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -3191,9 +3191,23 @@ public class JTable extends JComponent implements TableModelListener, Scrollable * (maximum or minimum). * */ + public void doLayout() { + boolean prefWidthSet = false; TableColumn resizingColumn = getResizingColumn(); - if (resizingColumn == null) { + // doLayout is called for both pack and show + // so if initial preferred width is set by user then + // it needs to be honoured even if resizingColumn + // is set to last column on account of + // AUTO_RESIZE_LAST_COLUMN autoResizeMode + for (int i = 0; i < columnModel.getColumnCount(); i++) { + if (columnModel.getColumn(i).getPreferredWidth() != 75 + && columnModel.getColumn(i).getWidth() == 75) { + prefWidthSet = true; + break; + } + } + if (resizingColumn == null || prefWidthSet) { setWidthsFromPreferredWidths(false); } else { diff --git a/src/java.desktop/share/classes/javax/swing/LayoutStyle.java b/src/java.desktop/share/classes/javax/swing/LayoutStyle.java index f1c384db6e2..bf84eb2379b 100644 --- a/src/java.desktop/share/classes/javax/swing/LayoutStyle.java +++ b/src/java.desktop/share/classes/javax/swing/LayoutStyle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2026, Oracle and/or its affiliates. All rights reserved. * 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 @@ package javax.swing; import java.awt.Container; import javax.swing.plaf.ComponentUI; -import sun.awt.AppContext; /** * LayoutStyle provides information about how to position @@ -40,6 +39,9 @@ import sun.awt.AppContext; * @since 1.6 */ public abstract class LayoutStyle { + + private static LayoutStyle sharedInstance; + /** * Sets the shared instance of LayoutStyle. Specifying * null results in using the LayoutStyle from @@ -51,10 +53,10 @@ public abstract class LayoutStyle { public static void setInstance(LayoutStyle style) { synchronized(LayoutStyle.class) { if (style == null) { - AppContext.getAppContext().remove(LayoutStyle.class); + sharedInstance = null; } else { - AppContext.getAppContext().put(LayoutStyle.class, style); + sharedInstance = style; } } } @@ -70,8 +72,7 @@ public abstract class LayoutStyle { public static LayoutStyle getInstance() { LayoutStyle style; synchronized(LayoutStyle.class) { - style = (LayoutStyle)AppContext.getAppContext(). - get(LayoutStyle.class); + style = sharedInstance; } if (style == null) { return UIManager.getLookAndFeel().getLayoutStyle(); diff --git a/src/java.desktop/share/classes/javax/swing/UIManager.java b/src/java.desktop/share/classes/javax/swing/UIManager.java index 7a2ae226f33..69063c562e6 100644 --- a/src/java.desktop/share/classes/javax/swing/UIManager.java +++ b/src/java.desktop/share/classes/javax/swing/UIManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,6 +59,7 @@ import java.util.Objects; import sun.awt.AppContext; import sun.awt.AWTAccessor; +import sun.swing.SwingAccessor; /** * {@code UIManager} manages the current look and feel, the set of @@ -233,8 +234,9 @@ public class UIManager implements Serializable */ public UIManager() {} + private static final LAFState LAF_STATE = new LAFState(); /** - * Return the LAFState object, lazily create one if necessary. + * Return the LAFState object. * All access to the LAFState fields is done via this method, * for example: *

    @@ -242,22 +244,18 @@ public class UIManager implements Serializable
          * 
    */ private static LAFState getLAFState() { - LAFState rv = (LAFState)SwingUtilities.appContextGet( - SwingUtilities2.LAF_STATE_KEY); - if (rv == null) { - synchronized (classLock) { - rv = (LAFState)SwingUtilities.appContextGet( - SwingUtilities2.LAF_STATE_KEY); - if (rv == null) { - SwingUtilities.appContextPut( - SwingUtilities2.LAF_STATE_KEY, - (rv = new LAFState())); - } - } + synchronized (classLock) { + return LAF_STATE; } - return rv; } + static { + SwingAccessor.setLAFStateAccessor(UIManager::isLafStateInitialized); + } + + private static boolean isLafStateInitialized() { + return LAF_STATE.initialized; + } /* Keys used in the swing.properties properties file. * See loadUserProperties(), initialize(). diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicButtonUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicButtonUI.java index c7c036e859f..7846e04b565 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicButtonUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicButtonUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,7 +59,6 @@ import javax.swing.plaf.ComponentUI; import javax.swing.plaf.UIResource; import javax.swing.text.View; -import sun.awt.AppContext; import sun.swing.SwingUtilities2; /** @@ -88,7 +87,7 @@ public class BasicButtonUI extends ButtonUI{ private static final String propertyPrefix = "Button" + "."; - private static final Object BASIC_BUTTON_UI_KEY = new Object(); + private static final ComponentUI UI = new BasicButtonUI(); private KeyListener keyListener = null; @@ -107,14 +106,7 @@ public class BasicButtonUI extends ButtonUI{ * @return an instance of {@code BasicButtonUI} */ public static ComponentUI createUI(JComponent c) { - AppContext appContext = AppContext.getAppContext(); - BasicButtonUI buttonUI = - (BasicButtonUI) appContext.get(BASIC_BUTTON_UI_KEY); - if (buttonUI == null) { - buttonUI = new BasicButtonUI(); - appContext.put(BASIC_BUTTON_UI_KEY, buttonUI); - } - return buttonUI; + return UI; } /** diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicCheckBoxUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicCheckBoxUI.java index 24af28c94c0..49549521005 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicCheckBoxUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicCheckBoxUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,6 @@ package javax.swing.plaf.basic; -import sun.awt.AppContext; - import javax.swing.*; import java.awt.*; @@ -51,7 +49,7 @@ import java.io.Serializable; */ public class BasicCheckBoxUI extends BasicRadioButtonUI { - private static final Object BASIC_CHECK_BOX_UI_KEY = new Object(); + private static final ComponentUI UI = new BasicCheckBoxUI(); private static final String propertyPrefix = "CheckBox" + "."; @@ -71,14 +69,7 @@ public class BasicCheckBoxUI extends BasicRadioButtonUI { * @return an instance of {@code BasicCheckBoxUI} */ public static ComponentUI createUI(JComponent b) { - AppContext appContext = AppContext.getAppContext(); - BasicCheckBoxUI checkboxUI = - (BasicCheckBoxUI) appContext.get(BASIC_CHECK_BOX_UI_KEY); - if (checkboxUI == null) { - checkboxUI = new BasicCheckBoxUI(); - appContext.put(BASIC_CHECK_BOX_UI_KEY, checkboxUI); - } - return checkboxUI; + return UI; } public String getPropertyPrefix() { diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java index 2d1a458e0d7..de3cb1adf75 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,6 @@ import javax.swing.text.*; import javax.swing.event.*; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeEvent; -import sun.awt.AppContext; import sun.swing.DefaultLookup; import sun.swing.SwingUtilities2; import sun.swing.UIAction; @@ -202,10 +201,6 @@ public class BasicComboBoxUI extends ComboBoxUI { // Cached the size that the display needs to render the largest item private Dimension cachedDisplaySize = new Dimension( 0, 0 ); - // Key used for lookup of the DefaultListCellRenderer in the AppContext. - private static final Object COMBO_UI_LIST_CELL_RENDERER_KEY = - new StringBuffer("DefaultListCellRendererKey"); - static final StringBuffer HIDE_POPUP_KEY = new StringBuffer("HidePopupKey"); @@ -237,18 +232,10 @@ public class BasicComboBoxUI extends ComboBoxUI { */ public BasicComboBoxUI() {} + private static final ListCellRenderer CELL_RENDERER = new DefaultListCellRenderer(); // Used for calculating the default size. private static ListCellRenderer getDefaultListCellRenderer() { - @SuppressWarnings("unchecked") - ListCellRenderer renderer = (ListCellRenderer)AppContext. - getAppContext().get(COMBO_UI_LIST_CELL_RENDERER_KEY); - - if (renderer == null) { - renderer = new DefaultListCellRenderer(); - AppContext.getAppContext().put(COMBO_UI_LIST_CELL_RENDERER_KEY, - new DefaultListCellRenderer()); - } - return renderer; + return CELL_RENDERER; } /** diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicLabelUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicLabelUI.java index 279de053fd6..04251ca6266 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicLabelUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicLabelUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * 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,6 @@ package javax.swing.plaf.basic; import sun.swing.SwingUtilities2; import sun.swing.DefaultLookup; import sun.swing.UIAction; -import sun.awt.AppContext; import javax.swing.*; import javax.swing.plaf.*; diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicLookAndFeel.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicLookAndFeel.java index 12b871d6efd..964ee1cb9c9 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicLookAndFeel.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicLookAndFeel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -78,7 +78,6 @@ import javax.swing.plaf.FontUIResource; import javax.swing.plaf.InsetsUIResource; import javax.swing.text.DefaultEditorKit; -import sun.awt.AppContext; import sun.awt.SunToolkit; import sun.swing.SwingAccessor; import sun.swing.SwingUtilities2; @@ -126,11 +125,6 @@ public abstract class BasicLookAndFeel extends LookAndFeel implements Serializab AWTEventHelper invocator = null; - /* - * Listen for our AppContext being disposed - */ - private PropertyChangeListener disposer = null; - /** * Constructor for subclasses to call. */ @@ -174,18 +168,6 @@ public abstract class BasicLookAndFeel extends LookAndFeel implements Serializab if (invocator == null) { invocator = new AWTEventHelper(); needsEventHelper = true; - - // Add a PropertyChangeListener to our AppContext so we're alerted - // when the AppContext is disposed(), at which time this laf should - // be uninitialize()d. - disposer = new PropertyChangeListener() { - public void propertyChange(PropertyChangeEvent prpChg) { - uninitialize(); - } - }; - AppContext.getAppContext().addPropertyChangeListener( - AppContext.GUI_DISPOSED, - disposer); } } @@ -193,35 +175,21 @@ public abstract class BasicLookAndFeel extends LookAndFeel implements Serializab * {@inheritDoc} */ public void uninitialize() { - AppContext context = AppContext.getAppContext(); - synchronized (BasicPopupMenuUI.MOUSE_GRABBER_KEY) { - Object grabber = context.get(BasicPopupMenuUI.MOUSE_GRABBER_KEY); - if (grabber != null) { - ((BasicPopupMenuUI.MouseGrabber)grabber).uninstall(); - } - } - synchronized (BasicPopupMenuUI.MENU_KEYBOARD_HELPER_KEY) { - Object helper = - context.get(BasicPopupMenuUI.MENU_KEYBOARD_HELPER_KEY); - if (helper != null) { - ((BasicPopupMenuUI.MenuKeyboardHelper)helper).uninstall(); - } - } + synchronized (BasicPopupMenuUI.class) { + if (BasicPopupMenuUI.mouseGrabber != null) { + BasicPopupMenuUI.mouseGrabber.uninstall(); + BasicPopupMenuUI.mouseGrabber = null; + } + if (BasicPopupMenuUI.menuKeyboardHelper != null) { + BasicPopupMenuUI.menuKeyboardHelper.uninstall(); + BasicPopupMenuUI.menuKeyboardHelper = null; + } + } - if(invocator != null) { + if (invocator != null) { invocator.run(); invocator = null; } - - if (disposer != null) { - // Note that we're likely calling removePropertyChangeListener() - // during the course of AppContext.firePropertyChange(). - // However, EventListenerAggregate has code to safely modify - // the list under such circumstances. - context.removePropertyChangeListener(AppContext.GUI_DISPOSED, - disposer); - disposer = null; - } } /** diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicPopupMenuUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicPopupMenuUI.java index 6fab795e36c..8df27d3e3cb 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicPopupMenuUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicPopupMenuUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * 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,8 +41,6 @@ import java.util.*; import sun.swing.UIAction; -import sun.awt.AppContext; - /** * A Windows L&F implementation of PopupMenuUI. This implementation * is a "combined" view/controller. @@ -52,10 +50,9 @@ import sun.awt.AppContext; * @author Arnaud Weber */ public class BasicPopupMenuUI extends PopupMenuUI { - static final StringBuilder MOUSE_GRABBER_KEY = new StringBuilder( - "javax.swing.plaf.basic.BasicPopupMenuUI.MouseGrabber"); - static final StringBuilder MENU_KEYBOARD_HELPER_KEY = new StringBuilder( - "javax.swing.plaf.basic.BasicPopupMenuUI.MenuKeyboardHelper"); + + static MouseGrabber mouseGrabber = new MouseGrabber(); + static MenuKeyboardHelper menuKeyboardHelper = null; /** * The instance of {@code JPopupMenu}. @@ -126,23 +123,18 @@ public class BasicPopupMenuUI extends PopupMenuUI { } popupMenu.addMenuKeyListener(menuKeyListener); - AppContext context = AppContext.getAppContext(); - synchronized (MOUSE_GRABBER_KEY) { - MouseGrabber mouseGrabber = (MouseGrabber)context.get( - MOUSE_GRABBER_KEY); - if (mouseGrabber == null) { - mouseGrabber = new MouseGrabber(); - context.put(MOUSE_GRABBER_KEY, mouseGrabber); - } + synchronized (MouseGrabber.class) { + if (mouseGrabber == null) mouseGrabber = new MouseGrabber(); } - synchronized (MENU_KEYBOARD_HELPER_KEY) { - MenuKeyboardHelper helper = - (MenuKeyboardHelper)context.get(MENU_KEYBOARD_HELPER_KEY); + + synchronized (BasicPopupMenuUI.class) { + MenuKeyboardHelper helper = menuKeyboardHelper; if (helper == null) { helper = new MenuKeyboardHelper(); - context.put(MENU_KEYBOARD_HELPER_KEY, helper); MenuSelectionManager msm = MenuSelectionManager.defaultManager(); msm.addChangeListener(helper); + menuKeyboardHelper = helper; + } } } @@ -768,10 +760,10 @@ public class BasicPopupMenuUI extends PopupMenuUI { } void uninstall() { - synchronized (MOUSE_GRABBER_KEY) { + synchronized (MouseGrabber.class) { MenuSelectionManager.defaultManager().removeChangeListener(this); ungrabWindow(); - AppContext.getAppContext().remove(MOUSE_GRABBER_KEY); + mouseGrabber = null; } } @@ -1233,9 +1225,8 @@ public class BasicPopupMenuUI extends PopupMenuUI { } void uninstall() { - synchronized (MENU_KEYBOARD_HELPER_KEY) { + synchronized (BasicPopupMenuUI.class) { MenuSelectionManager.defaultManager().removeChangeListener(this); - AppContext.getAppContext().remove(MENU_KEYBOARD_HELPER_KEY); } } } diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java index 9439059e03e..fdc68d3244f 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,6 @@ import javax.swing.*; import javax.swing.plaf.*; import javax.swing.text.View; import sun.swing.SwingUtilities2; -import sun.awt.AppContext; /** * RadioButtonUI implementation for BasicRadioButtonUI @@ -39,7 +38,7 @@ import sun.awt.AppContext; */ public class BasicRadioButtonUI extends BasicToggleButtonUI { - private static final Object BASIC_RADIO_BUTTON_UI_KEY = new Object(); + private static final ComponentUI UI = new BasicRadioButtonUI(); /** * The icon. @@ -66,14 +65,7 @@ public class BasicRadioButtonUI extends BasicToggleButtonUI * @return an instance of {@code BasicRadioButtonUI} */ public static ComponentUI createUI(JComponent b) { - AppContext appContext = AppContext.getAppContext(); - BasicRadioButtonUI radioButtonUI = - (BasicRadioButtonUI) appContext.get(BASIC_RADIO_BUTTON_UI_KEY); - if (radioButtonUI == null) { - radioButtonUI = new BasicRadioButtonUI(); - appContext.put(BASIC_RADIO_BUTTON_UI_KEY, radioButtonUI); - } - return radioButtonUI; + return UI; } @Override diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTextUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTextUI.java index 391cfdf0b65..d144b5b7240 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTextUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTextUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,6 @@ import javax.swing.border.Border; import javax.swing.plaf.UIResource; import javax.swing.plaf.synth.SynthUI; import sun.swing.DefaultLookup; -import sun.awt.AppContext; import sun.swing.SwingUtilities2; import javax.swing.plaf.basic.DragRecognitionSupport.BeforeDrag; @@ -2234,24 +2233,19 @@ public abstract class BasicTextUI extends TextUI implements ViewFactory { } } + private static volatile DragListener dragListenerSingleton; + private static DragListener getDragListener() { synchronized(DragListener.class) { - DragListener listener = - (DragListener)AppContext.getAppContext(). - get(DragListener.class); - - if (listener == null) { - listener = new DragListener(); - AppContext.getAppContext().put(DragListener.class, listener); + if (dragListenerSingleton == null) { + dragListenerSingleton = new DragListener(); } - - return listener; + return dragListenerSingleton; } } /** * Listens for mouse events for the purposes of detecting drag gestures. - * BasicTextUI will maintain one of these per AppContext. */ static class DragListener extends MouseInputAdapter implements BeforeDrag { diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicToggleButtonUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicToggleButtonUI.java index 2b68fe2b4f3..1a7dfe87353 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicToggleButtonUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicToggleButtonUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,6 @@ package javax.swing.plaf.basic; -import sun.awt.AppContext; - import java.awt.*; import java.awt.event.*; @@ -44,7 +42,7 @@ import javax.swing.text.View; */ public class BasicToggleButtonUI extends BasicButtonUI { - private static final Object BASIC_TOGGLE_BUTTON_UI_KEY = new Object(); + private static final ComponentUI UI = new BasicToggleButtonUI(); private static final String propertyPrefix = "ToggleButton" + "."; @@ -64,14 +62,7 @@ public class BasicToggleButtonUI extends BasicButtonUI { * @return an instance of {@code BasicToggleButtonUI} */ public static ComponentUI createUI(JComponent b) { - AppContext appContext = AppContext.getAppContext(); - BasicToggleButtonUI toggleButtonUI = - (BasicToggleButtonUI) appContext.get(BASIC_TOGGLE_BUTTON_UI_KEY); - if (toggleButtonUI == null) { - toggleButtonUI = new BasicToggleButtonUI(); - appContext.put(BASIC_TOGGLE_BUTTON_UI_KEY, toggleButtonUI); - } - return toggleButtonUI; + return UI; } protected String getPropertyPrefix() { diff --git a/src/java.desktop/share/classes/javax/swing/plaf/metal/DefaultMetalTheme.java b/src/java.desktop/share/classes/javax/swing/plaf/metal/DefaultMetalTheme.java index 8ee862fb0b3..d64267676c3 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/metal/DefaultMetalTheme.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/metal/DefaultMetalTheme.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 @@ import javax.swing.plaf.*; import javax.swing.*; import java.awt.*; -import sun.awt.AppContext; +import sun.swing.SwingAccessor; import sun.swing.SwingUtilities2; /** @@ -153,8 +153,7 @@ public class DefaultMetalTheme extends MetalTheme { static int getDefaultFontStyle(int key) { if (key != WINDOW_TITLE_FONT) { Object boldMetal = null; - if (AppContext.getAppContext().get( - SwingUtilities2.LAF_STATE_KEY) != null) { + if (SwingAccessor.getLAFStateAccessor().lafStateIsInitialized()) { // Only access the boldMetal key if a look and feel has // been loaded, otherwise we'll trigger loading the look // and feel. diff --git a/src/java.desktop/share/classes/javax/swing/plaf/nimbus/Effect.java b/src/java.desktop/share/classes/javax/swing/plaf/nimbus/Effect.java index 30bed2207e4..d1b7ba143b3 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/nimbus/Effect.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/nimbus/Effect.java @@ -24,8 +24,6 @@ */ package javax.swing.plaf.nimbus; -import sun.awt.AppContext; - import java.awt.image.BufferedImage; import java.lang.ref.SoftReference; @@ -81,13 +79,10 @@ abstract class Effect { // ================================================================================================================= // Static data cache + private static final ArrayCache ARRAY_CACHE = new ArrayCache(); + protected static ArrayCache getArrayCache() { - ArrayCache cache = (ArrayCache)AppContext.getAppContext().get(ArrayCache.class); - if (cache == null){ - cache = new ArrayCache(); - AppContext.getAppContext().put(ArrayCache.class,cache); - } - return cache; + return ARRAY_CACHE; } protected static class ArrayCache { diff --git a/src/java.desktop/share/classes/javax/swing/plaf/synth/ImagePainter.java b/src/java.desktop/share/classes/javax/swing/plaf/synth/ImagePainter.java index 8a1d957b615..1171f64eb23 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/synth/ImagePainter.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/synth/ImagePainter.java @@ -28,7 +28,6 @@ import java.awt.*; import java.lang.ref.WeakReference; import java.net.*; import javax.swing.*; -import sun.awt.AppContext; import sun.swing.plaf.synth.Paint9Painter; /** @@ -41,8 +40,6 @@ import sun.swing.plaf.synth.Paint9Painter; * @author Scott Violet */ class ImagePainter extends SynthPainter { - private static final StringBuffer CACHE_KEY = - new StringBuffer("SynthCacheKey"); private Image image; private Insets sInsets; @@ -53,22 +50,17 @@ class ImagePainter extends SynthPainter { private Paint9Painter imageCache; private boolean center; + private static volatile WeakReference cacheRef; + private static Paint9Painter getPaint9Painter() { // A SynthPainter is created per . We want the - // cache to be shared by all, and we don't use a static because we - // don't want it to persist between look and feels. For that reason - // we use a AppContext specific Paint9Painter. It's backed via + // cache to be shared by all. It's held via // a WeakRef so that it can go away if the look and feel changes. - synchronized(CACHE_KEY) { - @SuppressWarnings("unchecked") - WeakReference cacheRef = - (WeakReference)AppContext.getAppContext(). - get(CACHE_KEY); + synchronized(ImagePainter.class) { Paint9Painter painter; if (cacheRef == null || (painter = cacheRef.get()) == null) { painter = new Paint9Painter(30); cacheRef = new WeakReference(painter); - AppContext.getAppContext().put(CACHE_KEY, cacheRef); } return painter; } diff --git a/src/java.desktop/share/classes/javax/swing/plaf/synth/Region.java b/src/java.desktop/share/classes/javax/swing/plaf/synth/Region.java index 5a59f3bb98d..f8a0800ff8b 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/synth/Region.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/synth/Region.java @@ -24,8 +24,6 @@ */ package javax.swing.plaf.synth; -import sun.awt.AppContext; - import java.util.HashMap; import java.util.Locale; import java.util.Map; @@ -72,8 +70,6 @@ import javax.swing.UIDefaults; * @author Scott Violet */ public class Region { - private static final Object UI_TO_REGION_MAP_KEY = new Object(); - private static final Object LOWER_CASE_NAME_MAP_KEY = new Object(); /** * ArrowButton's are special types of buttons that also render a @@ -425,10 +421,10 @@ public class Region { */ public static final Region VIEWPORT = new Region("Viewport", false); - private static Map getUItoRegionMap() { - AppContext context = AppContext.getAppContext(); - @SuppressWarnings("unchecked") - Map map = (Map) context.get(UI_TO_REGION_MAP_KEY); + private static Map regionMap; + + private static synchronized Map getUItoRegionMap() { + Map map = regionMap; if (map == null) { map = new HashMap(); map.put("ArrowButtonUI", ARROW_BUTTON); @@ -476,18 +472,18 @@ public class Region { map.put("ToolBarSeparatorUI", TOOL_BAR_SEPARATOR); map.put("TreeUI", TREE); map.put("ViewportUI", VIEWPORT); - context.put(UI_TO_REGION_MAP_KEY, map); + regionMap = map; } return map; } - private static Map getLowerCaseNameMap() { - AppContext context = AppContext.getAppContext(); - @SuppressWarnings("unchecked") - Map map = (Map) context.get(LOWER_CASE_NAME_MAP_KEY); + private static Map lcRegionMap; + + private static synchronized Map getLowerCaseNameMap() { + Map map = lcRegionMap; if (map == null) { map = new HashMap(); - context.put(LOWER_CASE_NAME_MAP_KEY, map); + lcRegionMap = map; } return map; } diff --git a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthButtonUI.java b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthButtonUI.java index 3a3d5719605..f0c7a9a1622 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthButtonUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthButtonUI.java @@ -25,8 +25,6 @@ package javax.swing.plaf.synth; -import sun.awt.AppContext; - import javax.swing.*; import java.awt.*; import java.beans.*; diff --git a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java index 700e3ed8a38..095d675d3de 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java @@ -60,7 +60,6 @@ import javax.swing.plaf.ComponentUI; import javax.swing.plaf.InsetsUIResource; import javax.swing.plaf.basic.BasicLookAndFeel; -import sun.awt.AppContext; import sun.awt.SunToolkit; import sun.swing.DefaultLookup; import sun.swing.SwingAccessor; @@ -101,31 +100,13 @@ public class SynthLookAndFeel extends BasicLookAndFeel { static final Insets EMPTY_UIRESOURCE_INSETS = new InsetsUIResource( 0, 0, 0, 0); - /** - * AppContext key to get the current SynthStyleFactory. - */ - private static final Object STYLE_FACTORY_KEY = - new StringBuffer("com.sun.java.swing.plaf.gtk.StyleCache"); + private static ComponentUI selectedUI; + private static int selectedUIStateValue; /** - * AppContext key to get selectedUI. - */ - private static final Object SELECTED_UI_KEY = new StringBuilder("selectedUI"); - - /** - * AppContext key to get selectedUIState. - */ - private static final Object SELECTED_UI_STATE_KEY = new StringBuilder("selectedUIState"); - - /** - * The last SynthStyleFactory that was asked for from AppContext - * lastContext. + * The last SynthStyleFactory that was set. */ private static SynthStyleFactory lastFactory; - /** - * AppContext lastLAF came from. - */ - private static AppContext lastContext; /** * SynthStyleFactory for the this SynthLookAndFeel. @@ -141,7 +122,7 @@ public class SynthLookAndFeel extends BasicLookAndFeel { private Handler _handler; static ComponentUI getSelectedUI() { - return (ComponentUI) AppContext.getAppContext().get(SELECTED_UI_KEY); + return selectedUI; } /** @@ -182,23 +163,20 @@ public class SynthLookAndFeel extends BasicLookAndFeel { } } - AppContext context = AppContext.getAppContext(); - - context.put(SELECTED_UI_KEY, uix); - context.put(SELECTED_UI_STATE_KEY, Integer.valueOf(selectedUIState)); + selectedUI = uix; + selectedUIStateValue = selectedUIState; } static int getSelectedUIState() { - Integer result = (Integer) AppContext.getAppContext().get(SELECTED_UI_STATE_KEY); - - return result == null ? 0 : result.intValue(); + return selectedUIStateValue; } /** * Clears out the selected UI that was last set in setSelectedUI. */ static void resetSelectedUI() { - AppContext.getAppContext().remove(SELECTED_UI_KEY); + selectedUI = null; + selectedUIStateValue = 0; } @@ -210,12 +188,8 @@ public class SynthLookAndFeel extends BasicLookAndFeel { */ public static void setStyleFactory(SynthStyleFactory cache) { // We assume the setter is called BEFORE the getter has been invoked - // for a particular AppContext. synchronized(SynthLookAndFeel.class) { - AppContext context = AppContext.getAppContext(); lastFactory = cache; - lastContext = context; - context.put(STYLE_FACTORY_KEY, cache); } } @@ -226,13 +200,6 @@ public class SynthLookAndFeel extends BasicLookAndFeel { */ public static SynthStyleFactory getStyleFactory() { synchronized(SynthLookAndFeel.class) { - AppContext context = AppContext.getAppContext(); - - if (lastContext == context) { - return lastFactory; - } - lastContext = context; - lastFactory = (SynthStyleFactory) context.get(STYLE_FACTORY_KEY); return lastFactory; } } diff --git a/src/java.desktop/share/classes/javax/swing/text/JTextComponent.java b/src/java.desktop/share/classes/javax/swing/text/JTextComponent.java index 03e04d1c1a7..59cee1e12ee 100644 --- a/src/java.desktop/share/classes/javax/swing/text/JTextComponent.java +++ b/src/java.desktop/share/classes/javax/swing/text/JTextComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,9 +62,6 @@ import javax.accessibility.*; import javax.print.attribute.*; -import sun.awt.AppContext; - - import sun.swing.PrintingStatus; import sun.swing.SwingUtilities2; import sun.swing.text.TextComponentPrintable; @@ -1097,22 +1094,16 @@ public abstract class JTextComponent extends JComponent implements Scrollable, A return getKeymapTable().get(nm); } - private static HashMap getKeymapTable() { - synchronized (KEYMAP_TABLE) { - AppContext appContext = AppContext.getAppContext(); - @SuppressWarnings("unchecked") - HashMap keymapTable = - (HashMap)appContext.get(KEYMAP_TABLE); - if (keymapTable == null) { - keymapTable = new HashMap(17); - appContext.put(KEYMAP_TABLE, keymapTable); - //initialize default keymap - Keymap binding = addKeymap(DEFAULT_KEYMAP, null); - binding.setDefaultAction(new - DefaultEditorKit.DefaultKeyTypedAction()); - } - return keymapTable; + private static HashMap keymapTable; + + private static synchronized HashMap getKeymapTable() { + if (keymapTable == null) { + keymapTable = new HashMap(17); + //initialize default keymap + Keymap binding = addKeymap(DEFAULT_KEYMAP, null); + binding.setDefaultAction(new DefaultEditorKit.DefaultKeyTypedAction()); } + return keymapTable; } /** @@ -1653,7 +1644,7 @@ public abstract class JTextComponent extends JComponent implements Scrollable, A public void removeNotify() { super.removeNotify(); if (getFocusedComponent() == this) { - AppContext.getAppContext().remove(FOCUSED_COMPONENT); + focusedComponent = null; } } @@ -4084,13 +4075,14 @@ public abstract class JTextComponent extends JComponent implements Scrollable, A } } + private static JTextComponent focusedComponent; + /** * Returns the JTextComponent that most recently had focus. The returned * value may currently have focus. */ static final JTextComponent getFocusedComponent() { - return (JTextComponent)AppContext.getAppContext(). - get(FOCUSED_COMPONENT); + return focusedComponent; } @SuppressWarnings("deprecation") @@ -4105,9 +4097,6 @@ public abstract class JTextComponent extends JComponent implements Scrollable, A return modifiers; } - private static final Object KEYMAP_TABLE = - new StringBuilder("JTextComponent_KeymapTable"); - // // member variables used for on-the-spot input method // editing style support @@ -4438,9 +4427,6 @@ public abstract class JTextComponent extends JComponent implements Scrollable, A } } - private static final Object FOCUSED_COMPONENT = - new StringBuilder("JTextComponent_FocusedComponent"); - /** * The default keymap that will be shared by all * JTextComponent instances unless they @@ -4493,8 +4479,7 @@ public abstract class JTextComponent extends JComponent implements Scrollable, A // --- FocusListener methods ----------------------------------- public void focusGained(FocusEvent fe) { - AppContext.getAppContext().put(FOCUSED_COMPONENT, - fe.getSource()); + focusedComponent = (JTextComponent)fe.getSource(); } public void focusLost(FocusEvent fe) { diff --git a/src/java.desktop/share/classes/javax/swing/text/LayoutQueue.java b/src/java.desktop/share/classes/javax/swing/text/LayoutQueue.java index 6801a84da5b..1a4e7315eb4 100644 --- a/src/java.desktop/share/classes/javax/swing/text/LayoutQueue.java +++ b/src/java.desktop/share/classes/javax/swing/text/LayoutQueue.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ package javax.swing.text; import java.util.Vector; -import sun.awt.AppContext; /** * A queue of text layout tasks. @@ -36,11 +35,11 @@ import sun.awt.AppContext; */ public class LayoutQueue { - private static final Object DEFAULT_QUEUE = new Object(); - private Vector tasks; private Thread worker; + private static LayoutQueue defaultQueue; + /** * Construct a layout queue. */ @@ -53,15 +52,10 @@ public class LayoutQueue { * @return the default layout queue */ public static LayoutQueue getDefaultQueue() { - AppContext ac = AppContext.getAppContext(); - synchronized (DEFAULT_QUEUE) { - LayoutQueue defaultQueue = (LayoutQueue) ac.get(DEFAULT_QUEUE); - if (defaultQueue == null) { - defaultQueue = new LayoutQueue(); - ac.put(DEFAULT_QUEUE, defaultQueue); - } - return defaultQueue; + if (defaultQueue == null) { + defaultQueue = new LayoutQueue(); } + return defaultQueue; } /** @@ -70,9 +64,7 @@ public class LayoutQueue { * @param q the new queue. */ public static void setDefaultQueue(LayoutQueue q) { - synchronized (DEFAULT_QUEUE) { - AppContext.getAppContext().put(DEFAULT_QUEUE, q); - } + defaultQueue = q; } /** diff --git a/src/java.desktop/share/classes/javax/swing/text/html/HTMLEditorKit.java b/src/java.desktop/share/classes/javax/swing/text/html/HTMLEditorKit.java index 53ceea32668..b5b75e1067b 100644 --- a/src/java.desktop/share/classes/javax/swing/text/html/HTMLEditorKit.java +++ b/src/java.desktop/share/classes/javax/swing/text/html/HTMLEditorKit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 +92,6 @@ import javax.swing.text.ViewFactory; import javax.swing.text.html.parser.ParserDelegator; import sun.swing.SwingAccessor; -import sun.awt.AppContext; import static java.nio.charset.StandardCharsets.ISO_8859_1; @@ -432,11 +431,7 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible { * @param s a StyleSheet */ public void setStyleSheet(StyleSheet s) { - if (s == null) { - AppContext.getAppContext().remove(DEFAULT_STYLES_KEY); - } else { - AppContext.getAppContext().put(DEFAULT_STYLES_KEY, s); - } + defaultStyles = s; } /** @@ -448,12 +443,8 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible { * @return the StyleSheet */ public StyleSheet getStyleSheet() { - AppContext appContext = AppContext.getAppContext(); - StyleSheet defaultStyles = (StyleSheet) appContext.get(DEFAULT_STYLES_KEY); - if (defaultStyles == null) { defaultStyles = new StyleSheet(); - appContext.put(DEFAULT_STYLES_KEY, defaultStyles); try (InputStream is = HTMLEditorKit.getResourceAsStream(DEFAULT_CSS); InputStreamReader isr = new InputStreamReader(is, ISO_8859_1); Reader r = new BufferedReader(isr)) @@ -692,6 +683,7 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible { private static final ViewFactory defaultFactory = new HTMLFactory(); MutableAttributeSet input; + private static StyleSheet defaultStyles = null; private static final Object DEFAULT_STYLES_KEY = new Object(); private LinkController linkHandler = new LinkController(); private static Parser defaultParser = null; diff --git a/src/java.desktop/share/classes/javax/swing/text/html/parser/DTD.java b/src/java.desktop/share/classes/javax/swing/text/html/parser/DTD.java index e9999c679eb..d3a4fa76306 100644 --- a/src/java.desktop/share/classes/javax/swing/text/html/parser/DTD.java +++ b/src/java.desktop/share/classes/javax/swing/text/html/parser/DTD.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,6 @@ package javax.swing.text.html.parser; -import sun.awt.AppContext; - import java.io.PrintStream; import java.io.File; import java.io.FileInputStream; @@ -403,11 +401,6 @@ class DTD implements DTDConstants { return name; } - /** - * The hashtable key of DTDs in AppContext. - */ - private static final Object DTD_HASH_KEY = new Object(); - /** * Put a name and appropriate DTD to hashtable. * @@ -415,7 +408,7 @@ class DTD implements DTDConstants { * @param dtd the DTD */ public static void putDTDHash(String name, DTD dtd) { - getDtdHash().put(name, dtd); + DTD_MAP.put(name, dtd); } /** @@ -430,27 +423,14 @@ class DTD implements DTDConstants { */ public static DTD getDTD(String name) throws IOException { name = name.toLowerCase(); - DTD dtd = getDtdHash().get(name); + DTD dtd = DTD_MAP.get(name); if (dtd == null) dtd = new DTD(name); return dtd; } - private static Hashtable getDtdHash() { - AppContext appContext = AppContext.getAppContext(); - - @SuppressWarnings("unchecked") - Hashtable result = (Hashtable) appContext.get(DTD_HASH_KEY); - - if (result == null) { - result = new Hashtable(); - - appContext.put(DTD_HASH_KEY, result); - } - - return result; - } + private static final Hashtable DTD_MAP = new Hashtable(); /** * Recreates a DTD from an archived format. diff --git a/src/java.desktop/share/classes/javax/swing/text/html/parser/Element.java b/src/java.desktop/share/classes/javax/swing/text/html/parser/Element.java index cf8ea622c9b..8dd00373636 100644 --- a/src/java.desktop/share/classes/javax/swing/text/html/parser/Element.java +++ b/src/java.desktop/share/classes/javax/swing/text/html/parser/Element.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2026, Oracle and/or its affiliates. All rights reserved. * 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,6 @@ package javax.swing.text.html.parser; import java.io.Serializable; import java.util.BitSet; import java.util.Map; -import sun.awt.AppContext; /** * An element as described in a DTD using the ELEMENT construct. @@ -107,17 +106,14 @@ public final class Element implements DTDConstants, Serializable { this.name = name; this.index = index; if (index > getMaxIndex()) { - AppContext.getAppContext().put(MAX_INDEX_KEY, index); + maxIndex = index; } } - private static final Object MAX_INDEX_KEY = new Object(); + private static int maxIndex = 0; static int getMaxIndex() { - Integer value = (Integer) AppContext.getAppContext().get(MAX_INDEX_KEY); - return (value != null) - ? value.intValue() - : 0; + return maxIndex; } /** diff --git a/src/java.desktop/share/classes/javax/swing/text/html/parser/ParserDelegator.java b/src/java.desktop/share/classes/javax/swing/text/html/parser/ParserDelegator.java index 2d541abc06f..6971f313558 100644 --- a/src/java.desktop/share/classes/javax/swing/text/html/parser/ParserDelegator.java +++ b/src/java.desktop/share/classes/javax/swing/text/html/parser/ParserDelegator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2026, Oracle and/or its affiliates. All rights reserved. * 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,8 +24,6 @@ */ package javax.swing.text.html.parser; -import sun.awt.AppContext; - import javax.swing.text.html.HTMLEditorKit; import java.io.BufferedInputStream; import java.io.IOException; @@ -52,7 +50,8 @@ import java.io.Serializable; */ @SuppressWarnings("serial") // Same-version serialization only public class ParserDelegator extends HTMLEditorKit.Parser implements Serializable { - private static final Object DTD_KEY = new Object(); + + private static DTD dtd = null; /** * Sets the default DTD. @@ -62,10 +61,6 @@ public class ParserDelegator extends HTMLEditorKit.Parser implements Serializabl } private static synchronized DTD getDefaultDTD() { - AppContext appContext = AppContext.getAppContext(); - - DTD dtd = (DTD) appContext.get(DTD_KEY); - if (dtd == null) { DTD _dtd = null; // (PENDING) Hate having to hard code! @@ -77,10 +72,7 @@ public class ParserDelegator extends HTMLEditorKit.Parser implements Serializabl System.out.println("Throw an exception: could not get default dtd: " + nm); } dtd = createDTD(_dtd, nm); - - appContext.put(DTD_KEY, dtd); } - return dtd; } diff --git a/src/java.desktop/share/classes/sun/awt/image/ImageFetcher.java b/src/java.desktop/share/classes/sun/awt/image/ImageFetcher.java index 74c7c4d2ce2..917378389a4 100644 --- a/src/java.desktop/share/classes/sun/awt/image/ImageFetcher.java +++ b/src/java.desktop/share/classes/sun/awt/image/ImageFetcher.java @@ -26,7 +26,6 @@ package sun.awt.image; import java.util.Vector; -import sun.awt.AppContext; /** * An ImageFetcher is a thread used to fetch ImageFetchable objects. @@ -34,10 +33,6 @@ import sun.awt.AppContext; * thread may also be used to animate it if necessary, via the * startingAnimation() / stoppingAnimation() methods. * - * There can be up to FetcherInfo.MAX_NUM_FETCHERS_PER_APPCONTEXT - * ImageFetcher threads for each AppContext. A per-AppContext queue - * of ImageFetchables is used to track objects to fetch. - * * @author Jim Graham * @author Fred Ecks */ @@ -153,7 +148,6 @@ class ImageFetcher extends Thread { info.numWaiting++; info.waitList.wait(end - now); } catch (InterruptedException e) { - // A normal occurrence as an AppContext is disposed return null; } finally { info.numWaiting--; @@ -280,28 +274,20 @@ class ImageFetcher extends Thread { // We need to instantiate a new ImageFetcher thread. // First, figure out which ThreadGroup we'll put the // new ImageFetcher into - final AppContext appContext = AppContext.getAppContext(); - ThreadGroup threadGroup = appContext.getThreadGroup(); - ThreadGroup fetcherThreadGroup; - if (threadGroup.getParent() != null) { - // threadGroup is not the root, so we proceed - fetcherThreadGroup = threadGroup; - } else { - // threadGroup is the root ("system") ThreadGroup. - // We instead want to use its child: the "main" - // ThreadGroup. Thus, we start with the current - // ThreadGroup, and go up the tree until - // threadGroup.getParent().getParent() == null. - threadGroup = Thread.currentThread().getThreadGroup(); - ThreadGroup parent = threadGroup.getParent(); - while ((parent != null) - && (parent.getParent() != null)) { - threadGroup = parent; - parent = threadGroup.getParent(); - } - fetcherThreadGroup = threadGroup; + // We don't want the root ("system") ThreadGroup. + // We instead want to use its child: the "main" + // ThreadGroup. Thus, we start with the current + // ThreadGroup, and go up the tree until + // threadGroup.getParent().getParent() == null. + ThreadGroup threadGroup = Thread.currentThread().getThreadGroup(); + ThreadGroup parent = threadGroup.getParent(); + while ((parent != null) + && (parent.getParent() != null)) { + threadGroup = parent; + parent = threadGroup.getParent(); } - final ThreadGroup fetcherGroup = fetcherThreadGroup; + final ThreadGroup fetcherGroup = threadGroup; + for (int i = 0; i < info.fetchers.length; i++) { if (info.fetchers[i] == null) { @@ -320,12 +306,13 @@ class ImageFetcher extends Thread { } /** - * The FetcherInfo class encapsulates the per-AppContext ImageFetcher + * The FetcherInfo class encapsulates the ImageFetcher * information. This includes the array of ImageFetchers, as well as * the queue of ImageFetchable objects. */ class FetcherInfo { - static final int MAX_NUM_FETCHERS_PER_APPCONTEXT = 4; + static final int MAX_NUM_FETCHERS = 4; + static final FetcherInfo FETCHER_INFO = new FetcherInfo(); Thread[] fetchers; int numFetchers; @@ -333,25 +320,13 @@ class FetcherInfo { Vector waitList; private FetcherInfo() { - fetchers = new Thread[MAX_NUM_FETCHERS_PER_APPCONTEXT]; + fetchers = new Thread[MAX_NUM_FETCHERS]; numFetchers = 0; numWaiting = 0; waitList = new Vector<>(); } - /* The key to put()/get() the FetcherInfo into/from the AppContext. */ - private static final Object FETCHER_INFO_KEY = - new StringBuffer("FetcherInfo"); - static FetcherInfo getFetcherInfo() { - AppContext appContext = AppContext.getAppContext(); - synchronized(appContext) { - FetcherInfo info = (FetcherInfo)appContext.get(FETCHER_INFO_KEY); - if (info == null) { - info = new FetcherInfo(); - appContext.put(FETCHER_INFO_KEY, info); - } - return info; - } + return FETCHER_INFO; } } diff --git a/src/java.desktop/share/classes/sun/swing/DefaultLookup.java b/src/java.desktop/share/classes/sun/swing/DefaultLookup.java index d7a7f22eba3..a2ae0921507 100644 --- a/src/java.desktop/share/classes/sun/swing/DefaultLookup.java +++ b/src/java.desktop/share/classes/sun/swing/DefaultLookup.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved. * 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,6 @@ import java.awt.Insets; import javax.swing.*; import javax.swing.border.Border; import javax.swing.plaf.ComponentUI; -import sun.awt.AppContext; /** * DefaultLookup provides a way to customize the lookup done by the @@ -44,17 +43,9 @@ import sun.awt.AppContext; * @author Scott Violet */ public class DefaultLookup { + /** - * Key used to store DefaultLookup for AppContext. - */ - private static final Object DEFAULT_LOOKUP_KEY = new - StringBuffer("DefaultLookup"); - /** - * Thread that last asked for a default. - */ - private static Thread currentDefaultThread; - /** - * DefaultLookup for last thread. + * DefaultLookup currently set. */ private static DefaultLookup currentDefaultLookup; @@ -63,28 +54,24 @@ public class DefaultLookup { */ private static boolean isLookupSet; - /** - * Sets the DefaultLookup instance to use for the current - * AppContext. Null implies the UIManager should be - * used. + * Sets the DefaultLookup instance to use. + * Null implies the UIManager should be used. */ public static void setDefaultLookup(DefaultLookup lookup) { synchronized(DefaultLookup.class) { if (!isLookupSet && lookup == null) { - // Null was passed in, and no one has invoked setDefaultLookup + // Null was passed in, and no one has previously invoked setDefaultLookup // with a non-null value, we don't need to do anything. return; } else if (lookup == null) { - // null was passed in, but someone has invoked setDefaultLookup + // null was passed in, but someone has previously invoked setDefaultLookup // with a non-null value, use an instance of DefaultLookup // which will fallback to UIManager. lookup = new DefaultLookup(); } isLookupSet = true; - AppContext.getAppContext().put(DEFAULT_LOOKUP_KEY, lookup); - currentDefaultThread = Thread.currentThread(); currentDefaultLookup = lookup; } } @@ -98,27 +85,13 @@ public class DefaultLookup { // No one has set a valid DefaultLookup, use UIManager. return UIManager.get(key, c.getLocale()); } - Thread thisThread = Thread.currentThread(); DefaultLookup lookup; synchronized(DefaultLookup.class) { - // See if we've already cached the DefaultLookup for this thread, - // and use it if we have. - if (thisThread == currentDefaultThread) { - // It is cached, use it. - lookup = currentDefaultLookup; - } - else { - // Not cached, get the DefaultLookup to use from the AppContext - lookup = (DefaultLookup)AppContext.getAppContext().get( - DEFAULT_LOOKUP_KEY); - if (lookup == null) { - // Fallback to DefaultLookup, which will redirect to the - // UIManager. - lookup = new DefaultLookup(); - AppContext.getAppContext().put(DEFAULT_LOOKUP_KEY, lookup); - } - // Cache the values to make the next lookup easier. - currentDefaultThread = thisThread; + lookup = currentDefaultLookup; + if (lookup == null) { + // Fallback to DefaultLookup, which will redirect to the + // UIManager. + lookup = new DefaultLookup(); currentDefaultLookup = lookup; } } diff --git a/src/java.desktop/share/classes/sun/swing/SwingAccessor.java b/src/java.desktop/share/classes/sun/swing/SwingAccessor.java index 5c561de4a42..563cc038ae9 100644 --- a/src/java.desktop/share/classes/sun/swing/SwingAccessor.java +++ b/src/java.desktop/share/classes/sun/swing/SwingAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -133,6 +133,33 @@ public final class SwingAccessor { KeyStroke create(); } + /** + * An accessor for the LAFState class state. + */ + public interface LAFStateAccessor { + boolean lafStateIsInitialized(); + } + + private static LAFStateAccessor lafStateAccessor; + /** + * Set an accessor object for the LAFState class. + */ + public static void setLAFStateAccessor(LAFStateAccessor accessor) { + lafStateAccessor = accessor; + } + + /** + * Retrieve the accessor object for the LAFState class. + */ + public static LAFStateAccessor getLAFStateAccessor() { + var access = lafStateAccessor; + if (access == null) { + ensureClassInitialized(UIManager.class); + access = lafStateAccessor; + } + return access; + } + /** * The javax.swing.JComponent class accessor object. */ diff --git a/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java b/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java index 20a07c608a0..faf31e0b426 100644 --- a/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java +++ b/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -120,12 +120,6 @@ import static java.awt.geom.AffineTransform.TYPE_TRANSLATION; * */ public class SwingUtilities2 { - /** - * The {@code AppContext} key for our one {@code LAFState} - * instance. - */ - public static final Object LAF_STATE_KEY = - new StringBuffer("LookAndFeel State"); public static final Object MENU_SELECTION_MANAGER_LISTENER_KEY = new StringBuffer("MenuSelectionManager listener key"); diff --git a/src/java.desktop/share/legal/harfbuzz.md b/src/java.desktop/share/legal/harfbuzz.md index e0c40705ed6..3aa5ca841d6 100644 --- a/src/java.desktop/share/legal/harfbuzz.md +++ b/src/java.desktop/share/legal/harfbuzz.md @@ -1,4 +1,4 @@ -## Harfbuzz 11.2.0 +## Harfbuzz 12.3.2 ### Harfbuzz License diff --git a/src/java.desktop/share/native/libawt/awt/image/awt_ImageRep.c b/src/java.desktop/share/native/libawt/awt/image/awt_ImageRep.c index 6079b9e76b8..3cb2df0e0e9 100644 --- a/src/java.desktop/share/native/libawt/awt/image/awt_ImageRep.c +++ b/src/java.desktop/share/native/libawt/awt/image/awt_ImageRep.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -227,7 +227,7 @@ Java_sun_awt_image_ImageRepresentation_setICMpixels(JNIEnv *env, jclass cls, /* Release the locked arrays */ (*env)->ReleasePrimitiveArrayCritical(env, jlut, srcLUT, JNI_ABORT); (*env)->ReleasePrimitiveArrayCritical(env, jpix, srcData, JNI_ABORT); - (*env)->ReleasePrimitiveArrayCritical(env, jdata, dstData, JNI_ABORT); + (*env)->ReleasePrimitiveArrayCritical(env, jdata, dstData, 0); return JNI_TRUE; } @@ -385,7 +385,7 @@ Java_sun_awt_image_ImageRepresentation_setDiffICM(JNIEnv *env, jclass cls, } (*env)->ReleasePrimitiveArrayCritical(env, jpix, srcData, JNI_ABORT); - (*env)->ReleasePrimitiveArrayCritical(env, jdata, dstData, JNI_ABORT); + (*env)->ReleasePrimitiveArrayCritical(env, jdata, dstData, 0); return JNI_TRUE; } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh b/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh index 73e6b4c305b..011b5ad5520 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh @@ -104,7 +104,7 @@ public: foreground (foreground_), instancer (instancer_) { - if (font->is_synthetic ()) + if (font->is_synthetic) { font = hb_font_create_sub_font (font); hb_font_set_synthetic_bold (font, 0, 0, true); @@ -178,7 +178,10 @@ struct hb_colrv1_closure_context_t : { glyphs->add (glyph_id); } void add_layer_indices (unsigned first_layer_index, unsigned num_of_layers) - { layer_indices->add_range (first_layer_index, first_layer_index + num_of_layers - 1); } + { + if (num_of_layers == 0) return; + layer_indices->add_range (first_layer_index, first_layer_index + num_of_layers - 1); + } void add_palette_index (unsigned palette_index) { palette_indices->add (palette_index); } @@ -650,10 +653,10 @@ struct PaintColrLayers TRACE_SUBSET (this); auto *out = c->serializer->embed (this); if (unlikely (!out)) return_trace (false); - return_trace (c->serializer->check_assign (out->firstLayerIndex, c->plan->colrv1_layers.get (firstLayerIndex), - HB_SERIALIZE_ERROR_INT_OVERFLOW)); - return_trace (true); + uint32_t first_layer_index = numLayers ? c->plan->colrv1_layers.get (firstLayerIndex) : 0; + return_trace (c->serializer->check_assign (out->firstLayerIndex, first_layer_index, + HB_SERIALIZE_ERROR_INT_OVERFLOW)); } bool sanitize (hb_sanitize_context_t *c) const @@ -1075,9 +1078,9 @@ struct PaintTranslate float ddx = dx + c->instancer (varIdxBase, 0); float ddy = dy + c->instancer (varIdxBase, 1); - bool p1 = c->funcs->push_translate (c->data, ddx, ddy); + c->funcs->push_translate (c->data, ddx, ddy); c->recurse (this+src); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 14(noVar) or 15 (Var) */ @@ -1124,9 +1127,9 @@ struct PaintScale float sx = scaleX.to_float (c->instancer (varIdxBase, 0)); float sy = scaleY.to_float (c->instancer (varIdxBase, 1)); - bool p1 = c->funcs->push_scale (c->data, sx, sy); + c->funcs->push_scale (c->data, sx, sy); c->recurse (this+src); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 16 (noVar) or 17(Var) */ @@ -1177,13 +1180,9 @@ struct PaintScaleAroundCenter float tCenterX = centerX + c->instancer (varIdxBase, 2); float tCenterY = centerY + c->instancer (varIdxBase, 3); - bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY); - bool p2 = c->funcs->push_scale (c->data, sx, sy); - bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY); + c->funcs->push_scale_around_center (c->data, sx, sy, tCenterX, tCenterY); c->recurse (this+src); - if (p3) c->funcs->pop_transform (c->data); - if (p2) c->funcs->pop_transform (c->data); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 18 (noVar) or 19(Var) */ @@ -1228,9 +1227,9 @@ struct PaintScaleUniform TRACE_PAINT (this); float s = scale.to_float (c->instancer (varIdxBase, 0)); - bool p1 = c->funcs->push_scale (c->data, s, s); + c->funcs->push_scale (c->data, s, s); c->recurse (this+src); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 20 (noVar) or 21(Var) */ @@ -1278,13 +1277,9 @@ struct PaintScaleUniformAroundCenter float tCenterX = centerX + c->instancer (varIdxBase, 1); float tCenterY = centerY + c->instancer (varIdxBase, 2); - bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY); - bool p2 = c->funcs->push_scale (c->data, s, s); - bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY); + c->funcs->push_scale_around_center (c->data, s, s, tCenterX, tCenterY); c->recurse (this+src); - if (p3) c->funcs->pop_transform (c->data); - if (p2) c->funcs->pop_transform (c->data); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 22 (noVar) or 23(Var) */ @@ -1328,9 +1323,9 @@ struct PaintRotate TRACE_PAINT (this); float a = angle.to_float (c->instancer (varIdxBase, 0)); - bool p1 = c->funcs->push_rotate (c->data, a); + c->funcs->push_rotate (c->data, a); c->recurse (this+src); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 24 (noVar) or 25(Var) */ @@ -1378,13 +1373,9 @@ struct PaintRotateAroundCenter float tCenterX = centerX + c->instancer (varIdxBase, 1); float tCenterY = centerY + c->instancer (varIdxBase, 2); - bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY); - bool p2 = c->funcs->push_rotate (c->data, a); - bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY); + c->funcs->push_rotate_around_center (c->data, a, tCenterX, tCenterY); c->recurse (this+src); - if (p3) c->funcs->pop_transform (c->data); - if (p2) c->funcs->pop_transform (c->data); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 26 (noVar) or 27(Var) */ @@ -1432,9 +1423,9 @@ struct PaintSkew float sx = xSkewAngle.to_float(c->instancer (varIdxBase, 0)); float sy = ySkewAngle.to_float(c->instancer (varIdxBase, 1)); - bool p1 = c->funcs->push_skew (c->data, sx, sy); + c->funcs->push_skew (c->data, sx, sy); c->recurse (this+src); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 28(noVar) or 29 (Var) */ @@ -1485,13 +1476,9 @@ struct PaintSkewAroundCenter float tCenterX = centerX + c->instancer (varIdxBase, 2); float tCenterY = centerY + c->instancer (varIdxBase, 3); - bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY); - bool p2 = c->funcs->push_skew (c->data, sx, sy); - bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY); + c->funcs->push_skew_around_center (c->data, sx, sy, tCenterX, tCenterY); c->recurse (this+src); - if (p3) c->funcs->pop_transform (c->data); - if (p2) c->funcs->pop_transform (c->data); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 30(noVar) or 31 (Var) */ @@ -1626,7 +1613,7 @@ struct ClipBox const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); - switch (u.format) { + switch (u.format.v) { case 1: return_trace (u.format1.subset (c, instancer, VarIdx::NO_VARIATION)); case 2: return_trace (u.format2.subset (c, instancer)); default:return_trace (c->default_return_value ()); @@ -1635,7 +1622,7 @@ struct ClipBox void closurev1 (hb_colrv1_closure_context_t* c) const { - switch (u.format) { + switch (u.format.v) { case 2: u.format2.closurev1 (c); return; default:return; } @@ -1644,9 +1631,9 @@ struct ClipBox template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); default:return_trace (c->default_return_value ()); @@ -1657,7 +1644,7 @@ struct ClipBox const ItemVarStoreInstancer &instancer) const { ClipBoxData clip_box; - switch (u.format) { + switch (u.format.v) { case 1: u.format1.get_clip_box (clip_box, instancer); break; @@ -1677,7 +1664,7 @@ struct ClipBox protected: union { - HBUINT8 format; /* Format identifier */ + struct { HBUINT8 v; } format; /* Format identifier */ ClipBoxFormat1 format1; ClipBoxFormat2 format2; } u; @@ -1857,9 +1844,9 @@ struct Paint template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: return_trace (c->dispatch (u.paintformat1, std::forward (ds)...)); case 2: return_trace (c->dispatch (u.paintformat2, std::forward (ds)...)); case 3: return_trace (c->dispatch (u.paintformat3, std::forward (ds)...)); @@ -1898,7 +1885,7 @@ struct Paint protected: union { - HBUINT8 format; + struct { HBUINT8 v; } format; PaintColrLayers paintformat1; NoVariable paintformat2; Variable paintformat3; @@ -2073,7 +2060,7 @@ struct delta_set_index_map_subset_plan_t outer_bit_count = 1; inner_bit_count = 1; - if (unlikely (!output_map.resize (map_count, false))) return false; + if (unlikely (!output_map.resize_dirty (map_count))) return false; for (unsigned idx = 0; idx < map_count; idx++) { @@ -2693,7 +2680,8 @@ struct COLR { ItemVarStoreInstancer instancer (get_var_store_ptr (), get_delta_set_index_map_ptr (), - hb_array (font->coords, font->num_coords)); + hb_array (font->coords, + font->has_nonzero_coords ? font->num_coords : 0)); hb_paint_context_t c (this, funcs, data, font, palette_index, foreground, instancer); hb_decycler_node_t node (c.glyphs_decycler); diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Color/CPAL/CPAL.hh b/src/java.desktop/share/native/libharfbuzz/OT/Color/CPAL/CPAL.hh index 51fc1b52af4..71417fdf3cf 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Color/CPAL/CPAL.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Color/CPAL/CPAL.hh @@ -307,6 +307,7 @@ struct CPAL if (first_color_to_layer_index.has (first_color_record_idx)) continue; first_color_index_for_layer.push (first_color_record_idx); + if (unlikely (!c->serializer->propagate_error (first_color_index_for_layer))) return_trace (false); first_color_to_layer_index.set (first_color_record_idx, first_color_index_for_layer.length - 1); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/Coverage.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/Coverage.hh index 35d73c7b858..28678856373 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/Coverage.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/Coverage.hh @@ -46,7 +46,7 @@ struct Coverage protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ CoverageFormat1_3 format1; CoverageFormat2_4 format2; #ifndef HB_NO_BEYOND_64K @@ -55,7 +55,7 @@ struct Coverage #endif } u; public: - DEFINE_SIZE_UNION (2, format); + DEFINE_SIZE_UNION (2, format.v); #ifndef HB_OPTIMIZE_SIZE HB_ALWAYS_INLINE @@ -63,9 +63,9 @@ struct Coverage bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return_trace (false); + if (!u.format.v.sanitize (c)) return_trace (false); hb_barrier (); - switch (u.format) + switch (u.format.v) { case 1: return_trace (u.format1.sanitize (c)); case 2: return_trace (u.format2.sanitize (c)); @@ -86,7 +86,7 @@ struct Coverage unsigned int get (hb_codepoint_t k) const { return get_coverage (k); } unsigned int get_coverage (hb_codepoint_t glyph_id) const { - switch (u.format) { + switch (u.format.v) { case 1: return u.format1.get_coverage (glyph_id); case 2: return u.format2.get_coverage (glyph_id); #ifndef HB_NO_BEYOND_64K @@ -97,18 +97,38 @@ struct Coverage } } unsigned int get_coverage (hb_codepoint_t glyph_id, - hb_ot_lookup_cache_t *cache) const + hb_ot_layout_mapping_cache_t *cache) const { unsigned coverage; - if (cache && cache->get (glyph_id, &coverage)) return coverage; + if (cache && cache->get (glyph_id, &coverage)) return coverage < cache->MAX_VALUE ? coverage : NOT_COVERED; coverage = get_coverage (glyph_id); - if (cache) cache->set (glyph_id, coverage); + if (cache) { + if (coverage == NOT_COVERED) + cache->set_unchecked (glyph_id, cache->MAX_VALUE); + else if (likely (coverage < cache->MAX_VALUE)) + cache->set_unchecked (glyph_id, coverage); + } + return coverage; + } + + unsigned int get_coverage_binary (hb_codepoint_t glyph_id, + hb_ot_layout_binary_cache_t *cache) const + { + unsigned coverage; + if (cache && cache->get (glyph_id, &coverage)) return coverage < cache->MAX_VALUE ? coverage : NOT_COVERED; + coverage = get_coverage (glyph_id); + if (cache) { + if (coverage == NOT_COVERED) + cache->set_unchecked (glyph_id, cache->MAX_VALUE); + else + cache->set_unchecked (glyph_id, 0); + } return coverage; } unsigned get_population () const { - switch (u.format) { + switch (u.format.v) { case 1: return u.format1.get_population (); case 2: return u.format2.get_population (); #ifndef HB_NO_BEYOND_64K @@ -140,11 +160,11 @@ struct Coverage last = g; if (g > max) max = g; } - u.format = !unsorted && count <= num_ranges * 3 ? 1 : 2; + u.format.v = !unsorted && count <= num_ranges * 3 ? 1 : 2; #ifndef HB_NO_BEYOND_64K if (max > 0xFFFFu) - u.format += 2; + u.format.v += 2; if (unlikely (max > 0xFFFFFFu)) #else if (unlikely (max > 0xFFFFu)) @@ -154,7 +174,7 @@ struct Coverage return_trace (false); } - switch (u.format) + switch (u.format.v) { case 1: return_trace (u.format1.serialize (c, glyphs)); case 2: return_trace (u.format2.serialize (c, glyphs)); @@ -185,7 +205,7 @@ struct Coverage bool intersects (const hb_set_t *glyphs) const { - switch (u.format) + switch (u.format.v) { case 1: return u.format1.intersects (glyphs); case 2: return u.format2.intersects (glyphs); @@ -198,7 +218,7 @@ struct Coverage } bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const { - switch (u.format) + switch (u.format.v) { case 1: return u.format1.intersects_coverage (glyphs, index); case 2: return u.format2.intersects_coverage (glyphs, index); @@ -212,7 +232,7 @@ struct Coverage unsigned cost () const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.cost (); case 2: hb_barrier (); return u.format2.cost (); #ifndef HB_NO_BEYOND_64K @@ -228,7 +248,7 @@ struct Coverage template bool collect_coverage (set_t *glyphs) const { - switch (u.format) + switch (u.format.v) { case 1: return u.format1.collect_coverage (glyphs); case 2: return u.format2.collect_coverage (glyphs); @@ -244,7 +264,7 @@ struct Coverage hb_requires (hb_is_sink_of (IterableOut, hb_codepoint_t))> void intersect_set (const hb_set_t &glyphs, IterableOut&& intersect_glyphs) const { - switch (u.format) + switch (u.format.v) { case 1: return u.format1.intersect_set (glyphs, intersect_glyphs); case 2: return u.format2.intersect_set (glyphs, intersect_glyphs); @@ -262,7 +282,7 @@ struct Coverage iter_t (const Coverage &c_ = Null (Coverage)) { hb_memset (this, 0, sizeof (*this)); - format = c_.u.format; + format = c_.u.format.v; switch (format) { case 1: u.format1.init (c_.u.format1); return; @@ -332,7 +352,7 @@ struct Coverage } iter_t __end__ () const { - iter_t it = {}; + iter_t it; it.format = format; switch (format) { diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh index 97ea51089ec..122326e3024 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh @@ -41,11 +41,11 @@ struct CoverageFormat1_3 { friend struct Coverage; - protected: + public: HBUINT16 coverageFormat; /* Format identifier--format = 1 */ SortedArray16Of glyphArray; /* Array of GlyphIDs--in numerical order */ - public: + DEFINE_SIZE_ARRAY (4, glyphArray); private: diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh index 0c9bd09cbf7..8287c8d4d4d 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh @@ -40,7 +40,7 @@ struct CoverageFormat2_4 { friend struct Coverage; - protected: + public: HBUINT16 coverageFormat; /* Format identifier--format = 2 */ SortedArray16Of> rangeRecord; /* Array of glyph ranges--ordered by diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh index ceba37b0619..89e110990bc 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh @@ -252,7 +252,7 @@ struct CaretValue hb_codepoint_t glyph_id, const ItemVariationStore &var_store) const { - switch (u.format) { + switch (u.format.v) { case 1: return u.format1.get_caret_value (font, direction); case 2: return u.format2.get_caret_value (font, direction, glyph_id); case 3: return u.format3.get_caret_value (font, direction, var_store); @@ -263,9 +263,9 @@ struct CaretValue template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); case 3: return_trace (c->dispatch (u.format3, std::forward (ds)...)); @@ -275,7 +275,7 @@ struct CaretValue void collect_variation_indices (hb_collect_variation_indices_context_t *c) const { - switch (u.format) { + switch (u.format.v) { case 1: case 2: return; @@ -289,9 +289,9 @@ struct CaretValue bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return_trace (false); + if (!u.format.v.sanitize (c)) return_trace (false); hb_barrier (); - switch (u.format) { + switch (u.format.v) { case 1: return_trace (u.format1.sanitize (c)); case 2: return_trace (u.format2.sanitize (c)); case 3: return_trace (u.format3.sanitize (c)); @@ -301,13 +301,13 @@ struct CaretValue protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ CaretValueFormat1 format1; CaretValueFormat2 format2; CaretValueFormat3 format3; } u; public: - DEFINE_SIZE_UNION (2, format); + DEFINE_SIZE_UNION (2, format.v); }; struct LigGlyph @@ -519,7 +519,7 @@ struct MarkGlyphSets { bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const { - switch (u.format) { + switch (u.format.v) { case 1: return u.format1.covers (set_index, glyph_id); default:return false; } @@ -528,7 +528,7 @@ struct MarkGlyphSets template void collect_coverage (hb_vector_t &sets) const { - switch (u.format) { + switch (u.format.v) { case 1: u.format1.collect_coverage (sets); return; default:return; } @@ -537,7 +537,7 @@ struct MarkGlyphSets void collect_used_mark_sets (const hb_set_t& glyph_set, hb_set_t& used_mark_sets /* OUT */) const { - switch (u.format) { + switch (u.format.v) { case 1: u.format1.collect_used_mark_sets (glyph_set, used_mark_sets); return; default:return; } @@ -546,7 +546,7 @@ struct MarkGlyphSets bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - switch (u.format) { + switch (u.format.v) { case 1: return_trace (u.format1.subset (c)); default:return_trace (false); } @@ -555,9 +555,9 @@ struct MarkGlyphSets bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return_trace (false); + if (!u.format.v.sanitize (c)) return_trace (false); hb_barrier (); - switch (u.format) { + switch (u.format.v) { case 1: return_trace (u.format1.sanitize (c)); default:return_trace (true); } @@ -565,11 +565,11 @@ struct MarkGlyphSets protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ MarkGlyphSetsFormat1 format1; } u; public: - DEFINE_SIZE_UNION (2, format); + DEFINE_SIZE_UNION (2, format.v); }; @@ -977,7 +977,7 @@ struct GDEF } #ifndef HB_NO_GDEF_CACHE - table->get_mark_glyph_sets ().collect_coverage (mark_glyph_set_digests); + table->get_mark_glyph_sets ().collect_coverage (mark_glyph_sets); #endif } ~accelerator_t () { table.destroy (); } @@ -1002,18 +1002,34 @@ struct GDEF } + HB_ALWAYS_INLINE bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const { return #ifndef HB_NO_GDEF_CACHE - mark_glyph_set_digests[set_index].may_have (glyph_id) && + // We can access arrayZ directly because of sanitize_lookup_props() guarantee. + mark_glyph_sets.arrayZ[set_index].may_have (glyph_id) && #endif - table->mark_set_covers (set_index, glyph_id); + table->mark_set_covers (set_index, glyph_id) + ; + } + + unsigned sanitize_lookup_props (unsigned lookup_props) const + { +#ifndef HB_NO_GDEF_CACHE + if (lookup_props & LookupFlag::UseMarkFilteringSet && + (lookup_props >> 16) >= mark_glyph_sets.length) + { + // Invalid mark filtering set index; unset the flag. + lookup_props &= ~LookupFlag::UseMarkFilteringSet; + } +#endif + return lookup_props; } hb_blob_ptr_t table; #ifndef HB_NO_GDEF_CACHE - hb_vector_t mark_glyph_set_digests; + hb_vector_t mark_glyph_sets; mutable hb_cache_t<21, 3> glyph_props_cache; static_assert (sizeof (glyph_props_cache) == 512, ""); #endif diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Anchor.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Anchor.hh index 7802e397f4c..1938803fa7c 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Anchor.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Anchor.hh @@ -13,20 +13,20 @@ struct Anchor { protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ AnchorFormat1 format1; AnchorFormat2 format2; AnchorFormat3 format3; } u; public: - DEFINE_SIZE_UNION (2, format); + DEFINE_SIZE_UNION (2, format.v); bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return_trace (false); + if (!u.format.v.sanitize (c)) return_trace (false); hb_barrier (); - switch (u.format) { + switch (u.format.v) { case 1: return_trace (u.format1.sanitize (c)); case 2: return_trace (u.format2.sanitize (c)); case 3: return_trace (u.format3.sanitize (c)); @@ -38,7 +38,7 @@ struct Anchor float *x, float *y) const { *x = *y = 0; - switch (u.format) { + switch (u.format.v) { case 1: u.format1.get_anchor (c, glyph_id, x, y); return; case 2: u.format2.get_anchor (c, glyph_id, x, y); return; case 3: u.format3.get_anchor (c, glyph_id, x, y); return; @@ -49,7 +49,7 @@ struct Anchor bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - switch (u.format) { + switch (u.format.v) { case 1: return_trace (bool (reinterpret_cast (u.format1.copy (c->serializer)))); case 2: if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING) @@ -66,7 +66,7 @@ struct Anchor void collect_variation_indices (hb_collect_variation_indices_context_t *c) const { - switch (u.format) { + switch (u.format.v) { case 1: case 2: return; case 3: diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorFormat3.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorFormat3.hh index 61bd90310a5..c49705bea0e 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorFormat3.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorFormat3.hh @@ -37,12 +37,12 @@ struct AnchorFormat3 *x = font->em_fscale_x (xCoordinate); *y = font->em_fscale_y (yCoordinate); - if ((font->x_ppem || font->num_coords) && xDeviceTable.sanitize (&c->sanitizer, this)) + if ((font->x_ppem || font->has_nonzero_coords) && xDeviceTable.sanitize (&c->sanitizer, this)) { hb_barrier (); *x += (this+xDeviceTable).get_x_delta (font, c->var_store, c->var_store_cache); } - if ((font->y_ppem || font->num_coords) && yDeviceTable.sanitize (&c->sanitizer, this)) + if ((font->y_ppem || font->has_nonzero_coords) && yDeviceTable.sanitize (&c->sanitizer, this)) { hb_barrier (); *y += (this+yDeviceTable).get_y_delta (font, c->var_store, c->var_store_cache); @@ -91,10 +91,13 @@ struct AnchorFormat3 } } - /* in case that all axes are pinned or no variations after instantiation, - * both var_idxes will be mapped to HB_OT_LAYOUT_NO_VARIATIONS_INDEX */ - if (x_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX && - y_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX) + + bool no_downgrade = (!xDeviceTable.is_null () && !(this+xDeviceTable).is_variation_device ()) || + x_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX || + y_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX || + (!yDeviceTable.is_null () && !(this+yDeviceTable).is_variation_device ()); + + if (!no_downgrade) return_trace (c->serializer->check_assign (out->format, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW)); if (!c->serializer->embed (xDeviceTable)) return_trace (false); diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorMatrix.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorMatrix.hh index 9da9fff50ba..128ced6c176 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorMatrix.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorMatrix.hh @@ -77,6 +77,13 @@ struct AnchorMatrix return_trace (true); } + + bool offset_is_null (unsigned row, unsigned col, unsigned num_cols) const + { + if (unlikely (row >= rows || col >= num_cols)) return true; + auto &offset = matrixZ[row * num_cols + col]; + return offset.is_null (); + } }; diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePos.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePos.hh index 0105a9b8542..38a29dd9ed5 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePos.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePos.hh @@ -11,7 +11,7 @@ struct CursivePos { protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ CursivePosFormat1 format1; } u; @@ -19,9 +19,9 @@ struct CursivePos template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); default:return_trace (c->default_return_value ()); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePosFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePosFormat1.hh index 361aaed658a..f5a09e07d73 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePosFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePosFormat1.hh @@ -50,8 +50,9 @@ struct EntryExitRecord DEFINE_SIZE_STATIC (4); }; -static void -reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction, unsigned int new_parent) { +static inline void +reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction, unsigned int new_parent) +{ int chain = pos[i].attach_chain(), type = pos[i].attach_type(); if (likely (!chain || 0 == (type & ATTACH_TYPE_CURSIVE))) return; @@ -130,7 +131,7 @@ struct CursivePosFormat1 unlikely (!this_record.entryAnchor.sanitize (&c->sanitizer, this))) return_trace (false); hb_barrier (); - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + auto &skippy_iter = c->iter_input; skippy_iter.reset_fast (buffer->idx); unsigned unsafe_from; if (unlikely (!skippy_iter.prev (&unsafe_from))) @@ -229,8 +230,13 @@ struct CursivePosFormat1 */ reverse_cursive_minor_offset (pos, child, c->direction, parent); - pos[child].attach_type() = ATTACH_TYPE_CURSIVE; pos[child].attach_chain() = (int) parent - (int) child; + if (pos[child].attach_chain() != (int) parent - (int) child) + { + pos[child].attach_chain() = 0; + goto overflow; + } + pos[child].attach_type() = ATTACH_TYPE_CURSIVE; buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) pos[child].y_offset = y_offset; @@ -256,6 +262,7 @@ struct CursivePosFormat1 i, j); } + overflow: buffer->idx++; return_trace (true); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/GPOS.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/GPOS.hh index ce3f74d8c3b..b80f606f7b5 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/GPOS.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/GPOS.hh @@ -80,9 +80,8 @@ propagate_attachment_offsets (hb_glyph_position_t *pos, { /* Adjusts offsets of attached glyphs (both cursive and mark) to accumulate * offset of glyph they are attached to. */ - int chain = pos[i].attach_chain(), type = pos[i].attach_type(); - if (likely (!chain)) - return; + int chain = pos[i].attach_chain(); + int type = pos[i].attach_type(); pos[i].attach_chain() = 0; @@ -94,7 +93,8 @@ propagate_attachment_offsets (hb_glyph_position_t *pos, if (unlikely (!nesting_level)) return; - propagate_attachment_offsets (pos, len, j, direction, nesting_level - 1); + if (pos[j].attach_chain()) + propagate_attachment_offsets (pos, len, j, direction, nesting_level - 1); assert (!!(type & GPOS_impl::ATTACH_TYPE_MARK) ^ !!(type & GPOS_impl::ATTACH_TYPE_CURSIVE)); @@ -110,17 +110,37 @@ propagate_attachment_offsets (hb_glyph_position_t *pos, pos[i].x_offset += pos[j].x_offset; pos[i].y_offset += pos[j].y_offset; - assert (j < i); - if (HB_DIRECTION_IS_FORWARD (direction)) - for (unsigned int k = j; k < i; k++) { - pos[i].x_offset -= pos[k].x_advance; - pos[i].y_offset -= pos[k].y_advance; - } - else - for (unsigned int k = j + 1; k < i + 1; k++) { - pos[i].x_offset += pos[k].x_advance; - pos[i].y_offset += pos[k].y_advance; - } + // i is the position of the mark; j is the base. + if (j < i) + { + /* This is the common case: mark follows base. + * And currently the only way in OpenType. */ + if (HB_DIRECTION_IS_FORWARD (direction)) + for (unsigned int k = j; k < i; k++) { + pos[i].x_offset -= pos[k].x_advance; + pos[i].y_offset -= pos[k].y_advance; + } + else + for (unsigned int k = j + 1; k < i + 1; k++) { + pos[i].x_offset += pos[k].x_advance; + pos[i].y_offset += pos[k].y_advance; + } + } + else // j > i + { + /* This can happen with `kerx`: a mark attaching + * to a base after it in the logical order. */ + if (HB_DIRECTION_IS_FORWARD (direction)) + for (unsigned int k = i; k < j; k++) { + pos[i].x_offset += pos[k].x_advance; + pos[i].y_offset += pos[k].y_advance; + } + else + for (unsigned int k = i + 1; k < j + 1; k++) { + pos[i].x_offset -= pos[k].x_advance; + pos[i].y_offset -= pos[k].y_advance; + } + } } } @@ -149,8 +169,20 @@ GPOS::position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer) /* Handle attachments */ if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT) - for (unsigned i = 0; i < len; i++) - propagate_attachment_offsets (pos, len, i, direction); + { + auto *pos = buffer->pos; + // https://github.com/harfbuzz/harfbuzz/issues/5514 + if (HB_DIRECTION_IS_FORWARD (direction)) + { + for (unsigned i = 0; i < len; i++) + if (pos[i].attach_chain()) + propagate_attachment_offsets (pos, len, i, direction); + } else { + for (unsigned i = len; i-- > 0; ) + if (pos[i].attach_chain()) + propagate_attachment_offsets (pos, len, i, direction); + } + } if (unlikely (font->slant_xy) && HB_DIRECTION_IS_HORIZONTAL (direction)) diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/LigatureArray.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/LigatureArray.hh index eecdb95a95f..113b693dc3e 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/LigatureArray.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/LigatureArray.hh @@ -19,22 +19,30 @@ struct LigatureArray : List16OfOffset16To bool subset (hb_subset_context_t *c, Iterator coverage, unsigned class_count, - const hb_map_t *klass_mapping) const + const hb_map_t *klass_mapping, + hb_sorted_vector_t &new_coverage /* OUT */) const { TRACE_SUBSET (this); - const hb_set_t &glyphset = *c->plan->glyphset_gsub (); + const hb_map_t &glyph_map = c->plan->glyph_map_gsub; auto *out = c->serializer->start_embed (this); if (unlikely (!c->serializer->extend_min (out))) return_trace (false); bool ret = false; for (const auto _ : + hb_zip (coverage, *this) - | hb_filter (glyphset, hb_first)) + | hb_filter (glyph_map, hb_first)) { + const LigatureAttach& src = (this + _.second); + bool non_empty = + hb_range (src.rows * class_count) + | hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); }) + | hb_map ([&] (const unsigned index) { return !src.offset_is_null (index / class_count, index % class_count, class_count); }) + | hb_any; + + if (!non_empty) continue; + auto *matrix = out->serialize_append (c->serializer); if (unlikely (!matrix)) return_trace (false); - const LigatureAttach& src = (this + _.second); auto indexes = + hb_range (src.rows * class_count) | hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); }) @@ -44,6 +52,9 @@ struct LigatureArray : List16OfOffset16To this, src.rows, indexes); + + hb_codepoint_t new_gid = glyph_map.get (_.first); + new_coverage.push (new_gid); } return_trace (ret); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkArray.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkArray.hh index abae8f1c607..bddc5e7fe9e 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkArray.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkArray.hh @@ -47,10 +47,15 @@ struct MarkArray : Array16Of /* Array of MarkRecords--in Cove } hb_glyph_position_t &o = buffer->cur_pos(); + o.attach_chain() = (int) glyph_pos - (int) buffer->idx; + if (o.attach_chain() != (int) glyph_pos - (int) buffer->idx) + { + o.attach_chain() = 0; + goto overflow; + } + o.attach_type() = ATTACH_TYPE_MARK; o.x_offset = roundf (base_x - mark_x); o.y_offset = roundf (base_y - mark_y); - o.attach_type() = ATTACH_TYPE_MARK; - o.attach_chain() = (int) glyph_pos - (int) buffer->idx; buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) @@ -60,6 +65,7 @@ struct MarkArray : Array16Of /* Array of MarkRecords--in Cove c->buffer->idx, glyph_pos); } + overflow: buffer->idx++; return_trace (true); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePos.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePos.hh index b1d1118a86b..65f343bda8b 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePos.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePos.hh @@ -11,7 +11,7 @@ struct MarkBasePos { protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ MarkBasePosFormat1_2 format1; #ifndef HB_NO_BEYOND_64K MarkBasePosFormat1_2 format2; @@ -22,9 +22,9 @@ struct MarkBasePos template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); #ifndef HB_NO_BEYOND_64K case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePosFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePosFormat1.hh index e633f7a1be1..ad071f327ea 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePosFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePosFormat1.hh @@ -119,7 +119,7 @@ struct MarkBasePosFormat1_2 /* Now we search backwards for a non-mark glyph. * We don't use skippy_iter.prev() to avoid O(n^2) behavior. */ - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + auto &skippy_iter = c->iter_input; skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); if (c->last_base_until > buffer->idx) @@ -209,19 +209,22 @@ struct MarkBasePosFormat1_2 ; new_coverage.reset (); - + base_iter - | hb_map (hb_first) - | hb_map (glyph_map) - | hb_sink (new_coverage) - ; - - if (!out->baseCoverage.serialize_serialize (c->serializer, new_coverage.iter ())) - return_trace (false); - hb_sorted_vector_t base_indexes; - for (const unsigned row : + base_iter - | hb_map (hb_second)) + auto &base_array = (this+baseArray); + for (const auto _ : + base_iter) { + unsigned row = _.second; + bool non_empty = + hb_range ((unsigned) classCount) + | hb_filter (klass_mapping) + | hb_map ([&] (const unsigned col) { return !base_array.offset_is_null (row, col, (unsigned) classCount); }) + | hb_any + ; + + if (!non_empty) continue; + + hb_codepoint_t new_g = glyph_map.get ( _.first); + new_coverage.push (new_g); + + hb_range ((unsigned) classCount) | hb_filter (klass_mapping) | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; }) @@ -229,8 +232,12 @@ struct MarkBasePosFormat1_2 ; } + if (!new_coverage) return_trace (false); + if (!out->baseCoverage.serialize_serialize (c->serializer, new_coverage.iter ())) + return_trace (false); + return_trace (out->baseArray.serialize_subset (c, baseArray, this, - base_iter.len (), + new_coverage.length, base_indexes.iter ())); } }; diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPos.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPos.hh index b10102880c0..ee237eb479f 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPos.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPos.hh @@ -11,7 +11,7 @@ struct MarkLigPos { protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ MarkLigPosFormat1_2 format1; #ifndef HB_NO_BEYOND_64K MarkLigPosFormat1_2 format2; @@ -22,9 +22,9 @@ struct MarkLigPos template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); #ifndef HB_NO_BEYOND_64K case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPosFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPosFormat1.hh index cf4cbae9a3f..509a26c2485 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPosFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPosFormat1.hh @@ -101,7 +101,7 @@ struct MarkLigPosFormat1_2 /* Now we search backwards for a non-mark glyph */ - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + auto &skippy_iter = c->iter_input; skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); if (c->last_base_until > buffer->idx) @@ -200,19 +200,13 @@ struct MarkLigPosFormat1_2 &klass_mapping))) return_trace (false); - auto new_ligature_coverage = - + hb_iter (this + ligatureCoverage) - | hb_take ((this + ligatureArray).len) - | hb_map_retains_sorting (glyph_map) - | hb_filter ([] (hb_codepoint_t glyph) { return glyph != HB_MAP_VALUE_INVALID; }) - ; - - if (!out->ligatureCoverage.serialize_serialize (c->serializer, new_ligature_coverage)) + hb_sorted_vector_t new_lig_coverage; + if (!out->ligatureArray.serialize_subset (c, ligatureArray, this, + hb_iter (this+ligatureCoverage), + classCount, &klass_mapping, new_lig_coverage)) return_trace (false); - return_trace (out->ligatureArray.serialize_subset (c, ligatureArray, this, - hb_iter (this+ligatureCoverage), - classCount, &klass_mapping)); + return_trace (out->ligatureCoverage.serialize_serialize (c->serializer, new_lig_coverage.iter ())); } }; diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPos.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPos.hh index e0d9eca0280..c06f013cdce 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPos.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPos.hh @@ -11,7 +11,7 @@ struct MarkMarkPos { protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ MarkMarkPosFormat1_2 format1; #ifndef HB_NO_BEYOND_64K MarkMarkPosFormat1_2 format2; @@ -22,9 +22,9 @@ struct MarkMarkPos template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); #ifndef HB_NO_BEYOND_64K case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPosFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPosFormat1.hh index 6519e79b443..c93dbbb3f06 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPosFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPosFormat1.hh @@ -100,7 +100,7 @@ struct MarkMarkPosFormat1_2 if (likely (mark1_index == NOT_COVERED)) return_trace (false); /* now we search backwards for a suitable mark glyph until a non-mark glyph */ - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + auto &skippy_iter = c->iter_input; skippy_iter.reset_fast (buffer->idx); skippy_iter.set_lookup_props (c->lookup_props & ~(uint32_t)LookupFlag::IgnoreFlags); unsigned unsafe_from; @@ -196,19 +196,23 @@ struct MarkMarkPosFormat1_2 ; new_coverage.reset (); - + mark2_iter - | hb_map (hb_first) - | hb_map (glyph_map) - | hb_sink (new_coverage) - ; - - if (!out->mark2Coverage.serialize_serialize (c->serializer, new_coverage.iter ())) - return_trace (false); - hb_sorted_vector_t mark2_indexes; - for (const unsigned row : + mark2_iter - | hb_map (hb_second)) + auto &mark2_array = (this+mark2Array); + for (const auto _ : + mark2_iter) { + unsigned row = _.second; + + bool non_empty = + hb_range ((unsigned) classCount) + | hb_filter (klass_mapping) + | hb_map ([&] (const unsigned col) { return !mark2_array.offset_is_null (row, col, (unsigned) classCount); }) + | hb_any + ; + + if (!non_empty) continue; + + hb_codepoint_t new_g = glyph_map.get ( _.first); + new_coverage.push (new_g); + + hb_range ((unsigned) classCount) | hb_filter (klass_mapping) | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; }) @@ -216,6 +220,10 @@ struct MarkMarkPosFormat1_2 ; } + if (!new_coverage) return_trace (false); + if (!out->mark2Coverage.serialize_serialize (c->serializer, new_coverage.iter ())) + return_trace (false); + return_trace (out->mark2Array.serialize_subset (c, mark2Array, this, mark2_iter.len (), mark2_indexes.iter ())); diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPos.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPos.hh index e3794ea9ed5..bf7fff7face 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPos.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPos.hh @@ -12,7 +12,7 @@ struct PairPos { protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ PairPosFormat1_3 format1; PairPosFormat2_4 format2; #ifndef HB_NO_BEYOND_64K @@ -25,9 +25,9 @@ struct PairPos template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); #ifndef HB_NO_BEYOND_64K diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh index 2748882f527..1c067bde86f 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh @@ -103,52 +103,35 @@ struct PairPosFormat1_3 const Coverage &get_coverage () const { return this+coverage; } - unsigned cache_cost () const + struct external_cache_t { - return (this+coverage).cost (); - } - static void * cache_func (void *p, hb_ot_lookup_cache_op_t op) + hb_ot_layout_mapping_cache_t coverage; + }; + void *external_cache_create () const { - switch (op) + external_cache_t *cache = (external_cache_t *) hb_malloc (sizeof (external_cache_t)); + if (likely (cache)) { - case hb_ot_lookup_cache_op_t::CREATE: - { - hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) hb_malloc (sizeof (hb_ot_lookup_cache_t)); - if (likely (cache)) - cache->clear (); - return cache; - } - case hb_ot_lookup_cache_op_t::ENTER: - return (void *) true; - case hb_ot_lookup_cache_op_t::LEAVE: - return nullptr; - case hb_ot_lookup_cache_op_t::DESTROY: - { - hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) p; - hb_free (cache); - return nullptr; - } + cache->coverage.clear (); } - return nullptr; + return cache; } - bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } - bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); } - bool _apply (hb_ot_apply_context_t *c, bool cached) const + bool apply (hb_ot_apply_context_t *c, void *external_cache) const { TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE - hb_ot_lookup_cache_t *cache = cached ? (hb_ot_lookup_cache_t *) c->lookup_accel->cache : nullptr; - unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint, cache); + external_cache_t *cache = (external_cache_t *) external_cache; + unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint, cache ? &cache->coverage : nullptr); #else unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); #endif if (index == NOT_COVERED) return_trace (false); - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + auto &skippy_iter = c->iter_input; skippy_iter.reset_fast (buffer->idx); unsigned unsafe_to; if (unlikely (!skippy_iter.next (&unsafe_to))) diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat2.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat2.hh index d85b1ac2c17..ce731450f41 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat2.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat2.hh @@ -123,63 +123,39 @@ struct PairPosFormat2_4 : ValueBase const Coverage &get_coverage () const { return this+coverage; } - struct pair_pos_cache_t + struct external_cache_t { - hb_ot_lookup_cache_t coverage; - hb_ot_lookup_cache_t first; - hb_ot_lookup_cache_t second; + hb_ot_layout_mapping_cache_t coverage; + hb_ot_layout_mapping_cache_t first; + hb_ot_layout_mapping_cache_t second; }; - - unsigned cache_cost () const + void *external_cache_create () const { - return (this+coverage).cost () + (this+classDef1).cost () + (this+classDef2).cost (); - } - static void * cache_func (void *p, hb_ot_lookup_cache_op_t op) - { - switch (op) + external_cache_t *cache = (external_cache_t *) hb_malloc (sizeof (external_cache_t)); + if (likely (cache)) { - case hb_ot_lookup_cache_op_t::CREATE: - { - pair_pos_cache_t *cache = (pair_pos_cache_t *) hb_malloc (sizeof (pair_pos_cache_t)); - if (likely (cache)) - { - cache->coverage.clear (); - cache->first.clear (); - cache->second.clear (); - } - return cache; - } - case hb_ot_lookup_cache_op_t::ENTER: - return (void *) true; - case hb_ot_lookup_cache_op_t::LEAVE: - return nullptr; - case hb_ot_lookup_cache_op_t::DESTROY: - { - pair_pos_cache_t *cache = (pair_pos_cache_t *) p; - hb_free (cache); - return nullptr; - } + cache->coverage.clear (); + cache->first.clear (); + cache->second.clear (); } - return nullptr; + return cache; } - bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } - bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); } - bool _apply (hb_ot_apply_context_t *c, bool cached) const + bool apply (hb_ot_apply_context_t *c, void *external_cache) const { TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE - pair_pos_cache_t *cache = cached ? (pair_pos_cache_t *) c->lookup_accel->cache : nullptr; + external_cache_t *cache = (external_cache_t *) external_cache; unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint, cache ? &cache->coverage : nullptr); #else unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); #endif if (index == NOT_COVERED) return_trace (false); - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + auto &skippy_iter = c->iter_input; skippy_iter.reset_fast (buffer->idx); unsigned unsafe_to; if (unlikely (!skippy_iter.next (&unsafe_to))) diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePos.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePos.hh index a0243a218c5..30fc1aacda8 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePos.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePos.hh @@ -12,7 +12,7 @@ struct SinglePos { protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ SinglePosFormat1 format1; SinglePosFormat2 format2; } u; @@ -41,7 +41,7 @@ struct SinglePos const hb_hashmap_t> *layout_variation_idx_delta_map, unsigned newFormat) { - if (unlikely (!c->extend_min (u.format))) return; + if (unlikely (!c->extend_min (u.format.v))) return; unsigned format = 2; ValueFormat new_format; new_format = newFormat; @@ -49,8 +49,8 @@ struct SinglePos if (glyph_val_iter_pairs) format = get_format (glyph_val_iter_pairs); - u.format = format; - switch (u.format) { + u.format.v = format; + switch (u.format.v) { case 1: u.format1.serialize (c, src, glyph_val_iter_pairs, @@ -70,9 +70,9 @@ struct SinglePos template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); default:return_trace (c->default_return_value ()); diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/ValueFormat.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/ValueFormat.hh index 731d1ffca1a..b961a5139d8 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/ValueFormat.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/ValueFormat.hh @@ -56,9 +56,14 @@ struct ValueFormat : HBUINT16 * PosTable (may be NULL) */ #endif - IntType& operator = (uint16_t i) { v = i; return *this; } + NumType& operator = (uint16_t i) { v = i; return *this; } - unsigned int get_len () const { return hb_popcount ((unsigned int) *this); } + // Note: spec says skip 2 bytes per bit in the valueformat. But reports + // from Microsoft developers indicate that only the fields that are + // currently defined are counted. We don't expect any new fields to + // be added to ValueFormat. As such, we use the faster hb_popcount8 + // that only processes the lowest 8 bits. + unsigned int get_len () const { return hb_popcount8 ((uint8_t) *this); } unsigned int get_size () const { return get_len () * Value::static_size; } hb_vector_t get_device_table_indices () const { @@ -111,8 +116,8 @@ struct ValueFormat : HBUINT16 if (!has_device ()) return ret; - bool use_x_device = font->x_ppem || font->num_coords; - bool use_y_device = font->y_ppem || font->num_coords; + bool use_x_device = font->x_ppem || font->has_nonzero_coords; + bool use_y_device = font->y_ppem || font->has_nonzero_coords; if (!use_x_device && !use_y_device) return ret; diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSet.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSet.hh index b5d506f36f9..f13c5e7e251 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSet.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSet.hh @@ -91,6 +91,19 @@ struct AlternateSet return alternates.len; } + void + collect_alternates (hb_codepoint_t gid, + hb_map_t *alternate_count /* IN/OUT */, + hb_map_t *alternate_glyphs /* IN/OUT */) const + { + + hb_enumerate (alternates) + | hb_map ([gid] (hb_pair_t _) { return hb_pair (gid + (_.first << 24), _.second); }) + | hb_apply ([&] (const hb_pair_t &p) -> void + { _hb_collect_glyph_alternates_add (p.first, p.second, + alternate_count, alternate_glyphs); }) + ; + } + template bool serialize (hb_serialize_context_t *c, diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubst.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubst.hh index 8951f5a7a17..a43c75c8f4e 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubst.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubst.hh @@ -12,7 +12,7 @@ struct AlternateSubst { protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ AlternateSubstFormat1_2 format1; #ifndef HB_NO_BEYOND_64K AlternateSubstFormat1_2 format2; @@ -23,9 +23,9 @@ struct AlternateSubst template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); #ifndef HB_NO_BEYOND_64K case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); @@ -42,10 +42,10 @@ struct AlternateSubst hb_array_t alternate_glyphs_list) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (u.format))) return_trace (false); + if (unlikely (!c->extend_min (u.format.v))) return_trace (false); unsigned int format = 1; - u.format = format; - switch (u.format) { + u.format.v = format; + switch (u.format.v) { case 1: return_trace (u.format1.serialize (c, glyphs, alternate_len_list, alternate_glyphs_list)); default:return_trace (false); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubstFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubstFormat1.hh index 421a6e06627..7a3a2511b7f 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubstFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubstFormat1.hh @@ -69,6 +69,19 @@ struct AlternateSubstFormat1_2 { return (this+alternateSet[(this+coverage).get_coverage (gid)]) .get_alternates (start_offset, alternate_count, alternate_glyphs); } + void + collect_glyph_alternates (hb_map_t *alternate_count /* IN/OUT */, + hb_map_t *alternate_glyphs /* IN/OUT */) const + { + + hb_iter (alternateSet) + | hb_map (hb_add (this)) + | hb_zip (this+coverage) + | hb_apply ([&] (const hb_pair_t &, hb_codepoint_t> _) { + _.first.collect_alternates (_.second, alternate_count, alternate_glyphs); + }) + ; + } + bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh index 726da458fac..7bc98d31f32 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh @@ -44,6 +44,18 @@ struct Ligature c->output->add (ligGlyph); } + template + void collect_second (set_t &s) const + { + if (unlikely (!component.get_length ())) + { + // A ligature without any components. Anything matches. + s = set_t::full (); + return; + } + s.add (component.arrayZ[0]); + } + bool would_apply (hb_would_apply_context_t *c) const { if (c->len != component.lenP1) @@ -91,15 +103,6 @@ struct Ligature unsigned int total_component_count = 0; if (unlikely (count > HB_MAX_CONTEXT_LENGTH)) return false; - unsigned match_positions_stack[4]; - unsigned *match_positions = match_positions_stack; - if (unlikely (count > ARRAY_LENGTH (match_positions_stack))) - { - match_positions = (unsigned *) hb_malloc (hb_max (count, 1u) * sizeof (unsigned)); - if (unlikely (!match_positions)) - return_trace (false); - } - unsigned int match_end = 0; if (likely (!match_input (c, count, @@ -107,12 +110,9 @@ struct Ligature match_glyph, nullptr, &match_end, - match_positions, &total_component_count))) { c->buffer->unsafe_to_concat (c->buffer->idx, match_end); - if (match_positions != match_positions_stack) - hb_free (match_positions); return_trace (false); } @@ -129,10 +129,10 @@ struct Ligature match_end += delta; for (unsigned i = 0; i < count; i++) { - match_positions[i] += delta; + c->match_positions[i] += delta; if (i) *p++ = ','; - snprintf (p, sizeof(buf) - (p - buf), "%u", match_positions[i]); + snprintf (p, sizeof(buf) - (p - buf), "%u", c->match_positions[i]); p += strlen(p); } @@ -143,7 +143,6 @@ struct Ligature ligate_input (c, count, - match_positions, match_end, ligGlyph, total_component_count); @@ -156,8 +155,6 @@ struct Ligature pos); } - if (match_positions != match_positions_stack) - hb_free (match_positions); return_trace (true); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSet.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSet.hh index ff0ffce94d7..81c5c2bcfe4 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSet.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSet.hh @@ -11,11 +11,11 @@ namespace GSUB_impl { template struct LigatureSet { - protected: + public: Array16OfOffset16To> ligature; /* Array LigatureSet tables * ordered by preference */ - public: + DEFINE_SIZE_ARRAY (2, ligature); bool sanitize (hb_sanitize_context_t *c) const @@ -62,6 +62,15 @@ struct LigatureSet ; } + template + void collect_seconds (set_t &s) const + { + + hb_iter (ligature) + | hb_map (hb_add (this)) + | hb_apply ([&s] (const Ligature &_) { _.collect_second (s); }) + ; + } + bool would_apply (hb_would_apply_context_t *c) const { return @@ -72,14 +81,14 @@ struct LigatureSet ; } - bool apply (hb_ot_apply_context_t *c) const + bool apply (hb_ot_apply_context_t *c, const hb_set_digest_t *seconds = nullptr) const { TRACE_APPLY (this); unsigned int num_ligs = ligature.len; #ifndef HB_NO_OT_RULESETS_FAST_PATH - if (HB_OPTIMIZE_SIZE_VAL || num_ligs <= 4) + if (HB_OPTIMIZE_SIZE_VAL || num_ligs <= 1) #endif { slow: @@ -91,21 +100,21 @@ struct LigatureSet return_trace (false); } - /* This version is optimized for speed by matching the first component + /* This version is optimized for speed by matching the second component * of the ligature here, instead of calling into the ligation code. * * This is replicated in ChainRuleSet and RuleSet. */ - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + auto &skippy_iter = c->iter_context; skippy_iter.reset (c->buffer->idx); skippy_iter.set_match_func (match_always, nullptr); skippy_iter.set_glyph_data ((HBUINT16 *) nullptr); unsigned unsafe_to; - hb_codepoint_t first = (unsigned) -1; + hb_codepoint_t second = (unsigned) -1; bool matched = skippy_iter.next (&unsafe_to); if (likely (matched)) { - first = c->buffer->info[skippy_iter.idx].codepoint; + second = c->buffer->info[skippy_iter.idx].codepoint; unsafe_to = skippy_iter.idx + 1; if (skippy_iter.may_skip (c->buffer->info[skippy_iter.idx])) @@ -118,13 +127,14 @@ struct LigatureSet else goto slow; + if (seconds && !seconds->may_have (second)) + return_trace (false); bool unsafe_to_concat = false; - for (unsigned int i = 0; i < num_ligs; i++) { const auto &lig = this+ligature.arrayZ[i]; if (unlikely (lig.component.lenP1 <= 1) || - lig.component.arrayZ[0] == first) + lig.component.arrayZ[0] == second) { if (lig.apply (c)) { diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubst.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubst.hh index cffa910295f..22ce9b79d7f 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubst.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubst.hh @@ -12,7 +12,7 @@ struct LigatureSubst { protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ LigatureSubstFormat1_2 format1; #ifndef HB_NO_BEYOND_64K LigatureSubstFormat1_2 format2; @@ -23,9 +23,9 @@ struct LigatureSubst template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); #ifndef HB_NO_BEYOND_64K case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); @@ -45,10 +45,10 @@ struct LigatureSubst hb_array_t component_list /* Starting from second for each ligature */) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (u.format))) return_trace (false); + if (unlikely (!c->extend_min (u.format.v))) return_trace (false); unsigned int format = 1; - u.format = format; - switch (u.format) { + u.format.v = format; + switch (u.format.v) { case 1: return_trace (u.format1.serialize (c, first_glyphs, ligature_per_first_glyph_count_list, diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubstFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubstFormat1.hh index 6ae24b33754..909ddca220f 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubstFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubstFormat1.hh @@ -78,52 +78,44 @@ struct LigatureSubstFormat1_2 return lig_set.would_apply (c); } - unsigned cache_cost () const + struct external_cache_t { - return (this+coverage).cost (); - } - static void * cache_func (void *p, hb_ot_lookup_cache_op_t op) + hb_ot_layout_mapping_cache_t coverage; + hb_set_digest_t seconds; + }; + void *external_cache_create () const { - switch (op) + external_cache_t *cache = (external_cache_t *) hb_malloc (sizeof (external_cache_t)); + if (likely (cache)) { - case hb_ot_lookup_cache_op_t::CREATE: - { - hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) hb_malloc (sizeof (hb_ot_lookup_cache_t)); - if (likely (cache)) - cache->clear (); - return cache; - } - case hb_ot_lookup_cache_op_t::ENTER: - return (void *) true; - case hb_ot_lookup_cache_op_t::LEAVE: - return nullptr; - case hb_ot_lookup_cache_op_t::DESTROY: - { - hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) p; - hb_free (cache); - return nullptr; - } + cache->coverage.clear (); + + cache->seconds.init (); + + hb_iter (ligatureSet) + | hb_map (hb_add (this)) + | hb_apply ([cache] (const LigatureSet &_) { _.collect_seconds (cache->seconds); }) + ; } - return nullptr; + return cache; } - bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } - bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); } - bool _apply (hb_ot_apply_context_t *c, bool cached) const + bool apply (hb_ot_apply_context_t *c, void *external_cache) const { TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE - hb_ot_lookup_cache_t *cache = cached ? (hb_ot_lookup_cache_t *) c->lookup_accel->cache : nullptr; - unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint, cache); + external_cache_t *cache = (external_cache_t *) external_cache; + const hb_set_digest_t *seconds = cache ? &cache->seconds : nullptr; + unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint, cache ? &cache->coverage : nullptr); #else - unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); + const hb_set_digest_t *seconds = nullptr; + unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); #endif if (index == NOT_COVERED) return_trace (false); const auto &lig_set = this+ligatureSet[index]; - return_trace (lig_set.apply (c)); + return_trace (lig_set.apply (c, seconds)); } bool serialize (hb_serialize_context_t *c, diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/MultipleSubst.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/MultipleSubst.hh index cf3d754e3cc..8fb663825b5 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/MultipleSubst.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/MultipleSubst.hh @@ -12,7 +12,7 @@ struct MultipleSubst { protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ MultipleSubstFormat1_2 format1; #ifndef HB_NO_BEYOND_64K MultipleSubstFormat1_2 format2; @@ -24,9 +24,9 @@ struct MultipleSubst template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); #ifndef HB_NO_BEYOND_64K case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); @@ -41,10 +41,10 @@ struct MultipleSubst Iterator it) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (u.format))) return_trace (false); + if (unlikely (!c->extend_min (u.format.v))) return_trace (false); unsigned int format = 1; - u.format = format; - switch (u.format) { + u.format.v = format; + switch (u.format.v) { case 1: return_trace (u.format1.serialize (c, it)); default:return_trace (false); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubst.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubst.hh index 5ad463fea79..e33148d770b 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubst.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubst.hh @@ -12,7 +12,7 @@ struct ReverseChainSingleSubst { protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ ReverseChainSingleSubstFormat1 format1; } u; @@ -20,9 +20,9 @@ struct ReverseChainSingleSubst template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); default:return_trace (c->default_return_value ()); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Sequence.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Sequence.hh index a5e93a98bef..b3295bee16d 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Sequence.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Sequence.hh @@ -115,7 +115,7 @@ struct Sequence for (unsigned i = c->buffer->idx - count; i < c->buffer->idx; i++) { - if (buf < p) + if (buf < p && sizeof(buf) - 1u > unsigned (p - buf)) *p++ = ','; snprintf (p, sizeof(buf) - (p - buf), "%u", i); p += strlen(p); diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubst.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubst.hh index b84259e7f00..323eb4d0f90 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubst.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubst.hh @@ -13,7 +13,7 @@ struct SingleSubst { protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ SingleSubstFormat1_3 format1; SingleSubstFormat2_4 format2; #ifndef HB_NO_BEYOND_64K @@ -27,9 +27,9 @@ struct SingleSubst template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); #ifndef HB_NO_BEYOND_64K @@ -47,7 +47,7 @@ struct SingleSubst Iterator glyphs) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (u.format))) return_trace (false); + if (unlikely (!c->extend_min (u.format.v))) return_trace (false); unsigned format = 2; unsigned delta = 0; if (glyphs) @@ -71,8 +71,8 @@ struct SingleSubst if (!hb_all (++(+glyphs), delta, get_delta)) format += 1; } - u.format = format; - switch (u.format) { + u.format.v = format; + switch (u.format.v) { case 1: return_trace (u.format1.serialize (c, + glyphs | hb_map_retains_sorting (hb_first), diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat1.hh index be6cd820d28..5ee2c1d1f46 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat1.hh @@ -123,6 +123,21 @@ struct SingleSubstFormat1_3 return 1; } + void + collect_glyph_alternates (hb_map_t *alternate_count /* IN/OUT */, + hb_map_t *alternate_glyphs /* IN/OUT */) const + { + hb_codepoint_t d = deltaGlyphID; + hb_codepoint_t mask = get_mask (); + + + hb_iter (this+coverage) + | hb_map ([d, mask] (hb_codepoint_t g) { return hb_pair (g, (g + d) & mask); }) + | hb_apply ([&] (const hb_pair_t &p) -> void + { _hb_collect_glyph_alternates_add (p.first, p.second, + alternate_count, alternate_glyphs); }) + ; + } + bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat2.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat2.hh index e9096460451..0d51d130fee 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat2.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat2.hh @@ -100,6 +100,17 @@ struct SingleSubstFormat2_4 return 1; } + void + collect_glyph_alternates (hb_map_t *alternate_count /* IN/OUT */, + hb_map_t *alternate_glyphs /* IN/OUT */) const + { + + hb_zip (this+coverage, substitute) + | hb_apply ([&] (const hb_pair_t &p) -> void + { _hb_collect_glyph_alternates_add (p.first, p.second, + alternate_count, alternate_glyphs); }) + ; + } + bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/types.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/types.hh index 527f64114b4..5cf9eb368aa 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/types.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/types.hh @@ -29,8 +29,11 @@ #ifndef OT_LAYOUT_TYPES_HH #define OT_LAYOUT_TYPES_HH -using hb_ot_lookup_cache_t = hb_cache_t<15, 8, 7>; -static_assert (sizeof (hb_ot_lookup_cache_t) == 256, ""); +using hb_ot_layout_mapping_cache_t = hb_cache_t<16, 8, 8>; +static_assert (sizeof (hb_ot_layout_mapping_cache_t) == 512, ""); + +using hb_ot_layout_binary_cache_t = hb_cache_t<14, 1, 8>; +static_assert (sizeof (hb_ot_layout_binary_cache_t) == 256, ""); namespace OT { namespace Layout { diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/VARC.cc b/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/VARC.cc new file mode 100644 index 00000000000..f0e7f934579 --- /dev/null +++ b/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/VARC.cc @@ -0,0 +1,421 @@ +#include "VARC.hh" + +#ifndef HB_NO_VAR_COMPOSITES + +#include "../../../hb-draw.hh" +#include "../../../hb-ot-layout-common.hh" +#include "../../../hb-ot-layout-gdef-table.hh" + +namespace OT { + +//namespace Var { + + +#ifndef HB_NO_DRAW + +struct hb_transforming_pen_context_t +{ + hb_transform_t<> transform; + hb_draw_funcs_t *dfuncs; + void *data; + hb_draw_state_t *st; +}; + +static void +hb_transforming_pen_move_to (hb_draw_funcs_t *dfuncs HB_UNUSED, + void *data, + hb_draw_state_t *st, + float to_x, float to_y, + void *user_data HB_UNUSED) +{ + hb_transforming_pen_context_t *c = (hb_transforming_pen_context_t *) data; + + c->transform.transform_point (to_x, to_y); + + c->dfuncs->move_to (c->data, *c->st, to_x, to_y); +} + +static void +hb_transforming_pen_line_to (hb_draw_funcs_t *dfuncs HB_UNUSED, + void *data, + hb_draw_state_t *st, + float to_x, float to_y, + void *user_data HB_UNUSED) +{ + hb_transforming_pen_context_t *c = (hb_transforming_pen_context_t *) data; + + c->transform.transform_point (to_x, to_y); + + c->dfuncs->line_to (c->data, *c->st, to_x, to_y); +} + +static void +hb_transforming_pen_quadratic_to (hb_draw_funcs_t *dfuncs HB_UNUSED, + void *data, + hb_draw_state_t *st, + float control_x, float control_y, + float to_x, float to_y, + void *user_data HB_UNUSED) +{ + hb_transforming_pen_context_t *c = (hb_transforming_pen_context_t *) data; + + c->transform.transform_point (control_x, control_y); + c->transform.transform_point (to_x, to_y); + + c->dfuncs->quadratic_to (c->data, *c->st, control_x, control_y, to_x, to_y); +} + +static void +hb_transforming_pen_cubic_to (hb_draw_funcs_t *dfuncs HB_UNUSED, + void *data, + hb_draw_state_t *st, + float control1_x, float control1_y, + float control2_x, float control2_y, + float to_x, float to_y, + void *user_data HB_UNUSED) +{ + hb_transforming_pen_context_t *c = (hb_transforming_pen_context_t *) data; + + c->transform.transform_point (control1_x, control1_y); + c->transform.transform_point (control2_x, control2_y); + c->transform.transform_point (to_x, to_y); + + c->dfuncs->cubic_to (c->data, *c->st, control1_x, control1_y, control2_x, control2_y, to_x, to_y); +} + +static void +hb_transforming_pen_close_path (hb_draw_funcs_t *dfuncs HB_UNUSED, + void *data, + hb_draw_state_t *st, + void *user_data HB_UNUSED) +{ + hb_transforming_pen_context_t *c = (hb_transforming_pen_context_t *) data; + + c->dfuncs->close_path (c->data, *c->st); +} + +static inline void free_static_transforming_pen_funcs (); + +static struct hb_transforming_pen_funcs_lazy_loader_t : hb_draw_funcs_lazy_loader_t +{ + static hb_draw_funcs_t *create () + { + hb_draw_funcs_t *funcs = hb_draw_funcs_create (); + + hb_draw_funcs_set_move_to_func (funcs, hb_transforming_pen_move_to, nullptr, nullptr); + hb_draw_funcs_set_line_to_func (funcs, hb_transforming_pen_line_to, nullptr, nullptr); + hb_draw_funcs_set_quadratic_to_func (funcs, hb_transforming_pen_quadratic_to, nullptr, nullptr); + hb_draw_funcs_set_cubic_to_func (funcs, hb_transforming_pen_cubic_to, nullptr, nullptr); + hb_draw_funcs_set_close_path_func (funcs, hb_transforming_pen_close_path, nullptr, nullptr); + + hb_draw_funcs_make_immutable (funcs); + + hb_atexit (free_static_transforming_pen_funcs); + + return funcs; + } +} static_transforming_pen_funcs; + +static inline +void free_static_transforming_pen_funcs () +{ + static_transforming_pen_funcs.free_instance (); +} + +static hb_draw_funcs_t * +hb_transforming_pen_get_funcs () +{ + return static_transforming_pen_funcs.get_unconst (); +} + +hb_ubytes_t +VarComponent::get_path_at (const hb_varc_context_t &c, + hb_codepoint_t parent_gid, + hb_array_t coords, + hb_transform_t<> total_transform, + hb_ubytes_t total_record, + hb_scalar_cache_t *cache) const +{ + const unsigned char *end = total_record.arrayZ + total_record.length; + const unsigned char *record = total_record.arrayZ; + + auto &VARC = *c.font->face->table.VARC->table; + auto &varStore = &VARC+VARC.varStore; + +#define READ_UINT32VAR(name) \ + HB_STMT_START { \ + if (unlikely (unsigned (end - record) < HBUINT32VAR::min_size)) return hb_ubytes_t (); \ + hb_barrier (); \ + auto &varint = * (const HBUINT32VAR *) record; \ + unsigned size = varint.get_size (); \ + if (unlikely (unsigned (end - record) < size)) return hb_ubytes_t (); \ + name = (uint32_t) varint; \ + record += size; \ + } HB_STMT_END + + uint32_t flags; + READ_UINT32VAR (flags); + + // gid + + hb_codepoint_t gid = 0; + if (flags & (unsigned) flags_t::GID_IS_24BIT) + { + if (unlikely (unsigned (end - record) < HBGlyphID24::static_size)) + return hb_ubytes_t (); + hb_barrier (); + gid = * (const HBGlyphID24 *) record; + record += HBGlyphID24::static_size; + } + else + { + if (unlikely (unsigned (end - record) < HBGlyphID16::static_size)) + return hb_ubytes_t (); + hb_barrier (); + gid = * (const HBGlyphID16 *) record; + record += HBGlyphID16::static_size; + } + + // Condition + bool show = true; + if (flags & (unsigned) flags_t::HAVE_CONDITION) + { + unsigned conditionIndex; + READ_UINT32VAR (conditionIndex); + const auto &condition = (&VARC+VARC.conditionList)[conditionIndex]; + auto instancer = MultiItemVarStoreInstancer(&varStore, nullptr, coords, cache); + show = condition.evaluate (coords.arrayZ, coords.length, &instancer); + } + + // Axis values + + auto &axisIndices = c.scratch.axisIndices; + axisIndices.clear (); + auto &axisValues = c.scratch.axisValues; + axisValues.clear (); + if (flags & (unsigned) flags_t::HAVE_AXES) + { + unsigned axisIndicesIndex; + READ_UINT32VAR (axisIndicesIndex); + axisIndices.extend ((&VARC+VARC.axisIndicesList)[axisIndicesIndex]); + axisValues.resize (axisIndices.length); + const HBUINT8 *p = (const HBUINT8 *) record; + TupleValues::decompile (p, axisValues, (const HBUINT8 *) end); + record = (const unsigned char *) p; + } + + // Apply variations if any + if (flags & (unsigned) flags_t::AXIS_VALUES_HAVE_VARIATION) + { + uint32_t axisValuesVarIdx; + READ_UINT32VAR (axisValuesVarIdx); + if (show && coords && !axisValues.in_error ()) + varStore.get_delta (axisValuesVarIdx, coords, axisValues.as_array (), cache); + } + + auto component_coords = coords; + /* Copying coords is expensive; so we have put an arbitrary + * limit on the max number of coords for now. */ + if ((flags & (unsigned) flags_t::RESET_UNSPECIFIED_AXES) || + coords.length > HB_VAR_COMPOSITE_MAX_AXES) + component_coords = hb_array (c.font->coords, c.font->num_coords); + + // Transform + + uint32_t transformVarIdx = VarIdx::NO_VARIATION; + if (flags & (unsigned) flags_t::TRANSFORM_HAS_VARIATION) + READ_UINT32VAR (transformVarIdx); + +#define PROCESS_TRANSFORM_COMPONENTS \ + HB_STMT_START { \ + PROCESS_TRANSFORM_COMPONENT (FWORD, 1.0f, HAVE_TRANSLATE_X, translateX); \ + PROCESS_TRANSFORM_COMPONENT (FWORD, 1.0f, HAVE_TRANSLATE_Y, translateY); \ + PROCESS_TRANSFORM_COMPONENT (F4DOT12, HB_PI, HAVE_ROTATION, rotation); \ + PROCESS_TRANSFORM_COMPONENT (F6DOT10, 1.0f, HAVE_SCALE_X, scaleX); \ + PROCESS_TRANSFORM_COMPONENT (F6DOT10, 1.0f, HAVE_SCALE_Y, scaleY); \ + PROCESS_TRANSFORM_COMPONENT (F4DOT12, HB_PI, HAVE_SKEW_X, skewX); \ + PROCESS_TRANSFORM_COMPONENT (F4DOT12, HB_PI, HAVE_SKEW_Y, skewY); \ + PROCESS_TRANSFORM_COMPONENT (FWORD, 1.0f, HAVE_TCENTER_X, tCenterX); \ + PROCESS_TRANSFORM_COMPONENT (FWORD, 1.0f, HAVE_TCENTER_Y, tCenterY); \ + } HB_STMT_END + + hb_transform_decomposed_t<> transform; + + // Read transform components +#define PROCESS_TRANSFORM_COMPONENT(type, mult, flag, name) \ + if (flags & (unsigned) flags_t::flag) \ + { \ + static_assert (type::static_size == HBINT16::static_size, ""); \ + if (unlikely (unsigned (end - record) < HBINT16::static_size)) \ + return hb_ubytes_t (); \ + hb_barrier (); \ + transform.name = mult * * (const HBINT16 *) record; \ + record += HBINT16::static_size; \ + } + PROCESS_TRANSFORM_COMPONENTS; +#undef PROCESS_TRANSFORM_COMPONENT + + // Read reserved records + unsigned i = flags & (unsigned) flags_t::RESERVED_MASK; + while (i) + { + HB_UNUSED uint32_t discard; + READ_UINT32VAR (discard); + i &= i - 1; + } + + /* Parsing is over now. */ + + if (show) + { + // Only use coord_setter if there's actually any axis overrides. + coord_setter_t coord_setter (axisIndices ? component_coords : hb_array ()); + // Go backwards, to reduce coord_setter vector reallocations. + for (unsigned i = axisIndices.length; i; i--) + coord_setter[axisIndices[i - 1]] = axisValues[i - 1]; + if (axisIndices) + component_coords = coord_setter.get_coords (); + + // Apply transform variations if any + if (transformVarIdx != VarIdx::NO_VARIATION && coords) + { + float transformValues[9]; + unsigned numTransformValues = 0; +#define PROCESS_TRANSFORM_COMPONENT(type, mult, flag, name) \ + if (flags & (unsigned) flags_t::flag) \ + transformValues[numTransformValues++] = transform.name / mult; + PROCESS_TRANSFORM_COMPONENTS; +#undef PROCESS_TRANSFORM_COMPONENT + varStore.get_delta (transformVarIdx, coords, hb_array (transformValues, numTransformValues), cache); + numTransformValues = 0; +#define PROCESS_TRANSFORM_COMPONENT(type, mult, flag, name) \ + if (flags & (unsigned) flags_t::flag) \ + transform.name = transformValues[numTransformValues++] * mult; + PROCESS_TRANSFORM_COMPONENTS; +#undef PROCESS_TRANSFORM_COMPONENT + } + + // Divide them by their divisors +#define PROCESS_TRANSFORM_COMPONENT(type, mult, flag, name) \ + if (flags & (unsigned) flags_t::flag) \ + { \ + HBINT16 int_v; \ + int_v = roundf (transform.name); \ + type typed_v = * (const type *) &int_v; \ + float float_v = (float) typed_v; \ + transform.name = float_v; \ + } + PROCESS_TRANSFORM_COMPONENTS; +#undef PROCESS_TRANSFORM_COMPONENT + + if (!(flags & (unsigned) flags_t::HAVE_SCALE_Y)) + transform.scaleY = transform.scaleX; + + total_transform.transform (transform.to_transform ()); + total_transform.scale (c.font->x_mult ? 1.f / c.font->x_multf : 0.f, + c.font->y_mult ? 1.f / c.font->y_multf : 0.f); + + bool same_coords = component_coords.length == coords.length && + component_coords.arrayZ == coords.arrayZ; + + c.depth_left--; + VARC.get_path_at (c, gid, + component_coords, total_transform, + parent_gid, + same_coords ? cache : nullptr); + c.depth_left++; + } + +#undef PROCESS_TRANSFORM_COMPONENTS +#undef READ_UINT32VAR + + return hb_ubytes_t (record, end - record); +} + +bool +VARC::get_path_at (const hb_varc_context_t &c, + hb_codepoint_t glyph, + hb_array_t coords, + hb_transform_t<> transform, + hb_codepoint_t parent_glyph, + hb_scalar_cache_t *parent_cache) const +{ + // Don't recurse on the same glyph. + unsigned idx = glyph == parent_glyph ? + NOT_COVERED : + (this+coverage).get_coverage (glyph); + if (idx == NOT_COVERED) + { + if (c.draw_session) + { + // Build a transforming pen to apply the transform. + hb_draw_funcs_t *transformer_funcs = hb_transforming_pen_get_funcs (); + hb_transforming_pen_context_t context {transform, + c.draw_session->funcs, + c.draw_session->draw_data, + &c.draw_session->st}; + hb_draw_session_t transformer_session {transformer_funcs, &context}; + hb_draw_session_t &shape_draw_session = transform.is_identity () ? *c.draw_session : transformer_session; + + if (c.font->face->table.glyf->get_path_at (c.font, glyph, shape_draw_session, coords, c.scratch.glyf_scratch)) return true; +#ifndef HB_NO_CFF + if (c.font->face->table.cff2->get_path_at (c.font, glyph, shape_draw_session, coords)) return true; + if (c.font->face->table.cff1->get_path (c.font, glyph, shape_draw_session)) return true; // Doesn't have variations +#endif + return false; + } + else if (c.extents) + { + hb_glyph_extents_t glyph_extents; + if (!c.font->face->table.glyf->get_extents_at (c.font, glyph, &glyph_extents, coords)) +#ifndef HB_NO_CFF + if (!c.font->face->table.cff2->get_extents_at (c.font, glyph, &glyph_extents, coords)) + if (!c.font->face->table.cff1->get_extents (c.font, glyph, &glyph_extents)) // Doesn't have variations +#endif + return false; + + hb_extents_t<> comp_extents (glyph_extents); + transform.transform_extents (comp_extents); + c.extents->union_ (comp_extents); + } + return true; + } + + if (c.depth_left <= 0) + return true; + + if (c.edges_left <= 0) + return true; + (c.edges_left)--; + + hb_decycler_node_t node (c.decycler); + if (unlikely (!node.visit (glyph))) + return true; + + hb_ubytes_t record = (this+glyphRecords)[idx]; + + hb_scalar_cache_t static_cache; + hb_scalar_cache_t *cache = parent_cache ? + parent_cache : + (this+varStore).create_cache (&static_cache); + + transform.scale (c.font->x_multf, c.font->y_multf); + + VarCompositeGlyph::get_path_at (c, + glyph, + coords, transform, + record, + cache); + + if (cache != parent_cache) + (this+varStore).destroy_cache (cache, &static_cache); + + return true; +} + +#endif + +//} // namespace Var +} // namespace OT + +#endif diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/VARC.hh b/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/VARC.hh index 2ea1b6bca32..6b40f044556 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/VARC.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/VARC.hh @@ -32,7 +32,7 @@ struct hb_varc_context_t { hb_font_t *font; hb_draw_session_t *draw_session; - hb_extents_t *extents; + hb_extents_t<> *extents; mutable hb_decycler_t decycler; mutable signed edges_left; mutable signed depth_left; @@ -65,9 +65,9 @@ struct VarComponent get_path_at (const hb_varc_context_t &c, hb_codepoint_t parent_gid, hb_array_t coords, - hb_transform_t transform, + hb_transform_t<> transform, hb_ubytes_t record, - VarRegionList::cache_t *cache = nullptr) const; + hb_scalar_cache_t *cache = nullptr) const; }; struct VarCompositeGlyph @@ -76,9 +76,9 @@ struct VarCompositeGlyph get_path_at (const hb_varc_context_t &c, hb_codepoint_t gid, hb_array_t coords, - hb_transform_t transform, + hb_transform_t<> transform, hb_ubytes_t record, - VarRegionList::cache_t *cache) + hb_scalar_cache_t *cache) { while (record) { @@ -104,9 +104,9 @@ struct VARC get_path_at (const hb_varc_context_t &c, hb_codepoint_t gid, hb_array_t coords, - hb_transform_t transform = HB_TRANSFORM_IDENTITY, + hb_transform_t<> transform = HB_TRANSFORM_IDENTITY, hb_codepoint_t parent_gid = HB_CODEPOINT_INVALID, - VarRegionList::cache_t *parent_cache = nullptr) const; + hb_scalar_cache_t *parent_cache = nullptr) const; bool get_path (hb_font_t *font, @@ -129,7 +129,7 @@ struct VARC bool get_extents (hb_font_t *font, hb_codepoint_t gid, - hb_extents_t *extents, + hb_extents_t<> *extents, hb_varc_scratch_t &scratch) const { hb_varc_context_t c {font, @@ -194,9 +194,10 @@ struct VARC hb_codepoint_t gid, hb_glyph_extents_t *extents) const { +#ifndef HB_NO_DRAW if (!table->has_data ()) return false; - hb_extents_t f_extents; + hb_extents_t<> f_extents; auto *scratch = acquire_scratch (); if (unlikely (!scratch)) return true; @@ -207,6 +208,9 @@ struct VARC *extents = f_extents.to_glyph_extents (font->x_scale < 0, font->y_scale < 0); return ret; +#else + return false; +#endif } private: diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh index 1805df262aa..8f5287e9457 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh @@ -102,17 +102,15 @@ struct Glyph if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false; hb_array_t phantoms = points.as_array ().sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT); { + // Duplicated code. int lsb = 0; - int h_delta = face->table.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb) ? - (int) header->xMin - lsb : 0; + face->table.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb); + int h_delta = (int) header->xMin - lsb; HB_UNUSED int tsb = 0; - int v_orig = (int) header->yMax + #ifndef HB_NO_VERTICAL - ((void) face->table.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb), tsb) -#else - 0 + face->table.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb); #endif - ; + int v_orig = (int) header->yMax + tsb; unsigned h_adv = face->table.hmtx->get_advance_without_var_unscaled (gid); unsigned v_adv = #ifndef HB_NO_VERTICAL @@ -314,6 +312,7 @@ struct Glyph bool use_my_metrics = true, bool phantom_only = false, hb_array_t coords = hb_array_t (), + hb_scalar_cache_t *gvar_cache = nullptr, unsigned int depth = 0, unsigned *edge_count = nullptr) const { @@ -328,7 +327,7 @@ struct Glyph head_maxp_info->maxComponentDepth = hb_max (head_maxp_info->maxComponentDepth, depth); } - if (!coords) + if (!coords && font->has_nonzero_coords) coords = hb_array (font->coords, font->num_coords); contour_point_vector_t &points = type == SIMPLE ? all_points : scratch.comp_points; @@ -357,17 +356,15 @@ struct Glyph if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false; hb_array_t phantoms = points.as_array ().sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT); { + // Duplicated code. int lsb = 0; - int h_delta = glyf_accelerator.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb) ? - (int) header->xMin - lsb : 0; + glyf_accelerator.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb); + int h_delta = (int) header->xMin - lsb; HB_UNUSED int tsb = 0; - int v_orig = (int) header->yMax + #ifndef HB_NO_VERTICAL - ((void) glyf_accelerator.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb), tsb) -#else - 0 + glyf_accelerator.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb); #endif - ; + int v_orig = (int) header->yMax + tsb; unsigned h_adv = glyf_accelerator.hmtx->get_advance_without_var_unscaled (gid); unsigned v_adv = #ifndef HB_NO_VERTICAL @@ -383,7 +380,7 @@ struct Glyph } #ifndef HB_NO_VAR - if (coords) + if (hb_any (coords)) { #ifndef HB_NO_BEYOND_64K if (glyf_accelerator.GVAR->has_data ()) @@ -391,6 +388,7 @@ struct Glyph coords, points.as_array ().sub_array (old_length), scratch, + gvar_cache, phantom_only && type == SIMPLE); else #endif @@ -398,6 +396,7 @@ struct Glyph coords, points.as_array ().sub_array (old_length), scratch, + gvar_cache, phantom_only && type == SIMPLE); } #endif @@ -447,6 +446,7 @@ struct Glyph use_my_metrics, phantom_only, coords, + gvar_cache, depth + 1, edge_count))) { @@ -533,7 +533,11 @@ struct Glyph bool get_extents_without_var_scaled (hb_font_t *font, const glyf_accelerator_t &glyf_accelerator, hb_glyph_extents_t *extents) const { - if (type == EMPTY) return true; /* Empty glyph; zero extents. */ + if (type == EMPTY) + { + *extents = {0, 0, 0, 0}; + return true; /* Empty glyph; zero extents. */ + } return header->get_extents_without_var_scaled (font, glyf_accelerator, gid, extents); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh index 601e1303792..507c94f7f3d 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh @@ -189,7 +189,7 @@ struct SimpleGlyph unsigned old_length = points.length; points.alloc (points.length + num_points + 4); // Allocate for phantom points, to avoid a possible copy - if (unlikely (!points.resize (points.length + num_points, false))) return false; + if (unlikely (!points.resize_dirty (points.length + num_points))) return false; auto points_ = points.as_array ().sub_array (old_length); if (!phantom_only) hb_memset (points_.arrayZ, 0, sizeof (contour_point_t) * num_points); diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh index d9e5fedfa92..3fe2506bec9 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh @@ -220,7 +220,8 @@ struct glyf_accelerator_t template bool get_points (hb_font_t *font, hb_codepoint_t gid, T consumer, hb_array_t coords, - hb_glyf_scratch_t &scratch) const + hb_glyf_scratch_t &scratch, + hb_scalar_cache_t *gvar_cache = nullptr) const { if (gid >= num_glyphs) return false; @@ -228,7 +229,7 @@ struct glyf_accelerator_t all_points.resize (0); bool phantom_only = !consumer.is_consuming_contour_points (); - if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, scratch, nullptr, nullptr, nullptr, true, true, phantom_only, coords))) + if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, scratch, nullptr, nullptr, nullptr, true, true, phantom_only, coords, gvar_cache))) return false; unsigned count = all_points.length; @@ -371,28 +372,28 @@ struct glyf_accelerator_t contour_point_t *get_phantoms_sink () { return phantoms; } }; +#ifndef HB_NO_VAR unsigned - get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const + get_advance_with_var_unscaled (hb_codepoint_t gid, + hb_font_t *font, + bool is_vertical, + hb_glyf_scratch_t &scratch, + hb_scalar_cache_t *gvar_cache = nullptr) const { if (unlikely (gid >= num_glyphs)) return 0; bool success = false; contour_point_t phantoms[glyf_impl::PHANTOM_COUNT]; - if (font->num_coords) - { - hb_glyf_scratch_t scratch; - success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms, false), - hb_array (font->coords, font->num_coords), - scratch); - } - + success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms, false), + hb_array (font->coords, + font->has_nonzero_coords ? font->num_coords : 0), + scratch, gvar_cache); if (unlikely (!success)) - return -#ifndef HB_NO_VERTICAL - is_vertical ? vmtx->get_advance_without_var_unscaled (gid) : -#endif - hmtx->get_advance_without_var_unscaled (gid); + { + unsigned upem = font->face->get_upem (); + return is_vertical ? upem : upem / 2; + } float result = is_vertical ? phantoms[glyf_impl::PHANTOM_TOP].y - phantoms[glyf_impl::PHANTOM_BOTTOM].y @@ -400,40 +401,38 @@ struct glyf_accelerator_t return hb_clamp (roundf (result), 0.f, (float) UINT_MAX / 2); } - bool get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t gid, bool is_vertical, int *lsb) const + float + get_v_origin_with_var_unscaled (hb_codepoint_t gid, + hb_font_t *font, + hb_glyf_scratch_t &scratch, + hb_scalar_cache_t *gvar_cache = nullptr) const { - if (unlikely (gid >= num_glyphs)) return false; + if (unlikely (gid >= num_glyphs)) return 0; + + bool success = false; - hb_glyph_extents_t extents; - hb_glyf_scratch_t scratch; contour_point_t phantoms[glyf_impl::PHANTOM_COUNT]; - if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms, false), - hb_array (font->coords, font->num_coords), - scratch))) - return false; + success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms, false), + hb_array (font->coords, + font->has_nonzero_coords ? font->num_coords : 0), + scratch, gvar_cache); + if (unlikely (!success)) + { + return font->face->get_upem (); + } - *lsb = is_vertical - ? roundf (phantoms[glyf_impl::PHANTOM_TOP].y) - extents.y_bearing - : roundf (phantoms[glyf_impl::PHANTOM_LEFT].x); - return true; + return phantoms[glyf_impl::PHANTOM_TOP].y; } #endif - - bool get_leading_bearing_without_var_unscaled (hb_codepoint_t gid, bool is_vertical, int *lsb) const - { - if (unlikely (gid >= num_glyphs)) return false; - if (is_vertical) return false; // TODO Humm, what to do here? - - *lsb = glyph_for_gid (gid).get_header ()->xMin; - return true; - } +#endif public: bool get_extents (hb_font_t *font, hb_codepoint_t gid, hb_glyph_extents_t *extents) const - { return get_extents_at (font, gid, extents, hb_array (font->coords, font->num_coords)); } + { return get_extents_at (font, gid, extents, hb_array (font->coords, + font->has_nonzero_coords ? font->num_coords : 0)); } bool get_extents_at (hb_font_t *font, hb_codepoint_t gid, @@ -445,12 +444,15 @@ struct glyf_accelerator_t #ifndef HB_NO_VAR if (coords) { - hb_glyf_scratch_t scratch; - return get_points (font, - gid, - points_aggregator_t (font, extents, nullptr, true), - coords, - scratch); + hb_glyf_scratch_t *scratch = acquire_scratch (); + if (unlikely (!scratch)) return false; + bool ret = get_points (font, + gid, + points_aggregator_t (font, extents, nullptr, true), + coords, + *scratch); + release_scratch (scratch); + return ret; } #endif return glyph_for_gid (gid).get_extents_without_var_scaled (font, *this, extents); @@ -485,33 +487,20 @@ struct glyf_accelerator_t } bool - get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session) const + get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session, hb_scalar_cache_t *gvar_cache = nullptr) const { if (!has_data ()) return false; - hb_glyf_scratch_t *scratch; - - // Borrow the cached strach buffer. - { - scratch = cached_scratch.get_acquire (); - if (!scratch || unlikely (!cached_scratch.cmpexch (scratch, nullptr))) - { - scratch = (hb_glyf_scratch_t *) hb_calloc (1, sizeof (hb_glyf_scratch_t)); - if (unlikely (!scratch)) - return true; - } - } + hb_glyf_scratch_t *scratch = acquire_scratch (); + if (unlikely (!scratch)) return true; bool ret = get_points (font, gid, glyf_impl::path_builder_t (font, draw_session), - hb_array (font->coords, font->num_coords), - *scratch); + hb_array (font->coords, + font->has_nonzero_coords ? font->num_coords : 0), + *scratch, + gvar_cache); - // Put it back. - if (!cached_scratch.cmpexch (nullptr, scratch)) - { - scratch->~hb_glyf_scratch_t (); - hb_free (scratch); - } + release_scratch (scratch); return ret; } @@ -519,12 +508,38 @@ struct glyf_accelerator_t bool get_path_at (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session, hb_array_t coords, - hb_glyf_scratch_t &scratch) const + hb_glyf_scratch_t &scratch, + hb_scalar_cache_t *gvar_cache = nullptr) const { if (!has_data ()) return false; return get_points (font, gid, glyf_impl::path_builder_t (font, draw_session), coords, - scratch); + scratch, + gvar_cache); + } + + + hb_glyf_scratch_t *acquire_scratch () const + { + if (!has_data ()) return nullptr; + hb_glyf_scratch_t *scratch = cached_scratch.get_acquire (); + if (!scratch || unlikely (!cached_scratch.cmpexch (scratch, nullptr))) + { + scratch = (hb_glyf_scratch_t *) hb_calloc (1, sizeof (hb_glyf_scratch_t)); + if (unlikely (!scratch)) + return nullptr; + } + return scratch; + } + void release_scratch (hb_glyf_scratch_t *scratch) const + { + if (!scratch) + return; + if (!cached_scratch.cmpexch (nullptr, scratch)) + { + scratch->~hb_glyf_scratch_t (); + hb_free (scratch); + } } #ifndef HB_NO_VAR diff --git a/src/java.desktop/share/native/libharfbuzz/graph/classdef-graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/classdef-graph.hh index da6378820bb..d1f38b9de8a 100644 --- a/src/java.desktop/share/native/libharfbuzz/graph/classdef-graph.hh +++ b/src/java.desktop/share/native/libharfbuzz/graph/classdef-graph.hh @@ -74,7 +74,7 @@ struct ClassDef : public OT::ClassDef class_def_link->width = SmallTypes::size; class_def_link->objidx = class_def_prime_id; class_def_link->position = link_position; - class_def_prime_vertex.add_parent (parent_id); + class_def_prime_vertex.add_parent (parent_id, false); return true; } @@ -117,7 +117,7 @@ struct ClassDef : public OT::ClassDef int64_t vertex_len = vertex.obj.tail - vertex.obj.head; if (vertex_len < OT::ClassDef::min_size) return false; hb_barrier (); - switch (u.format) + switch (u.format.v) { case 1: return ((ClassDefFormat1*)this)->sanitize (vertex); case 2: return ((ClassDefFormat2*)this)->sanitize (vertex); diff --git a/src/java.desktop/share/native/libharfbuzz/graph/coverage-graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/coverage-graph.hh index 61ca063e345..46c703524d9 100644 --- a/src/java.desktop/share/native/libharfbuzz/graph/coverage-graph.hh +++ b/src/java.desktop/share/native/libharfbuzz/graph/coverage-graph.hh @@ -32,29 +32,27 @@ namespace graph { -struct CoverageFormat1 : public OT::Layout::Common::CoverageFormat1_3 -{ - bool sanitize (graph_t::vertex_t& vertex) const - { - int64_t vertex_len = vertex.obj.tail - vertex.obj.head; - constexpr unsigned min_size = OT::Layout::Common::CoverageFormat1_3::min_size; - if (vertex_len < min_size) return false; - hb_barrier (); - return vertex_len >= min_size + glyphArray.get_size () - glyphArray.len.get_size (); - } -}; +static bool sanitize ( + const OT::Layout::Common::CoverageFormat1_3* thiz, + graph_t::vertex_t& vertex +) { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + constexpr unsigned min_size = OT::Layout::Common::CoverageFormat1_3::min_size; + if (vertex_len < min_size) return false; + hb_barrier (); + return vertex_len >= min_size + thiz->glyphArray.get_size () - thiz->glyphArray.len.get_size (); +} -struct CoverageFormat2 : public OT::Layout::Common::CoverageFormat2_4 -{ - bool sanitize (graph_t::vertex_t& vertex) const - { - int64_t vertex_len = vertex.obj.tail - vertex.obj.head; - constexpr unsigned min_size = OT::Layout::Common::CoverageFormat2_4::min_size; - if (vertex_len < min_size) return false; - hb_barrier (); - return vertex_len >= min_size + rangeRecord.get_size () - rangeRecord.len.get_size (); - } -}; +static bool sanitize ( + const OT::Layout::Common::CoverageFormat2_4* thiz, + graph_t::vertex_t& vertex +) { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + constexpr unsigned min_size = OT::Layout::Common::CoverageFormat2_4::min_size; + if (vertex_len < min_size) return false; + hb_barrier (); + return vertex_len >= min_size + thiz->rangeRecord.get_size () - thiz->rangeRecord.len.get_size (); +} struct Coverage : public OT::Layout::Common::Coverage { @@ -98,11 +96,33 @@ struct Coverage : public OT::Layout::Common::Coverage coverage_link->width = SmallTypes::size; coverage_link->objidx = coverage_prime_id; coverage_link->position = link_position; - coverage_prime_vertex.add_parent (parent_id); + coverage_prime_vertex.add_parent (parent_id, false); return (Coverage*) coverage_prime_vertex.obj.head; } + // Filter an existing coverage table to glyphs at indices [start, end) and replace it with the filtered version. + static bool filter_coverage (gsubgpos_graph_context_t& c, + unsigned existing_coverage, + unsigned start, unsigned end) { + unsigned coverage_size = c.graph.vertices_[existing_coverage].table_size (); + auto& coverage_v = c.graph.vertices_[existing_coverage]; + Coverage* coverage_table = (Coverage*) coverage_v.obj.head; + if (!coverage_table || !coverage_table->sanitize (coverage_v)) + return false; + + auto new_coverage = + + hb_zip (coverage_table->iter (), hb_range ()) + | hb_filter ([&] (hb_pair_t p) { + return p.second >= start && p.second < end; + }) + | hb_map_retains_sorting (hb_first) + ; + + return make_coverage (c, new_coverage, existing_coverage, coverage_size * 2 + 100); + } + + // Replace the coverage table at dest obj with one covering 'glyphs'. template static bool make_coverage (gsubgpos_graph_context_t& c, It glyphs, @@ -141,10 +161,10 @@ struct Coverage : public OT::Layout::Common::Coverage int64_t vertex_len = vertex.obj.tail - vertex.obj.head; if (vertex_len < OT::Layout::Common::Coverage::min_size) return false; hb_barrier (); - switch (u.format) + switch (u.format.v) { - case 1: return ((CoverageFormat1*)this)->sanitize (vertex); - case 2: return ((CoverageFormat2*)this)->sanitize (vertex); + case 1: return graph::sanitize ((const OT::Layout::Common::CoverageFormat1_3*) this, vertex); + case 2: return graph::sanitize ((const OT::Layout::Common::CoverageFormat2_4*) this, vertex); #ifndef HB_NO_BEYOND_64K // Not currently supported case 3: diff --git a/src/java.desktop/share/native/libharfbuzz/graph/graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/graph.hh index ed1026f5866..78ae1a9dd5b 100644 --- a/src/java.desktop/share/native/libharfbuzz/graph/graph.hh +++ b/src/java.desktop/share/native/libharfbuzz/graph/graph.hh @@ -50,6 +50,7 @@ struct graph_t private: unsigned incoming_edges_ = 0; unsigned single_parent = (unsigned) -1; + bool has_incoming_virtual_edges_ = false; hb_hashmap_t parents; public: @@ -66,6 +67,11 @@ struct graph_t return parents.in_error (); } + bool has_incoming_virtual_edges () const + { + return has_incoming_virtual_edges_; + } + bool link_positions_valid (unsigned num_objects, bool removed_nil) { hb_set_t assigned_bytes; @@ -121,7 +127,9 @@ struct graph_t } } - bool equals (const vertex_t& other, + bool equals (unsigned this_index, + unsigned other_index, + const vertex_t& other, const graph_t& graph, const graph_t& other_graph, unsigned depth) const @@ -129,8 +137,10 @@ struct graph_t if (!(as_bytes () == other.as_bytes ())) { DEBUG_MSG (SUBSET_REPACK, nullptr, - "vertex [%lu] bytes != [%lu] bytes, depth = %u", + "vertex %u [%lu bytes] != %u [%lu bytes], depth = %u", + this_index, (unsigned long) table_size (), + other_index, (unsigned long) other.table_size (), depth); @@ -162,6 +172,7 @@ struct graph_t hb_swap (a.single_parent, b.single_parent); hb_swap (a.parents, b.parents); hb_swap (a.incoming_edges_, b.incoming_edges_); + hb_swap (a.has_incoming_virtual_edges_, b.has_incoming_virtual_edges_); hb_swap (a.start, b.start); hb_swap (a.end, b.end); hb_swap (a.priority, b.priority); @@ -207,13 +218,16 @@ struct graph_t void reset_parents () { incoming_edges_ = 0; + has_incoming_virtual_edges_ = false; single_parent = (unsigned) -1; parents.reset (); } - void add_parent (unsigned parent_index) + void add_parent (unsigned parent_index, bool is_virtual) { assert (parent_index != (unsigned) -1); + has_incoming_virtual_edges_ |= is_virtual; + if (incoming_edges_ == 0) { single_parent = parent_index; @@ -408,7 +422,7 @@ struct graph_t link_a.bias != link_b.bias) return false; - if (!graph.vertices_[link_a.objidx].equals ( + if (!graph.vertices_[link_a.objidx].equals (link_a.objidx, link_b.objidx, other_graph.vertices_[link_b.objidx], graph, other_graph, depth + 1)) return false; @@ -456,8 +470,12 @@ struct graph_t num_roots_for_space_.push (1); bool removed_nil = false; vertices_.alloc (objects.length); - vertices_scratch_.alloc (objects.length); + ordering_.resize (objects.length); + ordering_scratch_.alloc (objects.length); + unsigned count = objects.length; + unsigned order = objects.length; + unsigned skip = 0; for (unsigned i = 0; i < count; i++) { // If this graph came from a serialization buffer object 0 is the @@ -465,6 +483,9 @@ struct graph_t if (i == 0 && !objects.arrayZ[i]) { removed_nil = true; + order--; + ordering_.resize(objects.length - 1); + skip++; continue; } @@ -474,6 +495,12 @@ struct graph_t check_success (v->link_positions_valid (count, removed_nil)); + // To start we set the ordering to match the provided objects + // list. Note: objects are provided to us in reverse order (ie. + // the last object is the root). + unsigned obj_idx = i - skip; + ordering_[--order] = obj_idx; + if (!removed_nil) continue; // Fix indices to account for removed nil object. for (auto& l : v->obj.all_links_writer ()) { @@ -490,17 +517,20 @@ struct graph_t bool operator== (const graph_t& other) const { - return root ().equals (other.root (), *this, other, 0); + return root ().equals (root_idx(), other.root_idx(), other.root (), *this, other, 0); } void print () const { - for (int i = vertices_.length - 1; i >= 0; i--) + for (unsigned id : ordering_) { - const auto& v = vertices_[i]; - printf("%d: %u [", i, (unsigned int)v.table_size()); + const auto& v = vertices_[id]; + printf("%u: %u [", id, (unsigned int)v.table_size()); for (const auto &l : v.obj.real_links) { printf("%u, ", l.objidx); } + for (const auto &l : v.obj.virtual_links) { + printf("v%u, ", l.objidx); + } printf("]\n"); } } @@ -516,6 +546,7 @@ struct graph_t { return !successful || vertices_.in_error () || + ordering_.in_error() || num_roots_for_space_.in_error (); } @@ -526,10 +557,10 @@ struct graph_t unsigned root_idx () const { - // Object graphs are in reverse order, the first object is at the end - // of the vector. Since the graph is topologically sorted it's safe to + // First element of ordering_ is the root. + // Since the graph is topologically sorted it's safe to // assume the first object has no incoming edges. - return vertices_.length - 1; + return ordering_[0]; } const hb_serialize_context_t::object_t& object (unsigned i) const @@ -556,7 +587,7 @@ struct graph_t link->width = 2; link->objidx = child_id; link->position = (char*) offset - (char*) v.obj.head; - vertices_[child_id].add_parent (parent_id); + vertices_[child_id].add_parent (parent_id, false); } /* @@ -587,55 +618,51 @@ struct graph_t hb_priority_queue_t queue; queue.alloc (vertices_.length); - hb_vector_t &sorted_graph = vertices_scratch_; - if (unlikely (!check_success (sorted_graph.resize (vertices_.length)))) return; - hb_vector_t id_map; - if (unlikely (!check_success (id_map.resize (vertices_.length)))) return; + hb_vector_t &new_ordering = ordering_scratch_; + if (unlikely (!check_success (new_ordering.resize (vertices_.length)))) return; hb_vector_t removed_edges; if (unlikely (!check_success (removed_edges.resize (vertices_.length)))) return; update_parents (); queue.insert (root ().modified_distance (0), root_idx ()); - int new_id = root_idx (); unsigned order = 1; + unsigned pos = 0; while (!queue.in_error () && !queue.is_empty ()) { unsigned next_id = queue.pop_minimum().second; - sorted_graph[new_id] = std::move (vertices_[next_id]); - const vertex_t& next = sorted_graph[new_id]; - - if (unlikely (!check_success(new_id >= 0))) { + if (unlikely (!check_success(pos < new_ordering.length))) { // We are out of ids. Which means we've visited a node more than once. // This graph contains a cycle which is not allowed. DEBUG_MSG (SUBSET_REPACK, nullptr, "Invalid graph. Contains cycle."); return; } - - id_map[next_id] = new_id--; + new_ordering[pos++] = next_id; + const vertex_t& next = vertices_[next_id]; for (const auto& link : next.obj.all_links ()) { removed_edges[link.objidx]++; - if (!(vertices_[link.objidx].incoming_edges () - removed_edges[link.objidx])) + const auto& v = vertices_[link.objidx]; + if (!(v.incoming_edges () - removed_edges[link.objidx])) // Add the order that the links were encountered to the priority. // This ensures that ties between priorities objects are broken in a consistent // way. More specifically this is set up so that if a set of objects have the same // distance they'll be added to the topological order in the order that they are // referenced from the parent object. - queue.insert (vertices_[link.objidx].modified_distance (order++), + queue.insert (v.modified_distance (order++), link.objidx); } } check_success (!queue.in_error ()); - check_success (!sorted_graph.in_error ()); + check_success (!new_ordering.in_error ()); - check_success (remap_all_obj_indices (id_map, &sorted_graph)); - vertices_ = std::move (sorted_graph); + hb_swap (ordering_, new_ordering); - if (!check_success (new_id == -1)) + if (!check_success (pos == vertices_.length)) { print_orphaned_nodes (); + } } /* @@ -645,8 +672,8 @@ struct graph_t */ void find_space_roots (hb_set_t& visited, hb_set_t& roots) { - int root_index = (int) root_idx (); - for (int i = root_index; i >= 0; i--) + unsigned root_index = root_idx (); + for (unsigned i : ordering_) { if (visited.has (i)) continue; @@ -829,7 +856,6 @@ struct graph_t if (subgraph.in_error ()) return false; - unsigned original_root_idx = root_idx (); hb_map_t index_map; bool made_changes = false; for (auto entry : subgraph.iter ()) @@ -852,14 +878,6 @@ struct graph_t if (!made_changes) return false; - if (original_root_idx != root_idx () - && parents.has (original_root_idx)) - { - // If the root idx has changed since parents was determined, update root idx in parents - parents.add (root_idx ()); - parents.del (original_root_idx); - } - auto new_subgraph = + subgraph.keys () | hb_map([&] (uint32_t node_idx) { @@ -943,12 +961,14 @@ struct graph_t /* * Moves the child of old_parent_idx pointed to by old_offset to a new * vertex at the new_offset. + * + * Returns the id of the child node that was moved. */ template - void move_child (unsigned old_parent_idx, - const O* old_offset, - unsigned new_parent_idx, - const O* new_offset) + unsigned move_child (unsigned old_parent_idx, + const O* old_offset, + unsigned new_parent_idx, + const O* new_offset) { distance_invalid = true; positions_invalid = true; @@ -965,10 +985,56 @@ struct graph_t new_link->position = (const char*) new_offset - (const char*) new_v.obj.head; auto& child = vertices_[child_id]; - child.add_parent (new_parent_idx); + child.add_parent (new_parent_idx, false); old_v.remove_real_link (child_id, old_offset); child.remove_parent (old_parent_idx); + + return child_id; + } + + /* + * Moves all outgoing links in old parent that have + * a link position between [old_post_start, old_pos_end) + * to the new parent. Links are placed serially in the new + * parent starting at new_pos_start. + */ + template + void move_children (unsigned old_parent_idx, + unsigned old_pos_start, + unsigned old_pos_end, + unsigned new_parent_idx, + unsigned new_pos_start) + { + distance_invalid = true; + positions_invalid = true; + + auto& old_v = vertices_[old_parent_idx]; + auto& new_v = vertices_[new_parent_idx]; + + hb_vector_t old_links; + for (const auto& l : old_v.obj.real_links) + { + if (l.position < old_pos_start || l.position >= old_pos_end) + { + old_links.push(l); + continue; + } + + unsigned array_pos = l.position - old_pos_start; + + unsigned child_id = l.objidx; + auto* new_link = new_v.obj.real_links.push (); + new_link->width = O::static_size; + new_link->objidx = child_id; + new_link->position = new_pos_start + array_pos; + + auto& child = vertices_[child_id]; + child.add_parent (new_parent_idx, false); + child.remove_parent (old_parent_idx); + } + + old_v.obj.real_links = std::move (old_links); } /* @@ -1000,8 +1066,11 @@ struct graph_t distance_invalid = true; auto* clone = vertices_.push (); + unsigned clone_idx = vertices_.length - 1; + ordering_.push(clone_idx); + auto& child = vertices_[node_idx]; - if (vertices_.in_error ()) { + if (vertices_.in_error () || ordering_.in_error()) { return -1; } @@ -1011,51 +1080,23 @@ struct graph_t clone->space = child.space; clone->reset_parents (); - unsigned clone_idx = vertices_.length - 2; for (const auto& l : child.obj.real_links) { clone->obj.real_links.push (l); - vertices_[l.objidx].add_parent (clone_idx); + vertices_[l.objidx].add_parent (clone_idx, false); } for (const auto& l : child.obj.virtual_links) { clone->obj.virtual_links.push (l); - vertices_[l.objidx].add_parent (clone_idx); + vertices_[l.objidx].add_parent (clone_idx, true); } check_success (!clone->obj.real_links.in_error ()); check_success (!clone->obj.virtual_links.in_error ()); - // The last object is the root of the graph, so swap back the root to the end. - // The root's obj idx does change, however since it's root nothing else refers to it. - // all other obj idx's will be unaffected. - hb_swap (vertices_[vertices_.length - 2], *clone); - - // Since the root moved, update the parents arrays of all children on the root. - for (const auto& l : root ().obj.all_links ()) - vertices_[l.objidx].remap_parent (root_idx () - 1, root_idx ()); - return clone_idx; } - /* - * Creates a copy of child and re-assigns the link from - * parent to the clone. The copy is a shallow copy, objects - * linked from child are not duplicated. - * - * Returns the index of the newly created duplicate. - * - * If the child_idx only has incoming edges from parent_idx, this - * will do nothing and return the original child_idx. - */ - unsigned duplicate_if_shared (unsigned parent_idx, unsigned child_idx) - { - unsigned new_idx = duplicate (parent_idx, child_idx); - if (new_idx == (unsigned) -1) return child_idx; - return new_idx; - } - - /* * Creates a copy of child and re-assigns the link from * parent to the clone. The copy is a shallow copy, objects @@ -1073,10 +1114,15 @@ struct graph_t const auto& child = vertices_[child_idx]; unsigned links_to_child = child.incoming_edges_from_parent(parent_idx); - if (child.incoming_edges () <= links_to_child) + if (child.incoming_edges () <= links_to_child || child.has_incoming_virtual_edges()) { // Can't duplicate this node, doing so would orphan the original one as all remaining links // to child are from parent. + // + // We don't allow duplication of nodes with incoming virtual edges because we don't track + // the number of virtual vs real incoming edges. As a result we can't tell if a node + // with virtual edges may end up orphaned by duplication (ie. where one copy is only pointed + // to by virtual edges). DEBUG_MSG (SUBSET_REPACK, nullptr, " Not duplicating %u => %u", parent_idx, child_idx); return -1; @@ -1091,12 +1137,15 @@ struct graph_t if (parent_idx == clone_idx) parent_idx++; auto& parent = vertices_[parent_idx]; + unsigned count = 0; + unsigned num_real = parent.obj.real_links.length; for (auto& l : parent.obj.all_links_writer ()) { + count++; if (l.objidx != child_idx) continue; - reassign_link (l, parent_idx, clone_idx); + reassign_link (l, parent_idx, clone_idx, count > num_real); } return clone_idx; @@ -1129,10 +1178,15 @@ struct graph_t links_to_child += child.incoming_edges_from_parent(parent_idx); } - if (child.incoming_edges () <= links_to_child) + if (child.incoming_edges () <= links_to_child || child.has_incoming_virtual_edges()) { // Can't duplicate this node, doing so would orphan the original one as all remaining links // to child are from parent. + // + // We don't allow duplication of nodes with incoming virtual edges because we don't track + // the number of virtual vs real incoming edges. As a result we can't tell if a node + // with virtual edges may end up orphaned by duplication (ie. where one copy is only pointed + // to by virtual edges). DEBUG_MSG (SUBSET_REPACK, nullptr, " Not duplicating %u, ..., %u => %u", first_parent, last_parent, child_idx); return -1; } @@ -1146,12 +1200,15 @@ struct graph_t // duplicate shifts the root node idx, so if parent_idx was root update it. if (parent_idx == clone_idx) parent_idx++; auto& parent = vertices_[parent_idx]; + unsigned count = 0; + unsigned num_real = parent.obj.real_links.length; for (auto& l : parent.obj.all_links_writer ()) { + count++; if (l.objidx != child_idx) continue; - reassign_link (l, parent_idx, clone_idx); + reassign_link (l, parent_idx, clone_idx, count > num_real); } } @@ -1168,7 +1225,10 @@ struct graph_t distance_invalid = true; auto* clone = vertices_.push (); - if (vertices_.in_error ()) { + unsigned clone_idx = vertices_.length - 1; + ordering_.push(clone_idx); + + if (vertices_.in_error () || ordering_.in_error()) { return -1; } @@ -1177,20 +1237,37 @@ struct graph_t clone->distance = 0; clone->space = 0; - unsigned clone_idx = vertices_.length - 2; - - // The last object is the root of the graph, so swap back the root to the end. - // The root's obj idx does change, however since it's root nothing else refers to it. - // all other obj idx's will be unaffected. - hb_swap (vertices_[vertices_.length - 2], *clone); - - // Since the root moved, update the parents arrays of all children on the root. - for (const auto& l : root ().obj.all_links ()) - vertices_[l.objidx].remap_parent (root_idx () - 1, root_idx ()); - return clone_idx; } + /* + * Creates a new child node and remap the old child to it. + * + * Returns the index of the newly created child. + * + */ + unsigned remap_child (unsigned parent_idx, unsigned old_child_idx) + { + unsigned new_child_idx = duplicate (old_child_idx); + if (new_child_idx == (unsigned) -1) return -1; + + auto& parent = vertices_[parent_idx]; + for (auto& l : parent.obj.real_links) + { + if (l.objidx != old_child_idx) + continue; + reassign_link (l, parent_idx, new_child_idx, false); + } + + for (auto& l : parent.obj.virtual_links) + { + if (l.objidx != old_child_idx) + continue; + reassign_link (l, parent_idx, new_child_idx, true); + } + return new_child_idx; + } + /* * Raises the sorting priority of all children. */ @@ -1279,6 +1356,7 @@ struct graph_t if (!DEBUG_ENABLED(SUBSET_REPACK)) return; DEBUG_MSG (SUBSET_REPACK, nullptr, "Graph is not fully connected."); + parents_invalid = true; update_parents(); @@ -1348,7 +1426,8 @@ struct graph_t size_t total_size = 0; unsigned count = vertices_.length; for (unsigned i = 0; i < count; i++) { - size_t size = vertices_.arrayZ[i].obj.tail - vertices_.arrayZ[i].obj.head; + const auto& obj = vertices_.arrayZ[i].obj; + size_t size = obj.tail - obj.head; total_size += size; } return total_size; @@ -1398,8 +1477,11 @@ struct graph_t for (unsigned p = 0; p < count; p++) { - for (auto& l : vertices_.arrayZ[p].obj.all_links ()) - vertices_[l.objidx].add_parent (p); + for (auto& l : vertices_.arrayZ[p].obj.real_links) + vertices_[l.objidx].add_parent (p, false); + + for (auto& l : vertices_.arrayZ[p].obj.virtual_links) + vertices_[l.objidx].add_parent (p, true); } for (unsigned i = 0; i < count; i++) @@ -1418,7 +1500,7 @@ struct graph_t if (!positions_invalid) return; unsigned current_pos = 0; - for (int i = root_idx (); i >= 0; i--) + for (unsigned i : ordering_) { auto& v = vertices_[i]; v.start = current_pos; @@ -1450,11 +1532,11 @@ struct graph_t unsigned count = vertices_.length; for (unsigned i = 0; i < count; i++) vertices_.arrayZ[i].distance = hb_int_max (int64_t); - vertices_.tail ().distance = 0; + vertices_[root_idx ()].distance = 0; hb_priority_queue_t queue; queue.alloc (count); - queue.insert (0, vertices_.length - 1); + queue.insert (0, root_idx ()); hb_vector_t visited; visited.resize (vertices_.length); @@ -1464,22 +1546,23 @@ struct graph_t unsigned next_idx = queue.pop_minimum ().second; if (visited[next_idx]) continue; const auto& next = vertices_[next_idx]; - int64_t next_distance = vertices_[next_idx].distance; + int64_t next_distance = next.distance; visited[next_idx] = true; for (const auto& link : next.obj.all_links ()) { if (visited[link.objidx]) continue; - const auto& child = vertices_.arrayZ[link.objidx].obj; + auto& child_v = vertices_.arrayZ[link.objidx]; + const auto& child = child_v.obj; unsigned link_width = link.width ? link.width : 4; // treat virtual offsets as 32 bits wide int64_t child_weight = (child.tail - child.head) + - ((int64_t) 1 << (link_width * 8)) * (vertices_.arrayZ[link.objidx].space + 1); + ((int64_t) 1 << (link_width * 8)) * (child_v.space + 1); int64_t child_distance = next_distance + child_weight; - if (child_distance < vertices_.arrayZ[link.objidx].distance) + if (child_distance < child_v.distance) { - vertices_.arrayZ[link.objidx].distance = child_distance; + child_v.distance = child_distance; queue.insert (child_distance, link.objidx); } } @@ -1502,12 +1585,13 @@ struct graph_t */ void reassign_link (hb_serialize_context_t::object_t::link_t& link, unsigned parent_idx, - unsigned new_idx) + unsigned new_idx, + bool is_virtual) { unsigned old_idx = link.objidx; link.objidx = new_idx; vertices_[old_idx].remove_parent (parent_idx); - vertices_[new_idx].add_parent (parent_idx); + vertices_[new_idx].add_parent (parent_idx, is_virtual); } /* @@ -1521,36 +1605,21 @@ struct graph_t if (!id_map) return; for (unsigned i : subgraph) { - for (auto& link : vertices_[i].obj.all_links_writer ()) + auto& obj = vertices_[i].obj; + unsigned num_real = obj.real_links.length; + unsigned count = 0; + for (auto& link : obj.all_links_writer ()) { + count++; const uint32_t *v; if (!id_map.has (link.objidx, &v)) continue; - if (only_wide && !(link.width == 4 && !link.is_signed)) continue; + if (only_wide && (link.is_signed || (link.width != 4 && link.width != 3))) continue; - reassign_link (link, i, *v); + reassign_link (link, i, *v, count > num_real); } } } - /* - * Updates all objidx's in all links using the provided mapping. - */ - bool remap_all_obj_indices (const hb_vector_t& id_map, - hb_vector_t* sorted_graph) const - { - unsigned count = sorted_graph->length; - for (unsigned i = 0; i < count; i++) - { - if (!(*sorted_graph)[i].remap_parents (id_map)) - return false; - for (auto& link : sorted_graph->arrayZ[i].obj.all_links_writer ()) - { - link.objidx = id_map[link.objidx]; - } - } - return true; - } - /* * Finds all nodes in targets that are reachable from start_idx, nodes in visited will be skipped. * For this search the graph is treated as being undirected. @@ -1586,7 +1655,16 @@ struct graph_t public: // TODO(garretrieger): make private, will need to move most of offset overflow code into graph. hb_vector_t vertices_; - hb_vector_t vertices_scratch_; + + // Specifies the current topological ordering of this graph + // + // ordering_[pos] = obj index + // + // specifies that the 'pos'th spot is filled by the object + // given by obj index. + hb_vector_t ordering_; + hb_vector_t ordering_scratch_; + private: bool parents_invalid; bool distance_invalid; diff --git a/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.hh b/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.hh index b25d538fe3d..8969d007879 100644 --- a/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.hh +++ b/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.hh @@ -41,6 +41,7 @@ struct gsubgpos_graph_context_t unsigned lookup_list_index; hb_hashmap_t lookups; hb_hashmap_t subtable_to_extension; + hb_hashmap_t> split_subtables; HB_INTERNAL gsubgpos_graph_context_t (hb_tag_t table_tag_, graph_t& graph_); diff --git a/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-graph.hh index 7ad2ba430b7..ea6bcd239a0 100644 --- a/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-graph.hh +++ b/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-graph.hh @@ -27,9 +27,11 @@ #include "graph.hh" #include "../hb-ot-layout-gsubgpos.hh" #include "../OT/Layout/GSUB/ExtensionSubst.hh" +#include "../OT/Layout/GSUB/SubstLookupSubTable.hh" #include "gsubgpos-context.hh" #include "pairpos-graph.hh" #include "markbasepos-graph.hh" +#include "ligature-graph.hh" #ifndef GRAPH_GSUBGPOS_GRAPH_HH #define GRAPH_GSUBGPOS_GRAPH_HH @@ -85,6 +87,12 @@ struct Lookup : public OT::Lookup return lookupType == extension_type (table_tag); } + bool use_mark_filtering_set () const + { + unsigned flag = lookupFlag; + return flag & 0x0010u; + } + bool make_extension (gsubgpos_graph_context_t& c, unsigned this_index) { @@ -120,22 +128,18 @@ struct Lookup : public OT::Lookup unsigned type = lookupType; bool is_ext = is_extension (c.table_tag); - if (c.table_tag != HB_OT_TAG_GPOS) + if (c.table_tag != HB_OT_TAG_GPOS && c.table_tag != HB_OT_TAG_GSUB) return true; - if (!is_ext && - type != OT::Layout::GPOS_impl::PosLookupSubTable::Type::Pair && - type != OT::Layout::GPOS_impl::PosLookupSubTable::Type::MarkBase) + if (!is_ext && !is_supported_gpos_type(type, c) && !is_supported_gsub_type(type, c)) return true; hb_vector_t>> all_new_subtables; for (unsigned i = 0; i < subTable.len; i++) { unsigned subtable_index = c.graph.index_for_offset (this_index, &subTable[i]); - unsigned parent_index = this_index; if (is_ext) { unsigned ext_subtable_index = subtable_index; - parent_index = ext_subtable_index; ExtensionFormat1* extension = (ExtensionFormat1*) c.graph.object (ext_subtable_index).head; @@ -144,26 +148,47 @@ struct Lookup : public OT::Lookup subtable_index = extension->get_subtable_index (c.graph, ext_subtable_index); type = extension->get_lookup_type (); - if (type != OT::Layout::GPOS_impl::PosLookupSubTable::Type::Pair - && type != OT::Layout::GPOS_impl::PosLookupSubTable::Type::MarkBase) + if (!is_supported_gpos_type(type, c) && !is_supported_gsub_type(type, c)) continue; } - hb_vector_t new_sub_tables; - switch (type) + hb_vector_t* split_result; + if (c.split_subtables.has (subtable_index, &split_result)) { - case 2: - new_sub_tables = split_subtable (c, parent_index, subtable_index); break; - case 4: - new_sub_tables = split_subtable (c, parent_index, subtable_index); break; - default: - break; + if (split_result->length == 0) + continue; + all_new_subtables.push (hb_pair(i, *split_result)); + } + else + { + hb_vector_t new_sub_tables; + + if (c.table_tag == HB_OT_TAG_GPOS) { + switch (type) + { + case 2: + new_sub_tables = split_subtable (c, subtable_index); break; + case 4: + new_sub_tables = split_subtable (c, subtable_index); break; + default: + break; + } + } else if (c.table_tag == HB_OT_TAG_GSUB) { + switch (type) + { + case 4: + new_sub_tables = split_subtable (c, subtable_index); break; + default: + break; + } + } + + if (new_sub_tables.in_error ()) return false; + + c.split_subtables.set (subtable_index, new_sub_tables); + if (new_sub_tables) + all_new_subtables.push (hb_pair (i, std::move (new_sub_tables))); } - if (new_sub_tables.in_error ()) return false; - if (!new_sub_tables) continue; - hb_pair_t>* entry = all_new_subtables.push (); - entry->first = i; - entry->second = std::move (new_sub_tables); } if (all_new_subtables) { @@ -175,30 +200,29 @@ struct Lookup : public OT::Lookup template hb_vector_t split_subtable (gsubgpos_graph_context_t& c, - unsigned parent_idx, unsigned objidx) { T* sub_table = (T*) c.graph.object (objidx).head; if (!sub_table || !sub_table->sanitize (c.graph.vertices_[objidx])) return hb_vector_t (); - return sub_table->split_subtables (c, parent_idx, objidx); + return sub_table->split_subtables (c, objidx); } bool add_sub_tables (gsubgpos_graph_context_t& c, unsigned this_index, unsigned type, - hb_vector_t>>& subtable_ids) + const hb_vector_t>>& subtable_ids) { bool is_ext = is_extension (c.table_tag); - auto& v = c.graph.vertices_[this_index]; + auto* v = &c.graph.vertices_[this_index]; fix_existing_subtable_links (c, this_index, subtable_ids); unsigned new_subtable_count = 0; for (const auto& p : subtable_ids) new_subtable_count += p.second.length; - size_t new_size = v.table_size () + size_t new_size = v->table_size () + new_subtable_count * OT::Offset16::static_size; char* buffer = (char*) hb_calloc (1, new_size); if (!buffer) return false; @@ -207,10 +231,13 @@ struct Lookup : public OT::Lookup hb_free (buffer); return false; } - hb_memcpy (buffer, v.obj.head, v.table_size()); + hb_memcpy (buffer, v->obj.head, v->table_size()); - v.obj.head = buffer; - v.obj.tail = buffer + new_size; + if (use_mark_filtering_set ()) + hb_memcpy (buffer + new_size - 2, v->obj.tail - 2, 2); + + v->obj.head = buffer; + v->obj.tail = buffer + new_size; Lookup* new_lookup = (Lookup*) buffer; @@ -226,21 +253,23 @@ struct Lookup : public OT::Lookup if (is_ext) { unsigned ext_id = create_extension_subtable (c, subtable_id, type); - c.graph.vertices_[subtable_id].add_parent (ext_id); + c.graph.vertices_[subtable_id].add_parent (ext_id, false); subtable_id = ext_id; + // the reference to v may have changed on adding a node, so reassign it. + v = &c.graph.vertices_[this_index]; } - auto* link = v.obj.real_links.push (); + auto* link = v->obj.real_links.push (); link->width = 2; link->objidx = subtable_id; link->position = (char*) &new_lookup->subTable[offset_index++] - (char*) new_lookup; - c.graph.vertices_[subtable_id].add_parent (this_index); + c.graph.vertices_[subtable_id].add_parent (this_index, false); } } // Repacker sort order depends on link order, which we've messed up so resort it. - v.obj.real_links.qsort (); + v->obj.real_links.qsort (); // The head location of the lookup has changed, invalidating the lookups map entry // in the context. Update the map. @@ -250,17 +279,15 @@ struct Lookup : public OT::Lookup void fix_existing_subtable_links (gsubgpos_graph_context_t& c, unsigned this_index, - hb_vector_t>>& subtable_ids) + const hb_vector_t>>& subtable_ids) { auto& v = c.graph.vertices_[this_index]; - Lookup* lookup = (Lookup*) v.obj.head; - unsigned shift = 0; for (const auto& p : subtable_ids) { unsigned insert_index = p.first + shift; unsigned pos_offset = p.second.length * OT::Offset16::static_size; - unsigned insert_offset = (char*) &lookup->subTable[insert_index] - (char*) lookup; + unsigned insert_offset = Lookup::min_size + insert_index * OT::Offset16::static_size; shift += p.second.length; for (auto& l : v.obj.all_links_writer ()) @@ -326,7 +353,7 @@ struct Lookup : public OT::Lookup // Make extension point at the subtable. auto& ext_vertex = c.graph.vertices_[ext_index]; - ext_vertex.add_parent (lookup_index); + ext_vertex.add_parent (lookup_index, false); if (!existing_ext_index) subtable_vertex.remap_parent (lookup_index, ext_index); @@ -334,6 +361,19 @@ struct Lookup : public OT::Lookup } private: + bool is_supported_gsub_type(unsigned type, gsubgpos_graph_context_t& c) const { + return (c.table_tag == HB_OT_TAG_GSUB) && ( + type == OT::Layout::GSUB_impl::SubstLookupSubTable::Type::Ligature + ); + } + + bool is_supported_gpos_type(unsigned type, gsubgpos_graph_context_t& c) const { + return (c.table_tag == HB_OT_TAG_GPOS) && ( + type == OT::Layout::GPOS_impl::PosLookupSubTable::Type::Pair || + type == OT::Layout::GPOS_impl::PosLookupSubTable::Type::MarkBase + ); + } + unsigned extension_type (hb_tag_t table_tag) const { switch (table_tag) diff --git a/src/java.desktop/share/native/libharfbuzz/graph/markbasepos-graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/markbasepos-graph.hh index fb4166128a9..6d1a3d4ae4b 100644 --- a/src/java.desktop/share/native/libharfbuzz/graph/markbasepos-graph.hh +++ b/src/java.desktop/share/native/libharfbuzz/graph/markbasepos-graph.hh @@ -212,7 +212,6 @@ struct MarkBasePosFormat1 : public OT::Layout::GPOS_impl::MarkBasePosFormat1_2 split_subtables (gsubgpos_graph_context_t& c, - unsigned parent_index, unsigned this_index) { hb_set_t visited; @@ -265,7 +264,7 @@ struct MarkBasePosFormat1 : public OT::Layout::GPOS_impl::MarkBasePosFormat1_2 split_subtables (gsubgpos_graph_context_t& c, - unsigned parent_index, unsigned this_index) { - switch (u.format) { + switch (u.format.v) { case 1: - return ((MarkBasePosFormat1*)(&u.format1))->split_subtables (c, parent_index, this_index); + return ((MarkBasePosFormat1*)(&u.format1))->split_subtables (c, this_index); #ifndef HB_NO_BEYOND_64K case 2: HB_FALLTHROUGH; // Don't split 24bit MarkBasePos's. @@ -496,10 +494,10 @@ struct MarkBasePos : public OT::Layout::GPOS_impl::MarkBasePos bool sanitize (graph_t::vertex_t& vertex) const { int64_t vertex_len = vertex.obj.tail - vertex.obj.head; - if (vertex_len < u.format.get_size ()) return false; + if (vertex_len < u.format.v.get_size ()) return false; hb_barrier (); - switch (u.format) { + switch (u.format.v) { case 1: return ((MarkBasePosFormat1*)(&u.format1))->sanitize (vertex); #ifndef HB_NO_BEYOND_64K diff --git a/src/java.desktop/share/native/libharfbuzz/graph/pairpos-graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/pairpos-graph.hh index fd46861de46..85950b63457 100644 --- a/src/java.desktop/share/native/libharfbuzz/graph/pairpos-graph.hh +++ b/src/java.desktop/share/native/libharfbuzz/graph/pairpos-graph.hh @@ -49,7 +49,6 @@ struct PairPosFormat1 : public OT::Layout::GPOS_impl::PairPosFormat1_3 split_subtables (gsubgpos_graph_context_t& c, - unsigned parent_index, unsigned this_index) { hb_set_t visited; @@ -84,7 +83,7 @@ struct PairPosFormat1 : public OT::Layout::GPOS_impl::PairPosFormat1_3 (split_context, split_points); @@ -207,7 +206,6 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4 split_subtables (gsubgpos_graph_context_t& c, - unsigned parent_index, unsigned this_index) { const unsigned base_size = OT::Layout::GPOS_impl::PairPosFormat2_4::min_size; @@ -291,7 +289,7 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4width = SmallTypes::size; class_def_link->objidx = class_def_2_id; class_def_link->position = 10; - graph.vertices_[class_def_2_id].add_parent (pair_pos_prime_id); + graph.vertices_[class_def_2_id].add_parent (pair_pos_prime_id, false); graph.duplicate (pair_pos_prime_id, class_def_2_id); return pair_pos_prime_id; @@ -607,14 +605,13 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4 split_subtables (gsubgpos_graph_context_t& c, - unsigned parent_index, unsigned this_index) { - switch (u.format) { + switch (u.format.v) { case 1: - return ((PairPosFormat1*)(&u.format1))->split_subtables (c, parent_index, this_index); + return ((PairPosFormat1*)(&u.format1))->split_subtables (c, this_index); case 2: - return ((PairPosFormat2*)(&u.format2))->split_subtables (c, parent_index, this_index); + return ((PairPosFormat2*)(&u.format2))->split_subtables (c, this_index); #ifndef HB_NO_BEYOND_64K case 3: HB_FALLTHROUGH; case 4: HB_FALLTHROUGH; @@ -628,10 +625,10 @@ struct PairPos : public OT::Layout::GPOS_impl::PairPos bool sanitize (graph_t::vertex_t& vertex) const { int64_t vertex_len = vertex.obj.tail - vertex.obj.head; - if (vertex_len < u.format.get_size ()) return false; + if (vertex_len < u.format.v.get_size ()) return false; hb_barrier (); - switch (u.format) { + switch (u.format.v) { case 1: return ((PairPosFormat1*)(&u.format1))->sanitize (vertex); case 2: diff --git a/src/java.desktop/share/native/libharfbuzz/graph/serialize.hh b/src/java.desktop/share/native/libharfbuzz/graph/serialize.hh index 06e4bf44d8e..37fac8909e5 100644 --- a/src/java.desktop/share/native/libharfbuzz/graph/serialize.hh +++ b/src/java.desktop/share/native/libharfbuzz/graph/serialize.hh @@ -113,7 +113,7 @@ will_overflow (graph_t& graph, hb_hashmap_t record_set; const auto& vertices = graph.vertices_; - for (int parent_idx = vertices.length - 1; parent_idx >= 0; parent_idx--) + for (unsigned parent_idx : graph.ordering_) { // Don't need to check virtual links for overflow for (const auto& link : vertices.arrayZ[parent_idx].obj.real_links) @@ -172,14 +172,16 @@ void print_overflows (graph_t& graph, template inline void serialize_link_of_type (const hb_serialize_context_t::object_t::link_t& link, char* head, + unsigned size, + const hb_vector_t& id_map, hb_serialize_context_t* c) { + assert(link.position + link.width <= size); + OT::Offset* offset = reinterpret_cast*> (head + link.position); *offset = 0; c->add_link (*offset, - // serializer has an extra nil object at the start of the - // object array. So all id's are +1 of what our id's are. - link.objidx + 1, + id_map[link.objidx], (hb_serialize_context_t::whence_t) link.whence, link.bias); } @@ -187,6 +189,8 @@ serialize_link_of_type (const hb_serialize_context_t::object_t::link_t& link, inline void serialize_link (const hb_serialize_context_t::object_t::link_t& link, char* head, + unsigned size, + const hb_vector_t& id_map, hb_serialize_context_t* c) { switch (link.width) @@ -197,21 +201,21 @@ void serialize_link (const hb_serialize_context_t::object_t::link_t& link, case 4: if (link.is_signed) { - serialize_link_of_type (link, head, c); + serialize_link_of_type (link, head, size, id_map, c); } else { - serialize_link_of_type (link, head, c); + serialize_link_of_type (link, head, size, id_map, c); } return; case 2: if (link.is_signed) { - serialize_link_of_type (link, head, c); + serialize_link_of_type (link, head, size, id_map, c); } else { - serialize_link_of_type (link, head, c); + serialize_link_of_type (link, head, size, id_map, c); } return; case 3: - serialize_link_of_type (link, head, c); + serialize_link_of_type (link, head, size, id_map, c); return; default: // Unexpected link width. @@ -237,25 +241,36 @@ inline hb_blob_t* serialize (const graph_t& graph) c.start_serialize (); const auto& vertices = graph.vertices_; - for (unsigned i = 0; i < vertices.length; i++) { + + // Objects are placed in the serializer in reverse order since children need + // to be inserted before their parents. + + // Maps from our obj id's to the id's used during this serialization. + hb_vector_t id_map; + id_map.resize(graph.ordering_.length); + for (int pos = graph.ordering_.length - 1; pos >= 0; pos--) { + unsigned i = graph.ordering_[pos]; c.push (); - size_t size = vertices[i].obj.tail - vertices[i].obj.head; + auto& v = vertices[i]; + + size_t size = v.obj.tail - v.obj.head; + char* start = c.allocate_size (size); if (!start) { DEBUG_MSG (SUBSET_REPACK, nullptr, "Buffer out of space."); return nullptr; } - hb_memcpy (start, vertices[i].obj.head, size); + hb_memcpy (start, v.obj.head, size); // Only real links needs to be serialized. - for (const auto& link : vertices[i].obj.real_links) - serialize_link (link, start, &c); + for (const auto& link : v.obj.real_links) + serialize_link (link, start, size, id_map, &c); // All duplications are already encoded in the graph, so don't // enable sharing during packing. - c.pop_pack (false); + id_map[i] = c.pop_pack (false); } c.end_serialize (); diff --git a/src/java.desktop/share/native/libharfbuzz/graph/split-helpers.hh b/src/java.desktop/share/native/libharfbuzz/graph/split-helpers.hh index 61fd7c2d2ff..f1f86e332db 100644 --- a/src/java.desktop/share/native/libharfbuzz/graph/split-helpers.hh +++ b/src/java.desktop/share/native/libharfbuzz/graph/split-helpers.hh @@ -49,7 +49,7 @@ hb_vector_t actuate_subtable_split (Context& split_context, if (id == (unsigned) -1) { new_objects.reset (); - new_objects.allocated = -1; // mark error + new_objects.ensure_error (); return new_objects; } new_objects.push (id); @@ -58,7 +58,7 @@ hb_vector_t actuate_subtable_split (Context& split_context, if (!split_context.shrink (split_points[0])) { new_objects.reset (); - new_objects.allocated = -1; // mark error + new_objects.ensure_error (); } return new_objects; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh index d5a44bf473c..d2ce32616be 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh @@ -47,8 +47,7 @@ using namespace OT; struct ankr; -using hb_aat_class_cache_t = hb_cache_t<15, 8, 7>; -static_assert (sizeof (hb_aat_class_cache_t) == 256, ""); +using hb_aat_class_cache_t = hb_ot_layout_mapping_cache_t; struct hb_aat_scratch_t { @@ -79,7 +78,10 @@ struct hb_aat_scratch_t { hb_bit_set_t *s = buffer_glyph_set.get_acquire (); if (s && buffer_glyph_set.cmpexch (s, nullptr)) + { + s->clear (); return s; + } s = (hb_bit_set_t *) hb_calloc (1, sizeof (hb_bit_set_t)); if (unlikely (!s)) @@ -124,13 +126,14 @@ struct hb_aat_apply_context_t : const OT::GDEF &gdef; bool has_glyph_classes; const hb_sorted_vector_t *range_flags = nullptr; + hb_mask_t subtable_flags = 0; + bool buffer_is_reversed = false; + // Caches bool using_buffer_glyph_set = false; hb_bit_set_t *buffer_glyph_set = nullptr; - const hb_bit_set_t *left_set = nullptr; - const hb_bit_set_t *right_set = nullptr; - const hb_bit_set_t *machine_glyph_set = nullptr; + const hb_bit_set_t *first_set = nullptr; + const hb_bit_set_t *second_set = nullptr; hb_aat_class_cache_t *machine_class_cache = nullptr; - hb_mask_t subtable_flags = 0; /* Unused. For debug tracing only. */ unsigned int lookup_index; @@ -146,6 +149,12 @@ struct hb_aat_apply_context_t : void set_lookup_index (unsigned int i) { lookup_index = i; } + void reverse_buffer () + { + buffer->reverse (); + buffer_is_reversed = !buffer_is_reversed; + } + void setup_buffer_glyph_set () { using_buffer_glyph_set = buffer->len >= 4 && buffer_glyph_set; @@ -156,11 +165,11 @@ struct hb_aat_apply_context_t : bool buffer_intersects_machine () const { if (likely (using_buffer_glyph_set)) - return buffer_glyph_set->intersects (*machine_glyph_set); + return buffer_glyph_set->intersects (*first_set); // Faster for shorter buffers. for (unsigned i = 0; i < buffer->len; i++) - if (machine_glyph_set->has (buffer->info[i].codepoint)) + if (first_set->has (buffer->info[i].codepoint)) return true; return false; } @@ -639,6 +648,23 @@ struct LookupFormat10 glyphs.add_range (firstGlyph, firstGlyph + glyphCount - 1); } + template + void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const + { + if (unlikely (!glyphCount)) return; + if (firstGlyph == DELETED_GLYPH) return; + const HBUINT8 *p = valueArrayZ.arrayZ; + for (unsigned i = 0; i < glyphCount; i++) + { + unsigned int v = 0; + unsigned int count = valueSize; + for (unsigned int j = 0; j < count; j++) + v = (v << 8) | *p++; + if (filter (v)) + glyphs.add (firstGlyph + i); + } + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -666,7 +692,7 @@ struct Lookup { const T* get_value (hb_codepoint_t glyph_id, unsigned int num_glyphs) const { - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); return u.format0.get_value (glyph_id, num_glyphs); case 2: hb_barrier (); return u.format2.get_value (glyph_id); case 4: hb_barrier (); return u.format4.get_value (glyph_id); @@ -678,7 +704,7 @@ struct Lookup const typename T::type get_value_or_null (hb_codepoint_t glyph_id, unsigned int num_glyphs) const { - switch (u.format) { + switch (u.format.v) { /* Format 10 cannot return a pointer. */ case 10: hb_barrier (); return u.format10.get_value_or_null (glyph_id); default: @@ -690,7 +716,7 @@ struct Lookup template void collect_glyphs (set_t &glyphs, unsigned int num_glyphs) const { - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); u.format0.collect_glyphs (glyphs, num_glyphs); return; case 2: hb_barrier (); u.format2.collect_glyphs (glyphs); return; case 4: hb_barrier (); u.format4.collect_glyphs (glyphs); return; @@ -703,12 +729,13 @@ struct Lookup template void collect_glyphs_filtered (set_t &glyphs, unsigned num_glyphs, const filter_t &filter) const { - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); u.format0.collect_glyphs_filtered (glyphs, num_glyphs, filter); return; case 2: hb_barrier (); u.format2.collect_glyphs_filtered (glyphs, filter); return; case 4: hb_barrier (); u.format4.collect_glyphs_filtered (glyphs, filter); return; case 6: hb_barrier (); u.format6.collect_glyphs_filtered (glyphs, filter); return; case 8: hb_barrier (); u.format8.collect_glyphs_filtered (glyphs, filter); return; + case 10: hb_barrier (); u.format10.collect_glyphs_filtered (glyphs, filter); return; default:return; } } @@ -724,9 +751,9 @@ struct Lookup bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return_trace (false); + if (!u.format.v.sanitize (c)) return_trace (false); hb_barrier (); - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); return_trace (u.format0.sanitize (c)); case 2: hb_barrier (); return_trace (u.format2.sanitize (c)); case 4: hb_barrier (); return_trace (u.format4.sanitize (c)); @@ -739,9 +766,9 @@ struct Lookup bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return_trace (false); + if (!u.format.v.sanitize (c)) return_trace (false); hb_barrier (); - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); return_trace (u.format0.sanitize (c, base)); case 2: hb_barrier (); return_trace (u.format2.sanitize (c, base)); case 4: hb_barrier (); return_trace (u.format4.sanitize (c, base)); @@ -754,7 +781,7 @@ struct Lookup protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ LookupFormat0 format0; LookupFormat2 format2; LookupFormat4 format4; @@ -763,7 +790,7 @@ struct Lookup LookupFormat10 format10; } u; public: - DEFINE_SIZE_UNION (2, format); + DEFINE_SIZE_UNION (2, format.v); }; DECLARE_NULL_NAMESPACE_BYTES_TEMPLATE1 (AAT, Lookup, 2); @@ -838,11 +865,6 @@ struct StateTable STATE_START_OF_LINE = 1, }; - template - void collect_glyphs (set_t &glyphs, unsigned num_glyphs) const - { - (this+classTable).collect_glyphs (glyphs, num_glyphs); - } template void collect_initial_glyphs (set_t &glyphs, unsigned num_glyphs, const table_t &table) const { @@ -1082,6 +1104,8 @@ struct SubtableGlyphCoverage for (unsigned i = 0; i < subtable_count; i++) { uint32_t offset = (uint32_t) subtableOffsets[i]; + // A font file called SFNSDisplay.ttf has value 0xFFFFFFFF in the offsets. + // Just ignore it. if (offset == 0 || offset == 0xFFFFFFFF) continue; if (unlikely (!subtableOffsets[i].sanitize (c, this, bytes))) @@ -1192,11 +1216,24 @@ struct StateTableDriver int state = StateTableT::STATE_START_OF_TEXT; // If there's only one range, we already checked the flag. auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr; + const bool start_state_safe_to_break_eot = + !c->table->is_actionable (machine.get_entry (StateTableT::STATE_START_OF_TEXT, CLASS_END_OF_TEXT)); for (buffer->idx = 0; buffer->successful;) { - /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */ - if (last_range) + unsigned int klass = likely (buffer->idx < buffer->len) ? + machine.get_class (buffer->cur().codepoint, num_glyphs, ac->machine_class_cache) : + (unsigned) CLASS_END_OF_TEXT; + resume: + DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx); + const EntryT &entry = machine.get_entry (state, klass); + const int next_state = machine.new_state (entry.newState); + + bool is_not_epsilon_transition = !(entry.flags & Flags::DontAdvance); + bool is_not_actionable = !c->table->is_actionable (entry); + + if (unlikely (last_range)) { + /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */ auto *range = last_range; if (buffer->idx < buffer->len) { @@ -1211,7 +1248,7 @@ struct StateTableDriver } if (!(range->flags & ac->subtable_flags)) { - if (buffer->idx == buffer->len || unlikely (!buffer->successful)) + if (buffer->idx == buffer->len) break; state = StateTableT::STATE_START_OF_TEXT; @@ -1219,13 +1256,42 @@ struct StateTableDriver continue; } } + else + { + // Fast path for when transitioning from start-state to start-state with + // no action and advancing. Do so as long as the class remains the same. + // This is common with runs of non-actionable glyphs. - unsigned int klass = likely (buffer->idx < buffer->len) ? - machine.get_class (buffer->cur().codepoint, num_glyphs, ac->machine_class_cache) : - (unsigned) CLASS_END_OF_TEXT; - DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx); - const EntryT &entry = machine.get_entry (state, klass); - const int next_state = machine.new_state (entry.newState); + bool is_null_transition = state == StateTableT::STATE_START_OF_TEXT && + next_state == StateTableT::STATE_START_OF_TEXT && + start_state_safe_to_break_eot && + is_not_actionable && + is_not_epsilon_transition && + !last_range; + + if (is_null_transition) + { + unsigned old_klass = klass; + do + { + c->transition (buffer, this, entry); + + if (buffer->idx == buffer->len || !buffer->successful) + break; + + (void) buffer->next_glyph (); + + klass = likely (buffer->idx < buffer->len) ? + machine.get_class (buffer->cur().codepoint, num_glyphs, ac->machine_class_cache) : + (unsigned) CLASS_END_OF_TEXT; + } while (klass == old_klass); + + if (buffer->idx == buffer->len || !buffer->successful) + break; + + goto resume; + } + } /* Conditions under which it's guaranteed safe-to-break before current glyph: * @@ -1292,10 +1358,10 @@ struct StateTableDriver state = next_state; DEBUG_MSG (APPLY, nullptr, "s%d", state); - if (buffer->idx == buffer->len || unlikely (!buffer->successful)) + if (buffer->idx == buffer->len) break; - if (!(entry.flags & Flags::DontAdvance) || buffer->max_ops-- <= 0) + if (is_not_epsilon_transition || buffer->max_ops-- <= 0) (void) buffer->next_glyph (); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-kerx-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-kerx-table.hh index ca4f2243346..2a6b813972f 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-kerx-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-kerx-table.hh @@ -120,12 +120,12 @@ struct KerxSubTableFormat0 } template - void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + void collect_glyphs (set_t &first_set, set_t &second_set, unsigned num_glyphs) const { for (const KernPair& pair : pairs) { - left_set.add (pair.left); - right_set.add (pair.right); + first_set.add (pair.left); + second_set.add (pair.right); } } @@ -140,7 +140,7 @@ struct KerxSubTableFormat0 int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const { - if (!(*c->left_set)[left] || !(*c->right_set)[right]) return 0; + if (!(*c->first_set)[left] || !(*c->second_set)[right]) return 0; return table.get_kerning (left, right, c); } }; @@ -396,10 +396,10 @@ struct KerxSubTableFormat1 } template - void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + void collect_glyphs (set_t &first_set, set_t &second_set, unsigned num_glyphs) const { - machine.collect_initial_glyphs (left_set, num_glyphs, *this); - //machine.collect_glyphs (right_set, num_glyphs); // right_set is unused for machine kerning + machine.collect_initial_glyphs (first_set, num_glyphs, *this); + //machine.collect_glyphs (second_set, num_glyphs); // second_set is unused for machine kerning } protected: @@ -451,10 +451,10 @@ struct KerxSubTableFormat2 } template - void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + void collect_glyphs (set_t &first_set, set_t &second_set, unsigned num_glyphs) const { - (this+leftClassTable).collect_glyphs (left_set, num_glyphs); - (this+rightClassTable).collect_glyphs (right_set, num_glyphs); + (this+leftClassTable).collect_glyphs (first_set, num_glyphs); + (this+rightClassTable).collect_glyphs (second_set, num_glyphs); } struct accelerator_t @@ -468,7 +468,7 @@ struct KerxSubTableFormat2 int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const { - if (!(*c->left_set)[left] || !(*c->right_set)[right]) return 0; + if (!(*c->first_set)[left] || !(*c->second_set)[right]) return 0; return table.get_kerning (left, right, c); } }; @@ -629,6 +629,8 @@ struct KerxSubTableFormat4 } o.attach_type() = OT::Layout::GPOS_impl::ATTACH_TYPE_MARK; o.attach_chain() = (int) mark - (int) buffer->idx; + if (c->buffer_is_reversed) + o.attach_chain() = -o.attach_chain(); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; } @@ -671,10 +673,10 @@ struct KerxSubTableFormat4 } template - void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + void collect_glyphs (set_t &first_set, set_t &second_set, unsigned num_glyphs) const { - machine.collect_initial_glyphs (left_set, num_glyphs, *this); - //machine.collect_glyphs (right_set, num_glyphs); // right_set is unused for machine kerning + machine.collect_initial_glyphs (first_set, num_glyphs, *this); + //machine.collect_glyphs (second_set, num_glyphs); // second_set is unused for machine kerning } protected: @@ -762,19 +764,19 @@ struct KerxSubTableFormat6 } template - void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + void collect_glyphs (set_t &first_set, set_t &second_set, unsigned num_glyphs) const { if (is_long ()) { const auto &t = u.l; - (this+t.rowIndexTable).collect_glyphs (left_set, num_glyphs); - (this+t.columnIndexTable).collect_glyphs (right_set, num_glyphs); + (this+t.rowIndexTable).collect_glyphs (first_set, num_glyphs); + (this+t.columnIndexTable).collect_glyphs (second_set, num_glyphs); } else { const auto &t = u.s; - (this+t.rowIndexTable).collect_glyphs (left_set, num_glyphs); - (this+t.columnIndexTable).collect_glyphs (right_set, num_glyphs); + (this+t.rowIndexTable).collect_glyphs (first_set, num_glyphs); + (this+t.columnIndexTable).collect_glyphs (second_set, num_glyphs); } } @@ -789,7 +791,7 @@ struct KerxSubTableFormat6 int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const { - if (!(*c->left_set)[left] || !(*c->right_set)[right]) return 0; + if (!(*c->first_set)[left] || !(*c->second_set)[right]) return 0; return table.get_kerning (left, right, c); } }; @@ -878,15 +880,15 @@ struct KerxSubTable } template - void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + void collect_glyphs (set_t &first_set, set_t &second_set, unsigned num_glyphs) const { unsigned int subtable_type = get_type (); switch (subtable_type) { - case 0: u.format0.collect_glyphs (left_set, right_set, num_glyphs); return; - case 1: u.format1.collect_glyphs (left_set, right_set, num_glyphs); return; - case 2: u.format2.collect_glyphs (left_set, right_set, num_glyphs); return; - case 4: u.format4.collect_glyphs (left_set, right_set, num_glyphs); return; - case 6: u.format6.collect_glyphs (left_set, right_set, num_glyphs); return; + case 0: u.format0.collect_glyphs (first_set, second_set, num_glyphs); return; + case 1: u.format1.collect_glyphs (first_set, second_set, num_glyphs); return; + case 2: u.format2.collect_glyphs (first_set, second_set, num_glyphs); return; + case 4: u.format4.collect_glyphs (first_set, second_set, num_glyphs); return; + case 6: u.format6.collect_glyphs (first_set, second_set, num_glyphs); return; default: return; } } @@ -923,8 +925,8 @@ struct KerxSubTable struct kern_subtable_accelerator_data_t { - hb_bit_set_t left_set; - hb_bit_set_t right_set; + hb_bit_set_t first_set; + hb_bit_set_t second_set; mutable hb_aat_class_cache_t class_cache; }; @@ -1017,9 +1019,8 @@ struct KerxTable if (HB_DIRECTION_IS_HORIZONTAL (c->buffer->props.direction) != st->u.header.is_horizontal ()) goto skip; - c->left_set = &subtable_accel.left_set; - c->right_set = &subtable_accel.right_set; - c->machine_glyph_set = &subtable_accel.left_set; + c->first_set = &subtable_accel.first_set; + c->second_set = &subtable_accel.second_set; c->machine_class_cache = &subtable_accel.class_cache; if (!c->buffer_intersects_machine ()) @@ -1051,8 +1052,8 @@ struct KerxTable } } - if (reverse) - c->buffer->reverse (); + if (reverse != c->buffer_is_reversed) + c->reverse_buffer (); { /* See comment in sanitize() for conditional here. */ @@ -1060,15 +1061,14 @@ struct KerxTable ret |= st->dispatch (c); } - if (reverse) - c->buffer->reverse (); - (void) c->buffer->message (c->font, "end subtable %u", c->lookup_index); skip: st = &StructAfter (*st); c->set_lookup_index (c->lookup_index + 1); } + if (c->buffer_is_reversed) + c->reverse_buffer (); return ret; } @@ -1133,7 +1133,7 @@ struct KerxTable if (unlikely (accel_data.subtable_accels.in_error ())) return accel_data; - st->collect_glyphs (subtable_accel.left_set, subtable_accel.right_set, num_glyphs); + st->collect_glyphs (subtable_accel.first_set, subtable_accel.second_set, num_glyphs); subtable_accel.class_cache.clear (); st = &StructAfter (*st); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-morx-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-morx-table.hh index 92b07eec6e5..2cbb86c7566 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-morx-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-morx-table.hh @@ -487,7 +487,7 @@ struct LigatureSubtable if (entry.flags & LigatureEntryT::SetComponent) { /* Never mark same index twice, in case DontAdvance was used... */ - if (match_length && match_positions[(match_length - 1u) % ARRAY_LENGTH (match_positions)] == buffer->out_len) + if (unlikely (match_length && match_positions[(match_length - 1u) % ARRAY_LENGTH (match_positions)] == buffer->out_len)) match_length--; match_positions[match_length++ % ARRAY_LENGTH (match_positions)] = buffer->out_len; @@ -640,7 +640,7 @@ struct NoncontextualSubtable for (unsigned int i = 0; i < count; i++) { /* This block copied from StateTableDriver::drive. Keep in sync. */ - if (last_range) + if (unlikely (last_range)) { auto *range = last_range; { @@ -1169,15 +1169,15 @@ struct Chain hb_map ([subtable_flags] (const hb_aat_map_t::range_flags_t _) -> bool { return subtable_flags & (_.flags); }))) goto skip; - c->subtable_flags = subtable_flags; - c->machine_glyph_set = accel ? &accel->subtables[i].glyph_set : &Null(hb_bit_set_t); - c->machine_class_cache = accel ? &accel->subtables[i].class_cache : nullptr; - if (!(coverage & ChainSubtable::AllDirections) && HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) != bool (coverage & ChainSubtable::Vertical)) goto skip; + c->subtable_flags = subtable_flags; + c->first_set = accel ? &accel->subtables[i].glyph_set : &Null(hb_bit_set_t); + c->machine_class_cache = accel ? &accel->subtables[i].class_cache : nullptr; + if (!c->buffer_intersects_machine ()) { (void) c->buffer->message (c->font, "skipped chainsubtable %u because no glyph matches", c->lookup_index); @@ -1219,22 +1219,21 @@ struct Chain if (!c->buffer->message (c->font, "start chainsubtable %u", c->lookup_index)) goto skip; - if (reverse) - c->buffer->reverse (); + if (reverse != c->buffer_is_reversed) + c->reverse_buffer (); subtable->apply (c); - if (reverse) - c->buffer->reverse (); - (void) c->buffer->message (c->font, "end chainsubtable %u", c->lookup_index); - if (unlikely (!c->buffer->successful)) return; + if (unlikely (!c->buffer->successful)) break; skip: subtable = &StructAfter> (*subtable); c->set_lookup_index (c->lookup_index + 1); } + if (c->buffer_is_reversed) + c->reverse_buffer (); } unsigned int get_size () const { return length; } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-algs.hh b/src/java.desktop/share/native/libharfbuzz/hb-algs.hh index 6e250bfdef0..651ffcda01d 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-algs.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-algs.hh @@ -78,129 +78,246 @@ /* - * Big-endian integers. + * Fixed-endian integers / floats. */ + /* Endian swap, used in Windows related backends */ static inline constexpr uint16_t hb_uint16_swap (uint16_t v) { return (v >> 8) | (v << 8); } static inline constexpr uint32_t hb_uint32_swap (uint32_t v) { return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); } -#ifndef HB_FAST_INT_ACCESS +template +struct __attribute__((packed)) hb_packed_t { Type v; }; + +#ifndef HB_FAST_NUM_ACCESS + #if defined(__OPTIMIZE__) && \ defined(__BYTE_ORDER) && \ (__BYTE_ORDER == __BIG_ENDIAN || \ (__BYTE_ORDER == __LITTLE_ENDIAN && \ hb_has_builtin(__builtin_bswap16) && \ - hb_has_builtin(__builtin_bswap32))) -#define HB_FAST_INT_ACCESS 1 + hb_has_builtin(__builtin_bswap32) && \ + hb_has_builtin(__builtin_bswap64))) +#define HB_FAST_NUM_ACCESS 1 #else -#define HB_FAST_INT_ACCESS 0 -#endif +#define HB_FAST_NUM_ACCESS 0 #endif -template -struct BEInt; -template -struct BEInt +// https://github.com/harfbuzz/harfbuzz/issues/5456 +#if defined(__GNUC__) && !defined(__clang__) && (__GNUC__ <= 12) +#undef HB_FAST_NUM_ACCESS +#define HB_FAST_NUM_ACCESS 0 +#endif + +#endif + +template +struct HBInt; +template +struct HBInt { public: - BEInt () = default; - constexpr BEInt (Type V) : v {uint8_t (V)} {} + HBInt () = default; + constexpr HBInt (Type V) : v {uint8_t (V)} {} constexpr operator Type () const { return v; } private: uint8_t v; }; -template -struct BEInt +template +struct HBInt { - struct __attribute__((packed)) packed_uint16_t { uint16_t v; }; - public: - BEInt () = default; + HBInt () = default; - BEInt (Type V) -#if HB_FAST_INT_ACCESS -#if __BYTE_ORDER == __LITTLE_ENDIAN - { ((packed_uint16_t *) v)->v = __builtin_bswap16 (V); } -#else /* __BYTE_ORDER == __BIG_ENDIAN */ - { ((packed_uint16_t *) v)->v = V; } -#endif + HBInt (Type V) +#if HB_FAST_NUM_ACCESS + { + if (BE == (__BYTE_ORDER == __BIG_ENDIAN)) + ((hb_packed_t *) v)->v = V; + else + ((hb_packed_t *) v)->v = __builtin_bswap16 (V); + } #else - : v {uint8_t ((V >> 8) & 0xFF), - uint8_t ((V ) & 0xFF)} {} + : v {BE ? uint8_t ((V >> 8) & 0xFF) : uint8_t ((V ) & 0xFF), + BE ? uint8_t ((V ) & 0xFF) : uint8_t ((V >> 8) & 0xFF)} {} #endif - constexpr operator Type () const { -#if HB_FAST_INT_ACCESS -#if __BYTE_ORDER == __LITTLE_ENDIAN - return __builtin_bswap16 (((packed_uint16_t *) v)->v); -#else /* __BYTE_ORDER == __BIG_ENDIAN */ - return ((packed_uint16_t *) v)->v; -#endif + constexpr operator Type () const + { +#if HB_FAST_NUM_ACCESS + return (BE == (__BYTE_ORDER == __BIG_ENDIAN)) ? + ((const hb_packed_t *) v)->v + : + __builtin_bswap16 (((const hb_packed_t *) v)->v) + ; #else - return (v[0] << 8) - + (v[1] ); + return (BE ? (v[0] << 8) : (v[0] )) + + (BE ? (v[1] ) : (v[1] << 8)); #endif } private: uint8_t v[2]; }; -template -struct BEInt +template +struct HBInt { static_assert (!std::is_signed::value, ""); public: - BEInt () = default; - constexpr BEInt (Type V) : v {uint8_t ((V >> 16) & 0xFF), - uint8_t ((V >> 8) & 0xFF), - uint8_t ((V ) & 0xFF)} {} + HBInt () = default; + constexpr HBInt (Type V) : v {BE ? uint8_t ((V >> 16) & 0xFF) : uint8_t ((V >> 16) & 0xFF), + BE ? uint8_t ((V >> 8) & 0xFF) : uint8_t ((V >> 8) & 0xFF), + BE ? uint8_t ((V ) & 0xFF) : uint8_t ((V ) & 0xFF)} {} - constexpr operator Type () const { return (v[0] << 16) - + (v[1] << 8) - + (v[2] ); } + constexpr operator Type () const { return (BE ? (v[0] << 16) : (v[0] )) + + (BE ? (v[1] << 8) : (v[1] << 8)) + + (BE ? (v[2] ) : (v[2] << 16)); } private: uint8_t v[3]; }; -template -struct BEInt +template +struct HBInt { - struct __attribute__((packed)) packed_uint32_t { uint32_t v; }; + template + friend struct HBFloat; public: - BEInt () = default; + HBInt () = default; - BEInt (Type V) -#if HB_FAST_INT_ACCESS -#if __BYTE_ORDER == __LITTLE_ENDIAN - { ((packed_uint32_t *) v)->v = __builtin_bswap32 (V); } -#else /* __BYTE_ORDER == __BIG_ENDIAN */ - { ((packed_uint32_t *) v)->v = V; } -#endif + HBInt (Type V) +#if HB_FAST_NUM_ACCESS + { + if (BE == (__BYTE_ORDER == __BIG_ENDIAN)) + ((hb_packed_t *) v)->v = V; + else + ((hb_packed_t *) v)->v = __builtin_bswap32 (V); + } #else - : v {uint8_t ((V >> 24) & 0xFF), - uint8_t ((V >> 16) & 0xFF), - uint8_t ((V >> 8) & 0xFF), - uint8_t ((V ) & 0xFF)} {} + : v {BE ? uint8_t ((V >> 24) & 0xFF) : uint8_t ((V ) & 0xFF), + BE ? uint8_t ((V >> 16) & 0xFF) : uint8_t ((V >> 8) & 0xFF), + BE ? uint8_t ((V >> 8) & 0xFF) : uint8_t ((V >> 16) & 0xFF), + BE ? uint8_t ((V ) & 0xFF) : uint8_t ((V >> 24) & 0xFF)} {} #endif constexpr operator Type () const { -#if HB_FAST_INT_ACCESS -#if __BYTE_ORDER == __LITTLE_ENDIAN - return __builtin_bswap32 (((packed_uint32_t *) v)->v); -#else /* __BYTE_ORDER == __BIG_ENDIAN */ - return ((packed_uint32_t *) v)->v; -#endif +#if HB_FAST_NUM_ACCESS + return (BE == (__BYTE_ORDER == __BIG_ENDIAN)) ? + ((const hb_packed_t *) v)->v + : + __builtin_bswap32 (((const hb_packed_t *) v)->v) + ; #else - return (v[0] << 24) - + (v[1] << 16) - + (v[2] << 8) - + (v[3] ); + return (BE ? (v[0] << 24) : (v[0] )) + + (BE ? (v[1] << 16) : (v[1] << 8)) + + (BE ? (v[2] << 8) : (v[2] << 16)) + + (BE ? (v[3] ) : (v[3] << 24)); #endif } private: uint8_t v[4]; }; +template +struct HBInt +{ + template + friend struct HBFloat; + + public: + HBInt () = default; + + HBInt (Type V) +#if HB_FAST_NUM_ACCESS + { + if (BE == (__BYTE_ORDER == __BIG_ENDIAN)) + ((hb_packed_t *) v)->v = V; + else + ((hb_packed_t *) v)->v = __builtin_bswap64 (V); + } +#else + : v {BE ? uint8_t ((V >> 56) & 0xFF) : uint8_t ((V ) & 0xFF), + BE ? uint8_t ((V >> 48) & 0xFF) : uint8_t ((V >> 8) & 0xFF), + BE ? uint8_t ((V >> 40) & 0xFF) : uint8_t ((V >> 16) & 0xFF), + BE ? uint8_t ((V >> 32) & 0xFF) : uint8_t ((V >> 24) & 0xFF), + BE ? uint8_t ((V >> 24) & 0xFF) : uint8_t ((V >> 32) & 0xFF), + BE ? uint8_t ((V >> 16) & 0xFF) : uint8_t ((V >> 40) & 0xFF), + BE ? uint8_t ((V >> 8) & 0xFF) : uint8_t ((V >> 48) & 0xFF), + BE ? uint8_t ((V ) & 0xFF) : uint8_t ((V >> 56) & 0xFF)} {} +#endif + + constexpr operator Type () const { +#if HB_FAST_NUM_ACCESS + return (BE == (__BYTE_ORDER == __BIG_ENDIAN)) ? + ((const hb_packed_t *) v)->v + : + __builtin_bswap64 (((const hb_packed_t *) v)->v) + ; +#else + return (BE ? (uint64_t (v[0]) << 56) : (uint64_t (v[0]) )) + + (BE ? (uint64_t (v[1]) << 48) : (uint64_t (v[1]) << 8)) + + (BE ? (uint64_t (v[2]) << 40) : (uint64_t (v[2]) << 16)) + + (BE ? (uint64_t (v[3]) << 32) : (uint64_t (v[3]) << 24)) + + (BE ? (uint64_t (v[4]) << 24) : (uint64_t (v[4]) << 32)) + + (BE ? (uint64_t (v[5]) << 16) : (uint64_t (v[5]) << 40)) + + (BE ? (uint64_t (v[6]) << 8) : (uint64_t (v[6]) << 48)) + + (BE ? (uint64_t (v[7]) ) : (uint64_t (v[7]) << 56)); +#endif + } + private: uint8_t v[8]; +}; /* Floats. */ +template +struct HBFloat +{ + using IntType = typename std::conditional::type; + + public: + HBFloat () = default; + + HBFloat (Type V) + { +#if HB_FAST_NUM_ACCESS + { + if (BE == (__BYTE_ORDER == __BIG_ENDIAN)) + { + ((hb_packed_t *) v)->v = V; + return; + } + } +#endif + + union { + hb_packed_t f; + hb_packed_t i; + } u = {{V}}; + + const HBInt I = u.i.v; + for (unsigned i = 0; i < Bytes; i++) + v[i] = I.v[i]; + } + + /* c++14 constexpr */ operator Type () const + { +#if HB_FAST_NUM_ACCESS + { + if (BE == (__BYTE_ORDER == __BIG_ENDIAN)) + return ((const hb_packed_t *) v)->v; + } +#endif + + HBInt I; + for (unsigned i = 0; i < Bytes; i++) + I.v[i] = v[i]; + + union { + hb_packed_t i; + hb_packed_t f; + } u = {{I}}; + + return u.f.v; + } + private: uint8_t v[Bytes]; +}; + + /* We want our rounding towards +infinity. */ static inline double _hb_roundf (double x) { return floor (x + .5); } @@ -210,6 +327,27 @@ _hb_roundf (float x) { return floorf (x + .5f); } #define roundf(x) _hb_roundf(x) +static inline void +hb_sincos (float rotation, float &s, float &c) +{ +#ifdef HAVE_SINCOSF + sincosf (rotation, &s, &c); +#else + c = cosf (rotation); + s = sinf (rotation); +#endif +} +static inline void +hb_sincos (double rotation, double &s, double &c) +{ +#ifdef HAVE_SINCOS + sincos (rotation, &s, &c); +#else + c = cos (rotation); + s = sin (rotation); +#endif +} + /* Encodes three unsigned integers in one 64-bit number. If the inputs have more than 21 bits, * values will be truncated / overlap, and might not decode exactly. */ @@ -734,6 +872,17 @@ HB_FUNCOBJ (hb_clamp); * Bithacks. */ +/* Return the number of 1 bits in a uint8_t; faster than hb_popcount() */ +static inline unsigned +hb_popcount8 (uint8_t v) +{ + static const uint8_t popcount4[16] = { + 0, 1, 1, 2, 1, 2, 2, 3, + 1, 2, 2, 3, 2, 3, 3, 4 + }; + return popcount4[v & 0xF] + popcount4[v >> 4]; +} + /* Return the number of 1 bits in v. */ template static inline unsigned int @@ -1070,6 +1219,7 @@ _hb_cmp_operator (const void *pkey, const void *pval) } template +HB_HOT static inline bool hb_bsearch_impl (unsigned *pos, /* Out */ const K& key, diff --git a/src/java.desktop/share/native/libharfbuzz/hb-alloc-pool.hh b/src/java.desktop/share/native/libharfbuzz/hb-alloc-pool.hh new file mode 100644 index 00000000000..cb0d7aa7acd --- /dev/null +++ b/src/java.desktop/share/native/libharfbuzz/hb-alloc-pool.hh @@ -0,0 +1,105 @@ +/* + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_ALLOC_POOL_HH +#define HB_ALLOC_POOL_HH + +#include "hb-vector.hh" + +/* Memory pool for persistent small- to medium-sized allocations. + * + * Some AI musings on this, not necessarily true: + * + * This is a very simple implementation, but it's good enough for our + * purposes. It's not thread-safe. It's not very fast. It's not + * very memory efficient. It's not very cache efficient. It's not + * very anything efficient. But it's simple and it works. And it's + * good enough for our purposes. If you need something more + * sophisticated, use a real allocator. Or use a real language. */ + +struct hb_alloc_pool_t +{ + unsigned ChunkSize = 65536 - 2 * sizeof (void *); + + void *alloc (size_t size, unsigned alignment = 2 * sizeof (void *)) + { + if (unlikely (chunks.in_error ())) return nullptr; + + assert (alignment > 0); + assert (alignment <= 2 * sizeof (void *)); + assert ((alignment & (alignment - 1)) == 0); /* power of two */ + + if (size > (ChunkSize) / 4) + { + /* Big chunk, allocate separately. */ + hb_vector_t chunk; + if (unlikely (!chunk.resize (size))) return nullptr; + void *ret = chunk.arrayZ; + chunks.push (std::move (chunk)); + if (chunks.in_error ()) return nullptr; + if (chunks.length > 1) + { + // Bring back the previous last chunk to the end, so that + // we can continue to allocate from it. + hb_swap (chunks.arrayZ[chunks.length - 1], chunks.arrayZ[chunks.length - 2]); + } + return ret; + } + + unsigned pad = (unsigned) ((alignment - ((uintptr_t) current_chunk.arrayZ & (alignment - 1))) & (alignment - 1)); + + // Small chunk, allocate from the last chunk. + if (current_chunk.length < pad + size) + { + chunks.push (); + if (unlikely (chunks.in_error ())) return nullptr; + hb_vector_t &chunk = chunks.arrayZ[chunks.length - 1]; + if (unlikely (!chunk.resize (ChunkSize))) return nullptr; + current_chunk = chunk; + pad = (unsigned) ((alignment - ((uintptr_t) current_chunk.arrayZ & (alignment - 1))) & (alignment - 1)); + } + + current_chunk += pad; + + assert (current_chunk.length >= size); + void *ret = current_chunk.arrayZ; + current_chunk += size; + return ret; + } + + void discard (void *p_, size_t size) + { + // Reclaim memory if we can. + char *p = (char *) p_; + if (current_chunk.arrayZ == p + size && current_chunk.backwards_length >= size) + current_chunk -= size; + } + + private: + hb_vector_t> chunks; + hb_array_t current_chunk; +}; + + +#endif /* HB_ALLOC_POOL_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-array.hh b/src/java.desktop/share/native/libharfbuzz/hb-array.hh index d65bbc5c711..71d3bcdf1ea 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-array.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-array.hh @@ -291,6 +291,13 @@ struct hb_array_t : hb_iter_with_fallback_t, Type&> && (unsigned int) (arrayZ + length - (const char *) p) >= size; } + template + bool check_end (const void *p) const + { + return (uintptr_t) (((const char *) p) - arrayZ) <= length; + } + /* Only call if you allocated the underlying array using hb_malloc() or similar. */ void fini () { hb_free ((void *) arrayZ); arrayZ = nullptr; length = 0; } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh b/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh index 80bd90e87dc..05aaf5a155e 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh @@ -40,7 +40,6 @@ * Atomic integers and pointers. */ - /* We need external help for these */ #if defined(hb_atomic_int_impl_add) \ @@ -80,27 +79,11 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) #include +#define HB_STL_ATOMIC_IMPL + #define _hb_memory_r_barrier() std::atomic_thread_fence(std::memory_order_acquire) #define _hb_memory_w_barrier() std::atomic_thread_fence(std::memory_order_release) -#define hb_atomic_int_impl_add(AI, V) (reinterpret_cast::type> *> (AI)->fetch_add ((V), std::memory_order_acq_rel)) -#define hb_atomic_int_impl_set_relaxed(AI, V) (reinterpret_cast::type> *> (AI)->store ((V), std::memory_order_relaxed)) -#define hb_atomic_int_impl_set(AI, V) (reinterpret_cast::type> *> (AI)->store ((V), std::memory_order_release)) -#define hb_atomic_int_impl_get_relaxed(AI) (reinterpret_cast::type> const *> (AI)->load (std::memory_order_relaxed)) -#define hb_atomic_int_impl_get(AI) (reinterpret_cast::type> const *> (AI)->load (std::memory_order_acquire)) - -#define hb_atomic_ptr_impl_set_relaxed(P, V) (reinterpret_cast *> (P)->store ((V), std::memory_order_relaxed)) -#define hb_atomic_ptr_impl_get_relaxed(P) (reinterpret_cast const *> (P)->load (std::memory_order_relaxed)) -#define hb_atomic_ptr_impl_get(P) (reinterpret_cast *> (P)->load (std::memory_order_acquire)) -static inline bool -_hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) -{ - const void *O = O_; // Need lvalue - return reinterpret_cast *> (P)->compare_exchange_weak (O, N, std::memory_order_acq_rel, std::memory_order_relaxed); -} -#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N)) - - #else /* defined(HB_NO_MT) */ #define hb_atomic_int_impl_add(AI, V) ((*(AI) += (V)) - (V)) @@ -159,6 +142,76 @@ inline T hb_atomic_int_impl_get (const T *AI) { T v = *AI; _hb_memory_r_barrie inline void *hb_atomic_ptr_impl_get (void ** const P) { void *v = *P; _hb_memory_r_barrier (); return v; } #endif +#ifdef HB_STL_ATOMIC_IMPL +template +struct hb_atomic_t +{ + hb_atomic_t () = default; + constexpr hb_atomic_t (T v) : v (v) {} + constexpr hb_atomic_t (const hb_atomic_t& o) : v (o.get_relaxed ()) {} + constexpr hb_atomic_t (hb_atomic_t&& o) : v (o.get_relaxed ()) { o.set_relaxed ({}); } + + hb_atomic_t &operator= (const hb_atomic_t& o) { set_relaxed (o.get_relaxed ()); return *this; } + hb_atomic_t &operator= (hb_atomic_t&& o){ set_relaxed (o.get_relaxed ()); o.set_relaxed ({}); return *this; } + hb_atomic_t &operator= (T v_) + { + set_relaxed (v_); + return *this; + } + operator T () const { return get_relaxed (); } + + void set_relaxed (T v_) { v.store (v_, std::memory_order_relaxed); } + void set_release (T v_) { v.store (v_, std::memory_order_release); } + T get_relaxed () const { return v.load (std::memory_order_relaxed); } + T get_acquire () const { return v.load (std::memory_order_acquire); } + T inc () { return v.fetch_add (1, std::memory_order_acq_rel); } + T dec () { return v.fetch_add (-1, std::memory_order_acq_rel); } + + int operator++ (int) { return inc (); } + int operator-- (int) { return dec (); } + + friend void swap (hb_atomic_t &a, hb_atomic_t &b) noexcept + { + T v = a.get_acquire (); + a.set_relaxed (b.get_acquire ()); + b.set_relaxed (v); + } + + std::atomic v = 0; +}; + +template +struct hb_atomic_t +{ + hb_atomic_t () = default; + constexpr hb_atomic_t (T *v) : v (v) {} + hb_atomic_t (const hb_atomic_t &other) = delete; + + void init (T *v_ = nullptr) { set_relaxed (v_); } + void set_relaxed (T *v_) { v.store (v_, std::memory_order_relaxed); } + T *get_relaxed () const { return v.load (std::memory_order_relaxed); } + T *get_acquire () const { return v.load (std::memory_order_acquire); } + bool cmpexch (T *old, T *new_) { return v.compare_exchange_weak (old, new_, std::memory_order_acq_rel, std::memory_order_relaxed); } + + operator bool () const { return get_acquire () != nullptr; } + T *operator->() const { return get_acquire (); } + template + operator C * () const + { + return get_acquire (); + } + + friend void swap (hb_atomic_t &a, hb_atomic_t &b) noexcept + { + T *p = a.get_acquire (); + a.set_relaxed (b.get_acquire ()); + b.set_relaxed (p); + } + + std::atomic v = nullptr; +}; + +#else template struct hb_atomic_t @@ -178,7 +231,6 @@ struct hb_atomic_t int operator ++ (int) { return inc (); } int operator -- (int) { return dec (); } - long operator |= (long v_) { set_relaxed (get_relaxed () | v_); return *this; } T v = 0; }; @@ -194,7 +246,7 @@ struct hb_atomic_t void set_relaxed (T* v_) { hb_atomic_ptr_impl_set_relaxed (&v, v_); } T *get_relaxed () const { return (T *) hb_atomic_ptr_impl_get_relaxed (&v); } T *get_acquire () const { return (T *) hb_atomic_ptr_impl_get ((void **) &v); } - bool cmpexch (const T *old, T *new_) { return hb_atomic_ptr_impl_cmpexch ((void **) &v, (void *) old, (void *) new_); } + bool cmpexch (T *old, T *new_) { return hb_atomic_ptr_impl_cmpexch ((void **) &v, (void *) old, (void *) new_); } operator bool () const { return get_acquire () != nullptr; } T * operator -> () const { return get_acquire (); } @@ -203,6 +255,8 @@ struct hb_atomic_t T *v = nullptr; }; +#endif + static inline bool hb_barrier () { _hb_compiler_memory_r_barrier (); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-bimap.hh b/src/java.desktop/share/native/libharfbuzz/hb-bimap.hh index f541472544a..f9c0e8870ff 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-bimap.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-bimap.hh @@ -176,7 +176,7 @@ struct hb_inc_bimap_t { hb_codepoint_t count = get_population (); hb_vector_t work; - if (unlikely (!work.resize (count, false))) return; + if (unlikely (!work.resize_dirty (count))) return; for (hb_codepoint_t rhs = 0; rhs < count; rhs++) work.arrayZ[rhs] = back_map[rhs]; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-bit-page.hh b/src/java.desktop/share/native/libharfbuzz/hb-bit-page.hh index 9562a9674a5..902db195507 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-bit-page.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-bit-page.hh @@ -142,6 +142,7 @@ struct hb_bit_page_t bool operator [] (hb_codepoint_t g) const { return get (g); } bool operator () (hb_codepoint_t g) const { return get (g); } + bool has (hb_codepoint_t g) const { return get (g); } void add_range (hb_codepoint_t a, hb_codepoint_t b) { @@ -290,7 +291,7 @@ struct hb_bit_page_t unsigned int j = m & ELT_MASK; const elt_t vv = v[i] & ~((elt_t (1) << j) - 1); - for (const elt_t *p = &vv; i < len (); p = &v[++i]) + for (const elt_t *p = &vv; i < len (); p = ((const elt_t *) &v[0]) + (++i)) if (*p) { *codepoint = i * ELT_BITS + elt_get_min (*p); @@ -346,6 +347,36 @@ struct hb_bit_page_t return 0; } + /* + * Iterator implementation. + */ + struct iter_t : hb_iter_with_fallback_t + { + static constexpr bool is_sorted_iterator = true; + iter_t (const hb_bit_page_t &s_ = Null (hb_bit_page_t), bool init = true) : s (&s_), v (INVALID) + { + if (init) + v = s->get_min (); + } + + typedef hb_codepoint_t __item_t__; + hb_codepoint_t __item__ () const { return v; } + bool __more__ () const { return v != INVALID; } + void __next__ () { + s->next (&v); + } + void __prev__ () { s->previous (&v); } + iter_t end () const { return iter_t (*s, false); } + bool operator != (const iter_t& o) const + { return v != o.v; } + + protected: + const hb_bit_page_t *s; + hb_codepoint_t v; + }; + iter_t iter () const { return iter_t (*this); } + operator iter_t () const { return iter (); } + static constexpr hb_codepoint_t INVALID = HB_SET_VALUE_INVALID; typedef unsigned long long elt_t; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-bit-set-invertible.hh b/src/java.desktop/share/native/libharfbuzz/hb-bit-set-invertible.hh index 740a2437671..4028dd63531 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-bit-set-invertible.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-bit-set-invertible.hh @@ -368,7 +368,7 @@ struct hb_bit_set_invertible_t unsigned __len__ () const { return l; } iter_t end () const { return iter_t (*s, false); } bool operator != (const iter_t& o) const - { return v != o.v || s != o.s; } + { return v != o.v; } protected: const hb_bit_set_invertible_t *s; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh b/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh index 799c3607599..f86d5750854 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh @@ -91,10 +91,10 @@ struct hb_bit_set_t if (pages.length < count && (unsigned) pages.allocated < count && count <= 2) exact_size = true; // Most sets are small and local - if (unlikely (!pages.resize (count, clear, exact_size) || - !page_map.resize (count, clear))) + if (unlikely (!pages.resize_full (count, clear, exact_size) || + !page_map.resize_full (count, clear, false))) { - pages.resize (page_map.length, clear, exact_size); + pages.resize_full (page_map.length, clear, exact_size); successful = false; return false; } @@ -108,10 +108,11 @@ struct hb_bit_set_t page_map.alloc (sz); } - void reset () + hb_bit_set_t& reset () { successful = true; clear (); + return *this; } void clear () @@ -394,7 +395,7 @@ struct hb_bit_set_t { if (unlikely (!successful)) return; unsigned int count = other.pages.length; - if (unlikely (!resize (count, false, exact_size))) + if (unlikely (!resize (count, false, exact_size))) return; population = other.population; @@ -922,7 +923,7 @@ struct hb_bit_set_t unsigned __len__ () const { return l; } iter_t end () const { return iter_t (*s, false); } bool operator != (const iter_t& o) const - { return s != o.s || v != o.v; } + { return v != o.v; } protected: const hb_bit_set_t *s; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-unicode.hh b/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-unicode.hh index 9e21beebd34..87c1524df6f 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-unicode.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-unicode.hh @@ -32,7 +32,7 @@ #include "hb.hh" -#line 36 "hb-buffer-deserialize-text-unicode.hh" +#line 33 "hb-buffer-deserialize-text-unicode.hh" static const unsigned char _deserialize_text_unicode_trans_keys[] = { 0u, 0u, 43u, 102u, 48u, 102u, 48u, 124u, 48u, 57u, 62u, 124u, 48u, 124u, 60u, 117u, 85u, 117u, 85u, 117u, 0 @@ -150,12 +150,12 @@ _hb_buffer_deserialize_text_unicode (hb_buffer_t *buffer, hb_glyph_info_t info = {0}; const hb_glyph_position_t pos = {0}; -#line 154 "hb-buffer-deserialize-text-unicode.hh" +#line 147 "hb-buffer-deserialize-text-unicode.hh" { cs = deserialize_text_unicode_start; } -#line 159 "hb-buffer-deserialize-text-unicode.hh" +#line 150 "hb-buffer-deserialize-text-unicode.hh" { int _slen; int _trans; @@ -215,7 +215,7 @@ _resume: hb_memset (&info, 0, sizeof (info)); } break; -#line 219 "hb-buffer-deserialize-text-unicode.hh" +#line 203 "hb-buffer-deserialize-text-unicode.hh" } _again: @@ -238,7 +238,7 @@ _again: *end_ptr = p; } break; -#line 242 "hb-buffer-deserialize-text-unicode.hh" +#line 224 "hb-buffer-deserialize-text-unicode.hh" } } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer-serialize.cc b/src/java.desktop/share/native/libharfbuzz/hb-buffer-serialize.cc index 763172818c4..6787da6f65f 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-buffer-serialize.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer-serialize.cc @@ -427,7 +427,7 @@ _hb_buffer_serialize_unicode_text (hb_buffer_t *buffer, * #HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES flag is set. Then, * - If #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set, `=` then #hb_glyph_info_t.cluster. * - If #HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS is not set, the #hb_glyph_position_t in the format: - * - If both #hb_glyph_position_t.x_offset and #hb_glyph_position_t.y_offset are not 0, `@x_offset,y_offset`. Then, + * - If #hb_glyph_position_t.x_offset and #hb_glyph_position_t.y_offset are not both 0, `@x_offset,y_offset`. Then, * - `+x_advance`, then `,y_advance` if #hb_glyph_position_t.y_advance is not 0. Then, * - If #HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS is set, the #hb_glyph_extents_t in the format `` * diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc b/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc index 56299d9b7e0..0c9190bf6f8 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc @@ -163,7 +163,7 @@ buffer_verify_unsafe_to_break (hb_buffer_t *buffer, hb_buffer_append (fragment, text_buffer, text_start, text_end); if (!hb_shape_full (font, fragment, features, num_features, shapers) || - fragment->successful || fragment->shaping_failed) + fragment->successful) { hb_buffer_destroy (reconstruction); hb_buffer_destroy (fragment); @@ -313,11 +313,11 @@ buffer_verify_unsafe_to_concat (hb_buffer_t *buffer, * Shape the two fragment streams. */ if (!hb_shape_full (font, fragments[0], features, num_features, shapers) || - !fragments[0]->successful || fragments[0]->shaping_failed) + !fragments[0]->successful) goto out; if (!hb_shape_full (font, fragments[1], features, num_features, shapers) || - !fragments[1]->successful || fragments[1]->shaping_failed) + !fragments[1]->successful) goto out; if (!forward) diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc b/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc index c0600fd839b..8f6da312cdd 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc @@ -158,14 +158,15 @@ hb_segment_properties_overlay (hb_segment_properties_t *p, bool hb_buffer_t::enlarge (unsigned int size) { - if (unlikely (!successful)) - return false; if (unlikely (size > max_len)) { successful = false; return false; } + if (unlikely (!successful)) + return false; + unsigned int new_allocated = allocated; hb_glyph_position_t *new_pos = nullptr; hb_glyph_info_t *new_info = nullptr; @@ -226,6 +227,13 @@ hb_buffer_t::shift_forward (unsigned int count) assert (have_output); if (unlikely (!ensure (len + count))) return false; + max_ops -= len - idx; + if (unlikely (max_ops < 0)) + { + successful = false; + return false; + } + memmove (info + idx + count, info + idx, (len - idx) * sizeof (info[0])); if (idx + count > len) { @@ -297,7 +305,6 @@ hb_buffer_t::clear () props = default_props; successful = true; - shaping_failed = false; have_output = false; have_positions = false; @@ -320,7 +327,6 @@ hb_buffer_t::enter () { deallocate_var_all (); serial = 0; - shaping_failed = false; scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT; unsigned mul; if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_LEN_FACTOR, &mul))) @@ -339,7 +345,6 @@ hb_buffer_t::leave () max_ops = HB_BUFFER_MAX_OPS_DEFAULT; deallocate_var_all (); serial = 0; - // Intentionally not reseting shaping_failed, such that it can be inspected. } @@ -520,7 +525,19 @@ hb_buffer_t::set_masks (hb_mask_t value, hb_mask_t not_mask = ~mask; value &= mask; + max_ops -= len; + if (unlikely (max_ops < 0)) + successful = false; + unsigned int count = len; + + if (cluster_start == 0 && cluster_end == (unsigned int) -1) + { + for (unsigned int i = 0; i < count; i++) + info[i].mask = (info[i].mask & not_mask) | value; + return; + } + for (unsigned int i = 0; i < count; i++) if (cluster_start <= info[i].cluster && info[i].cluster < cluster_end) info[i].mask = (info[i].mask & not_mask) | value; @@ -536,6 +553,10 @@ hb_buffer_t::merge_clusters_impl (unsigned int start, return; } + max_ops -= end - start; + if (unlikely (max_ops < 0)) + successful = false; + unsigned int cluster = info[start].cluster; for (unsigned int i = start + 1; i < end; i++) @@ -569,6 +590,10 @@ hb_buffer_t::merge_out_clusters (unsigned int start, if (unlikely (end - start < 2)) return; + max_ops -= end - start; + if (unlikely (max_ops < 0)) + successful = false; + unsigned int cluster = out_info[start].cluster; for (unsigned int i = start + 1; i < end; i++) @@ -726,7 +751,6 @@ DEFINE_NULL_INSTANCE (hb_buffer_t) = HB_SEGMENT_PROPERTIES_DEFAULT, false, /* successful */ - true, /* shaping_failed */ false, /* have_output */ true /* have_positions */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh b/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh index 81c0f4a72e3..1c46981cc9c 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh @@ -32,6 +32,7 @@ #include "hb.hh" #include "hb-unicode.hh" +#include "hb-set-digest.hh" static_assert ((sizeof (hb_glyph_info_t) == 20), ""); @@ -44,14 +45,14 @@ HB_MARK_AS_FLAG_T (hb_buffer_diff_flags_t); enum hb_buffer_scratch_flags_t { HB_BUFFER_SCRATCH_FLAG_DEFAULT = 0x00000000u, - HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII = 0x00000001u, + HB_BUFFER_SCRATCH_FLAG_HAS_FRACTION_SLASH = 0x00000001u, HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES = 0x00000002u, HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK = 0x00000004u, HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT = 0x00000008u, HB_BUFFER_SCRATCH_FLAG_HAS_CGJ = 0x00000010u, - HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS = 0x00000020u, - HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE = 0x00000040u, - HB_BUFFER_SCRATCH_FLAG_HAS_VARIATION_SELECTOR_FALLBACK= 0x00000080u, + HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE = 0x00000020u, + HB_BUFFER_SCRATCH_FLAG_HAS_VARIATION_SELECTOR_FALLBACK= 0x00000040u, + HB_BUFFER_SCRATCH_FLAG_HAS_CONTINUATIONS = 0x00000080u, /* Reserved for shapers' internal use. */ HB_BUFFER_SCRATCH_FLAG_SHAPER0 = 0x01000000u, @@ -90,7 +91,6 @@ struct hb_buffer_t hb_segment_properties_t props; /* Script, language, direction */ bool successful; /* Allocations successful */ - bool shaping_failed; /* Shaping failure */ bool have_output; /* Whether we have an output buffer going on */ bool have_positions; /* Whether we have positions */ @@ -110,6 +110,7 @@ struct hb_buffer_t hb_codepoint_t context[2][CONTEXT_LENGTH]; unsigned int context_len[2]; + hb_set_digest_t digest; /* Manually updated sometimes */ /* * Managed by enter / leave @@ -200,6 +201,12 @@ struct hb_buffer_t void collect_codepoints (set_t &d) const { d.clear (); d.add_array (&info[0].codepoint, len, sizeof (info[0])); } + void update_digest () + { + digest = hb_set_digest_t (); + collect_codepoints (digest); + } + HB_INTERNAL void similar (const hb_buffer_t &src); HB_INTERNAL void reset (); HB_INTERNAL void clear (); @@ -346,7 +353,7 @@ struct hb_buffer_t { if (out_info != info || out_len != idx) { - if (unlikely (!make_room_for (1, 1))) return false; + if (unlikely (!ensure (out_len + 1))) return false; out_info[out_len] = info[idx]; } out_len++; @@ -363,7 +370,7 @@ struct hb_buffer_t { if (out_info != info || out_len != idx) { - if (unlikely (!make_room_for (n, n))) return false; + if (unlikely (!ensure (out_len + n))) return false; memmove (out_info + out_len, info + idx, n * sizeof (out_info[0])); } out_len += n; @@ -404,22 +411,12 @@ struct hb_buffer_t /* Adds glyph flags in mask to infos with clusters between start and end. * The start index will be from out-buffer if from_out_buffer is true. * If interior is true, then the cluster having the minimum value is skipped. */ - void _set_glyph_flags (hb_mask_t mask, - unsigned start = 0, - unsigned end = (unsigned) -1, - bool interior = false, - bool from_out_buffer = false) + void _set_glyph_flags_impl (hb_mask_t mask, + unsigned start, + unsigned end, + bool interior, + bool from_out_buffer) { - end = hb_min (end, len); - - if (unlikely (end - start > 255)) - return; - - if (interior && !from_out_buffer && end - start < 2) - return; - - scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS; - if (!from_out_buffer || !have_output) { if (!interior) @@ -456,6 +453,25 @@ struct hb_buffer_t } } + HB_ALWAYS_INLINE + void _set_glyph_flags (hb_mask_t mask, + unsigned start = 0, + unsigned end = (unsigned) -1, + bool interior = false, + bool from_out_buffer = false) + { + if (unlikely (end != (unsigned) -1 && end - start > 255)) + return; + + end = hb_min (end, len); + + if (interior && !from_out_buffer && end - start < 2) + return; + + _set_glyph_flags_impl (mask, start, end, interior, from_out_buffer); + } + + void unsafe_to_break (unsigned int start = 0, unsigned int end = -1) { _set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK | HB_GLYPH_FLAG_UNSAFE_TO_CONCAT, @@ -606,6 +622,10 @@ struct hb_buffer_t if (unlikely (start == end)) return; + max_ops -= end - start; + if (unlikely (max_ops < 0)) + successful = false; + unsigned cluster_first = infos[start].cluster; unsigned cluster_last = infos[end - 1].cluster; @@ -614,10 +634,7 @@ struct hb_buffer_t { for (unsigned int i = start; i < end; i++) if (cluster != infos[i].cluster) - { - scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS; infos[i].mask |= mask; - } return; } @@ -626,18 +643,12 @@ struct hb_buffer_t if (cluster == cluster_first) { for (unsigned int i = end; start < i && infos[i - 1].cluster != cluster_first; i--) - { - scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS; infos[i - 1].mask |= mask; - } } else /* cluster == cluster_last */ { for (unsigned int i = start; i < end && infos[i].cluster != cluster_last; i++) - { - scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS; infos[i].mask |= mask; - } } } unsigned diff --git a/src/java.desktop/share/native/libharfbuzz/hb-cache.hh b/src/java.desktop/share/native/libharfbuzz/hb-cache.hh index 7d09ca89d7f..3609ccecc71 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-cache.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-cache.hh @@ -64,17 +64,23 @@ template , - hb_atomic_t>::type, - typename std::conditional::type + typename std::conditional, + typename std::conditional, + hb_atomic_t>::type>::type, + typename std::conditional::type>::type >::type; static_assert ((key_bits >= cache_bits), ""); static_assert ((key_bits + value_bits <= cache_bits + 8 * sizeof (item_t)), ""); + static constexpr unsigned MAX_VALUE = (1u << value_bits) - 1; + hb_cache_t () { clear (); } void clear () @@ -83,25 +89,32 @@ struct hb_cache_t v = -1; } + HB_HOT bool get (unsigned int key, unsigned int *value) const { unsigned int k = key & ((1u<> value_bits) != (key >> cache_bits)) return false; *value = v & ((1u<> key_bits) || (value >> value_bits))) - return false; /* Overflows */ + return; /* Overflows */ + set_unchecked (key, value); + } + + HB_HOT + void set_unchecked (unsigned int key, unsigned int value) + { unsigned int k = key & ((1u<>cache_bits)< cff2_cs_interp_env_t (const hb_ubytes_t &str, ACC &acc, unsigned int fd, const int *coords_=nullptr, unsigned int num_coords_=0) : SUPER (str, acc.globalSubrs, acc.privateDicts[fd].localSubrs), - cached_scalars_vector (&acc.cached_scalars_vector) + region_count (0), cached_scalars_vector (&acc.cached_scalars_vector) { coords = coords_; num_coords = num_coords_; varStore = acc.varStore; - do_blend = num_coords && coords && varStore->size; + do_blend = num_coords && varStore->size; set_ivs (acc.privateDicts[fd].ivs); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-common.cc b/src/java.desktop/share/native/libharfbuzz/hb-common.cc index 5c8546a378c..9eeae358a75 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-common.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-common.cc @@ -40,43 +40,6 @@ **/ -/* hb_options_t */ - -hb_atomic_t _hb_options; - -void -_hb_options_init () -{ - hb_options_union_t u; - u.i = 0; - u.opts.initialized = true; - - const char *c = getenv ("HB_OPTIONS"); - if (c) - { - while (*c) - { - const char *p = strchr (c, ':'); - if (!p) - p = c + strlen (c); - -#define OPTION(name, symbol) \ - if (0 == strncmp (c, name, p - c) && strlen (name) == static_cast(p - c)) do { u.opts.symbol = true; } while (0) - - OPTION ("uniscribe-bug-compatible", uniscribe_bug_compatible); - -#undef OPTION - - c = *p ? p + 1 : p; - } - - } - - /* This is idempotent and threadsafe. */ - _hb_options = u.i; -} - - /* hb_tag_t */ /** @@ -545,8 +508,11 @@ hb_script_to_iso15924_tag (hb_script_t script) * Fetches the #hb_direction_t of a script when it is * set horizontally. All right-to-left scripts will return * #HB_DIRECTION_RTL. All left-to-right scripts will return - * #HB_DIRECTION_LTR. Scripts that can be written either - * horizontally or vertically will return #HB_DIRECTION_INVALID. + * #HB_DIRECTION_LTR. + * + * Scripts that can be written either right-to-left or + * left-to-right will return #HB_DIRECTION_INVALID. + * * Unknown scripts will return #HB_DIRECTION_LTR. * * Return value: The horizontal #hb_direction_t of @script @@ -628,6 +594,9 @@ hb_script_get_horizontal_direction (hb_script_t script) /* Unicode-16.0 additions */ case HB_SCRIPT_GARAY: + /* Unicode-17.0 additions */ + case HB_SCRIPT_SIDETIC: + return HB_DIRECTION_RTL; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-config.hh b/src/java.desktop/share/native/libharfbuzz/hb-config.hh index 3956690da35..c522eeea2ea 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-config.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-config.hh @@ -38,7 +38,6 @@ #ifndef HB_EXPERIMENTAL_API #define HB_NO_BEYOND_64K #define HB_NO_CUBIC_GLYF -#define HB_NO_VAR_COMPOSITES #endif #ifdef HB_TINY @@ -91,7 +90,10 @@ #ifdef HB_MINI #define HB_NO_AAT #define HB_NO_LEGACY -#define HB_NO_BORING_EXPANSION +#define HB_NO_BEYOND_64K +#define HB_NO_CUBIC_GLYF +#define HB_NO_VAR_COMPOSITES +#define HB_NO_VAR_HVF #endif #ifdef __OPTIMIZE_SIZE__ @@ -109,12 +111,6 @@ /* Closure of options. */ -#ifdef HB_NO_BORING_EXPANSION -#define HB_NO_BEYOND_64K -#define HB_NO_CUBIC_GLYF -#define HB_NO_VAR_COMPOSITES -#endif - #ifdef HB_NO_VAR #define HB_NO_VAR_COMPOSITES #endif @@ -149,10 +145,6 @@ #define HB_NO_PAINT #endif -#ifdef HB_NO_GETENV -#define HB_NO_UNISCRIBE_BUG_COMPATIBLE -#endif - #ifdef HB_NO_LEGACY #define HB_NO_CMAP_LEGACY_SUBTABLES #define HB_NO_FALLBACK_SHAPE diff --git a/src/java.desktop/share/native/libharfbuzz/hb-debug.hh b/src/java.desktop/share/native/libharfbuzz/hb-debug.hh index 1e9a18b9326..87d30d9ded1 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-debug.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-debug.hh @@ -37,48 +37,6 @@ #endif -/* - * Global runtime options. - */ - -struct hb_options_t -{ - bool unused : 1; /* In-case sign bit is here. */ - bool initialized : 1; - bool uniscribe_bug_compatible : 1; -}; - -union hb_options_union_t { - unsigned i; - hb_options_t opts; -}; -static_assert ((sizeof (hb_atomic_t) >= sizeof (hb_options_union_t)), ""); - -HB_INTERNAL void -_hb_options_init (); - -extern HB_INTERNAL hb_atomic_t _hb_options; - -static inline hb_options_t -hb_options () -{ -#ifdef HB_NO_GETENV - return hb_options_t (); -#endif - /* Make a local copy, so we can access bitfield threadsafely. */ - hb_options_union_t u; - u.i = _hb_options; - - if (unlikely (!u.i)) - { - _hb_options_init (); - u.i = _hb_options; - } - - return u.opts; -} - - /* * Debug output (needs enabling at compile time.) */ @@ -394,6 +352,10 @@ struct hb_no_trace_t { #define HB_DEBUG_WASM (HB_DEBUG+0) #endif +#ifndef HB_DEBUG_KBTS +#define HB_DEBUG_KBTS (HB_DEBUG+0) +#endif + /* * With tracing. */ @@ -484,7 +446,7 @@ struct hb_no_trace_t { #ifndef HB_BUFFER_MESSAGE_MORE -#define HB_BUFFER_MESSAGE_MORE (HB_DEBUG+1) +#define HB_BUFFER_MESSAGE_MORE (HB_DEBUG+0) #endif diff --git a/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h b/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h index 927563c4c40..a87a53d0e30 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h @@ -287,7 +287,7 @@ typedef void (*hb_font_get_glyph_shape_func_t) (hb_font_t *font, void *font_data * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * * Since: 7.0.0 - * XDeprecated: REPLACEME: Use hb_font_draw_glyph_func_or_fail_t instead. + * Deprecated: 11.2.0: Use hb_font_draw_glyph_func_or_fail_t instead. **/ typedef void (*hb_font_draw_glyph_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t glyph, @@ -308,7 +308,7 @@ typedef void (*hb_font_draw_glyph_func_t) (hb_font_t *font, void *font_data, * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * * Since: 7.0.0 - * XDeprecated: REPLACEME: Use hb_font_paint_glyph_or_fail_func_t instead. + * Deprecated: 11.2.0: Use hb_font_paint_glyph_or_fail_func_t instead. */ typedef hb_bool_t (*hb_font_paint_glyph_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t glyph, @@ -346,7 +346,7 @@ hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs, * Sets the implementation function for #hb_font_draw_glyph_func_t. * * Since: 7.0.0 - * XDeprecated: REPLACEME: Use hb_font_funcs_set_draw_glyph_or_fail_func instead. + * Deprecated: 11.2.0: Use hb_font_funcs_set_draw_glyph_or_fail_func instead. **/ HB_DEPRECATED_FOR (hb_font_funcs_set_draw_glyph_or_fail_func) HB_EXTERN void @@ -364,7 +364,7 @@ hb_font_funcs_set_draw_glyph_func (hb_font_funcs_t *ffuncs, * Sets the implementation function for #hb_font_paint_glyph_func_t. * * Since: 7.0.0 - * XDeprecated: REPLACEME: Use hb_font_funcs_set_paint_glyph_or_fail_func() instead. + * Deprecated: 11.2.0: Use hb_font_funcs_set_paint_glyph_or_fail_func() instead. */ HB_DEPRECATED_FOR (hb_font_funcs_set_paint_glyph_or_fail_func) HB_EXTERN void diff --git a/src/java.desktop/share/native/libharfbuzz/hb-draw.cc b/src/java.desktop/share/native/libharfbuzz/hb-draw.cc index 8764ffe7129..c243d12f7ae 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-draw.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-draw.cc @@ -63,14 +63,14 @@ hb_draw_quadratic_to_nil (hb_draw_funcs_t *dfuncs, void *draw_data, float to_x, float to_y, void *user_data HB_UNUSED) { -#define HB_ONE_THIRD 0.33333333f +#define HB_TWO_THIRD 0.66666666666666666666666667f dfuncs->emit_cubic_to (draw_data, *st, - (st->current_x + 2.f * control_x) * HB_ONE_THIRD, - (st->current_y + 2.f * control_y) * HB_ONE_THIRD, - (to_x + 2.f * control_x) * HB_ONE_THIRD, - (to_y + 2.f * control_y) * HB_ONE_THIRD, + st->current_x + (control_x - st->current_x) * HB_TWO_THIRD, + st->current_y + (control_y - st->current_y) * HB_TWO_THIRD, + to_x + (control_x - to_x) * HB_TWO_THIRD, + to_y + (control_y - to_y) * HB_TWO_THIRD, to_x, to_y); -#undef HB_ONE_THIRD +#undef HB_TWO_THIRD } static void @@ -467,7 +467,7 @@ hb_draw_extents_move_to (hb_draw_funcs_t *dfuncs HB_UNUSED, float to_x, float to_y, void *user_data HB_UNUSED) { - hb_extents_t *extents = (hb_extents_t *) data; + hb_extents_t<> *extents = (hb_extents_t<> *) data; extents->add_point (to_x, to_y); } @@ -479,7 +479,7 @@ hb_draw_extents_line_to (hb_draw_funcs_t *dfuncs HB_UNUSED, float to_x, float to_y, void *user_data HB_UNUSED) { - hb_extents_t *extents = (hb_extents_t *) data; + hb_extents_t<> *extents = (hb_extents_t<> *) data; extents->add_point (to_x, to_y); } @@ -492,7 +492,7 @@ hb_draw_extents_quadratic_to (hb_draw_funcs_t *dfuncs HB_UNUSED, float to_x, float to_y, void *user_data HB_UNUSED) { - hb_extents_t *extents = (hb_extents_t *) data; + hb_extents_t<> *extents = (hb_extents_t<> *) data; extents->add_point (control_x, control_y); extents->add_point (to_x, to_y); @@ -507,7 +507,7 @@ hb_draw_extents_cubic_to (hb_draw_funcs_t *dfuncs HB_UNUSED, float to_x, float to_y, void *user_data HB_UNUSED) { - hb_extents_t *extents = (hb_extents_t *) data; + hb_extents_t<> *extents = (hb_extents_t<> *) data; extents->add_point (control1_x, control1_y); extents->add_point (control2_x, control2_y); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-face-builder.cc b/src/java.desktop/share/native/libharfbuzz/hb-face-builder.cc index 6b7e1913024..c1feaac6280 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-face-builder.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-face-builder.cc @@ -169,8 +169,7 @@ _hb_face_builder_get_table_tags (const hb_face_t *face HB_UNUSED, if (unlikely (start_offset >= population)) { - if (table_count) - *table_count = 0; + *table_count = 0; return population; } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-face.cc b/src/java.desktop/share/native/libharfbuzz/hb-face.cc index 9d59d7c9468..a0f497eea7f 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-face.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-face.cc @@ -84,8 +84,7 @@ hb_face_count (hb_blob_t *blob) hb_sanitize_context_t c (blob); - const char *start = hb_blob_get_data (blob, nullptr); - auto *ot = reinterpret_cast (const_cast (start)); + auto *ot = blob->as (); if (unlikely (!ot->sanitize (&c))) return 0; @@ -329,7 +328,7 @@ hb_face_create_from_file_or_fail (const char *file_name, return face; } -static struct supported_face_loaders_t { +static const struct supported_face_loaders_t { char name[16]; hb_face_t * (*from_file) (const char *font_file, unsigned face_index); hb_face_t * (*from_blob) (hb_blob_t *blob, unsigned face_index); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-font.cc b/src/java.desktop/share/native/libharfbuzz/hb-font.cc index 849855e2c22..6c636e23567 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-font.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-font.cc @@ -246,7 +246,6 @@ hb_font_get_glyph_v_advance_nil (hb_font_t *font, hb_codepoint_t glyph HB_UNUSED, void *user_data HB_UNUSED) { - /* TODO use font_extents.ascender+descender */ return -font->y_scale; } @@ -352,6 +351,10 @@ hb_font_get_glyph_h_origin_default (hb_font_t *font, hb_position_t *y, void *user_data HB_UNUSED) { + if (font->has_glyph_h_origins_func_set ()) + { + return font->get_glyph_h_origins (1, &glyph, 0, x, 0, y, 0, false); + } hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y); if (ret) font->parent_scale_position (x, y); @@ -366,7 +369,6 @@ hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED, hb_position_t *y, void *user_data HB_UNUSED) { - *x = *y = 0; return false; } @@ -378,12 +380,100 @@ hb_font_get_glyph_v_origin_default (hb_font_t *font, hb_position_t *y, void *user_data HB_UNUSED) { + if (font->has_glyph_v_origins_func_set ()) + { + return font->get_glyph_v_origins (1, &glyph, 0, x, 0, y, 0, false); + } hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y); if (ret) font->parent_scale_position (x, y); return ret; } +#define hb_font_get_glyph_h_origins_nil hb_font_get_glyph_h_origins_default + +static hb_bool_t +hb_font_get_glyph_h_origins_default (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + unsigned int count, + const hb_codepoint_t *first_glyph HB_UNUSED, + unsigned glyph_stride HB_UNUSED, + hb_position_t *first_x, + unsigned x_stride, + hb_position_t *first_y, + unsigned y_stride, + void *user_data HB_UNUSED) +{ + if (font->has_glyph_h_origin_func_set ()) + { + for (unsigned int i = 0; i < count; i++) + { + font->get_glyph_h_origin (*first_glyph, first_x, first_y, false); + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_x = &StructAtOffsetUnaligned (first_x, x_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); + } + return true; + } + + hb_bool_t ret = font->parent->get_glyph_h_origins (count, + first_glyph, glyph_stride, + first_x, x_stride, + first_y, y_stride); + if (ret) + { + for (unsigned i = 0; i < count; i++) + { + font->parent_scale_position (first_x, first_y); + first_x = &StructAtOffsetUnaligned (first_x, x_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); + } + } + return ret; +} + +#define hb_font_get_glyph_v_origins_nil hb_font_get_glyph_v_origins_default + +static hb_bool_t +hb_font_get_glyph_v_origins_default (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + unsigned int count, + const hb_codepoint_t *first_glyph HB_UNUSED, + unsigned glyph_stride HB_UNUSED, + hb_position_t *first_x, + unsigned x_stride, + hb_position_t *first_y, + unsigned y_stride, + void *user_data HB_UNUSED) +{ + if (font->has_glyph_v_origin_func_set ()) + { + for (unsigned int i = 0; i < count; i++) + { + font->get_glyph_v_origin (*first_glyph, first_x, first_y, false); + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_x = &StructAtOffsetUnaligned (first_x, x_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); + } + return true; + } + + hb_bool_t ret = font->parent->get_glyph_v_origins (count, + first_glyph, glyph_stride, + first_x, x_stride, + first_y, y_stride); + if (ret) + { + for (unsigned i = 0; i < count; i++) + { + font->parent_scale_position (first_x, first_y); + first_x = &StructAtOffsetUnaligned (first_x, x_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); + } + } + return ret; +} + static hb_position_t hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED, @@ -1256,6 +1346,77 @@ hb_font_get_glyph_v_origin (hb_font_t *font, return font->get_glyph_v_origin (glyph, x, y); } +/** + * hb_font_get_glyph_h_origins: + * @font: #hb_font_t to work upon + * @count: The number of glyph IDs in the sequence queried + * @first_glyph: The first glyph ID to query + * @glyph_stride: The stride between successive glyph IDs + * @first_x: (out): The first X coordinate of the origin retrieved + * @x_stride: The stride between successive X coordinates + * @first_y: (out): The first Y coordinate of the origin retrieved + * @y_stride: The stride between successive Y coordinates + * + * Fetches the (X,Y) coordinates of the origin for requested glyph IDs + * in the specified font, for horizontal text segments. + * + * Return value: `true` if data found, `false` otherwise + * + * Since: 11.3.0 + **/ +hb_bool_t +hb_font_get_glyph_h_origins (hb_font_t *font, + unsigned int count, + const hb_codepoint_t *first_glyph, + unsigned int glyph_stride, + hb_position_t *first_x, + unsigned int x_stride, + hb_position_t *first_y, + unsigned int y_stride) + +{ + return font->get_glyph_h_origins (count, + first_glyph, glyph_stride, + first_x, x_stride, + first_y, y_stride); +} + +/** + * hb_font_get_glyph_v_origins: + * @font: #hb_font_t to work upon + * @count: The number of glyph IDs in the sequence queried + * @first_glyph: The first glyph ID to query + * @glyph_stride: The stride between successive glyph IDs + * @first_x: (out): The first X coordinate of the origin retrieved + * @x_stride: The stride between successive X coordinates + * @first_y: (out): The first Y coordinate of the origin retrieved + * @y_stride: The stride between successive Y coordinates + * + * Fetches the (X,Y) coordinates of the origin for requested glyph IDs + * in the specified font, for vertical text segments. + * + * Return value: `true` if data found, `false` otherwise + * + * Since: 11.3.0 + **/ +hb_bool_t +hb_font_get_glyph_v_origins (hb_font_t *font, + unsigned int count, + const hb_codepoint_t *first_glyph, + unsigned int glyph_stride, + hb_position_t *first_x, + unsigned int x_stride, + hb_position_t *first_y, + unsigned int y_stride) + +{ + return font->get_glyph_v_origins (count, + first_glyph, glyph_stride, + first_x, x_stride, + first_y, y_stride); +} + + /** * hb_font_get_glyph_h_kerning: * @font: #hb_font_t to work upon @@ -1443,7 +1604,7 @@ hb_font_get_glyph_shape (hb_font_t *font, * * Return value: `true` if glyph was drawn, `false` otherwise * - * XSince: REPLACEME + * Since: 11.2.0 **/ hb_bool_t hb_font_draw_glyph_or_fail (hb_font_t *font, @@ -1480,7 +1641,7 @@ hb_font_draw_glyph_or_fail (hb_font_t *font, * * Return value: `true` if glyph was painted, `false` otherwise * - * XSince: REPLACEME + * Since: 11.2.0 */ hb_bool_t hb_font_paint_glyph_or_fail (hb_font_t *font, @@ -1883,6 +2044,7 @@ DEFINE_NULL_INSTANCE (hb_font_t) = 1000, /* x_scale */ 1000, /* y_scale */ + false, /* is_synthetic */ 0.f, /* x_embolden */ 0.f, /* y_embolden */ true, /* embolden_in_place */ @@ -1900,6 +2062,7 @@ DEFINE_NULL_INSTANCE (hb_font_t) = 0, /* ptem */ HB_FONT_NO_VAR_NAMED_INSTANCE, /* instance_index */ + false, /* has_nonzero_coords */ 0, /* num_coords */ nullptr, /* coords */ nullptr, /* design_coords */ @@ -1960,8 +2123,14 @@ hb_font_create (hb_face_t *face) hb_font_set_funcs_using (font, nullptr); #ifndef HB_NO_VAR - if (face && face->index >> 16) - hb_font_set_var_named_instance (font, (face->index >> 16) - 1); + // Initialize variations. + if (likely (face)) + { + if (face->index >> 16) + hb_font_set_var_named_instance (font, (face->index >> 16) - 1); + else + hb_font_set_variations (font, nullptr, 0); + } #endif return font; @@ -1979,6 +2148,7 @@ _hb_font_adopt_var_coords (hb_font_t *font, font->coords = coords; font->design_coords = design_coords; font->num_coords = coords_length; + font->has_nonzero_coords = hb_any (hb_array (coords, coords_length)); font->changed (); font->serial_coords = font->serial; @@ -2393,7 +2563,7 @@ hb_font_set_funcs_data (hb_font_t *font, font->changed (); } -static struct supported_font_funcs_t { +static const struct supported_font_funcs_t { char name[16]; void (*func) (hb_font_t *); } supported_font_funcs[] = @@ -2450,6 +2620,9 @@ hb_bool_t hb_font_set_funcs_using (hb_font_t *font, const char *name) { + if (unlikely (hb_object_is_immutable (font))) + return false; + bool retry = false; if (!name || !*name) @@ -2704,12 +2877,12 @@ hb_font_get_ptem (hb_font_t *font) * * Return value: `true` if the font is synthetic, `false` otherwise. * - * XSince: REPLACEME + * Since: 11.2.0 */ hb_bool_t hb_font_is_synthetic (hb_font_t *font) { - return font->is_synthetic (); + return font->is_synthetic; } /** @@ -2858,12 +3031,6 @@ hb_font_set_variations (hb_font_t *font, if (hb_object_is_immutable (font)) return; - if (!variations_length && font->instance_index == HB_FONT_NO_VAR_NAMED_INSTANCE) - { - hb_font_set_var_coords_normalized (font, nullptr, 0); - return; - } - const OT::fvar &fvar = *font->face->table.fvar; auto axes = fvar.get_axes (); const unsigned coords_length = axes.length; @@ -2970,7 +3137,6 @@ hb_font_set_variation (hb_font_t *font, hb_ot_var_normalize_coords (font->face, coords_length, design_coords, normalized); _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length); - } /** @@ -2991,11 +3157,16 @@ hb_font_set_variation (hb_font_t *font, void hb_font_set_var_coords_design (hb_font_t *font, const float *coords, - unsigned int coords_length) + unsigned int input_coords_length) { if (hb_object_is_immutable (font)) return; + const OT::fvar &fvar = *font->face->table.fvar; + auto axes = fvar.get_axes (); + const unsigned coords_length = axes.length; + + input_coords_length = hb_min (input_coords_length, coords_length); int *normalized = coords_length ? (int *) hb_calloc (coords_length, sizeof (int)) : nullptr; float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr; @@ -3006,8 +3177,11 @@ hb_font_set_var_coords_design (hb_font_t *font, return; } - if (coords_length) - hb_memcpy (design_coords, coords, coords_length * sizeof (font->design_coords[0])); + if (input_coords_length) + hb_memcpy (design_coords, coords, input_coords_length * sizeof (font->design_coords[0])); + // Fill in the rest with default values + for (unsigned int i = input_coords_length; i < coords_length; i++) + design_coords[i] = axes[i].get_default (); hb_ot_var_normalize_coords (font->face, coords_length, coords, normalized); _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length); @@ -3072,34 +3246,31 @@ hb_font_get_var_named_instance (hb_font_t *font) void hb_font_set_var_coords_normalized (hb_font_t *font, const int *coords, /* 2.14 normalized */ - unsigned int coords_length) + unsigned int input_coords_length) { if (hb_object_is_immutable (font)) return; + const OT::fvar &fvar = *font->face->table.fvar; + auto axes = fvar.get_axes (); + unsigned coords_length = axes.length; + + input_coords_length = hb_min (input_coords_length, coords_length); int *copy = coords_length ? (int *) hb_calloc (coords_length, sizeof (coords[0])) : nullptr; - int *unmapped = coords_length ? (int *) hb_calloc (coords_length, sizeof (coords[0])) : nullptr; float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (design_coords[0])) : nullptr; - if (unlikely (coords_length && !(copy && unmapped && design_coords))) + if (unlikely (coords_length && !(copy && design_coords))) { hb_free (copy); - hb_free (unmapped); hb_free (design_coords); return; } - if (coords_length) - { - hb_memcpy (copy, coords, coords_length * sizeof (coords[0])); - hb_memcpy (unmapped, coords, coords_length * sizeof (coords[0])); - } + if (input_coords_length) + hb_memcpy (copy, coords, input_coords_length * sizeof (coords[0])); - /* Best effort design coords simulation */ - font->face->table.avar->unmap_coords (unmapped, coords_length); for (unsigned int i = 0; i < coords_length; ++i) - design_coords[i] = font->face->table.fvar->unnormalize_axis_value (i, unmapped[i]); - hb_free (unmapped); + design_coords[i] = NAN; _hb_font_adopt_var_coords (font, copy, design_coords, coords_length); } @@ -3112,8 +3283,8 @@ hb_font_set_var_coords_normalized (hb_font_t *font, * Fetches the list of normalized variation coordinates currently * set on a font. * - * Note that this returned array may only contain values for some - * (or none) of the axes; omitted axes effectively have zero values. + * Note that if no variation coordinates are set, this function may + * return %NULL. * * Return value is valid as long as variation coordinates of the font * are not modified. @@ -3140,9 +3311,12 @@ hb_font_get_var_coords_normalized (hb_font_t *font, * Fetches the list of variation coordinates (in design-space units) currently * set on a font. * - * Note that this returned array may only contain values for some - * (or none) of the axes; omitted axes effectively have their default - * values. + * Note that if no variation coordinates are set, this function may + * return %NULL. + * + * If variations have been set on the font using normalized coordinates + * (i.e. via hb_font_set_var_coords_normalized()), the design coordinates will + * have NaN (Not a Number) values. * * Return value is valid as long as variation coordinates of the font * are not modified. diff --git a/src/java.desktop/share/native/libharfbuzz/hb-font.h b/src/java.desktop/share/native/libharfbuzz/hb-font.h index 4e267ba6a80..2d06b659278 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-font.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-font.h @@ -97,7 +97,7 @@ hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs); * @descender: The depth of typographic descenders. * @line_gap: The suggested line-spacing gap. * - * Font-wide extent values, measured in font units. + * Font-wide extent values, measured in scaled units. * * Note that typically @ascender is positive and @descender * negative, in coordinate systems that grow up. @@ -332,7 +332,7 @@ typedef hb_font_get_glyph_advances_func_t hb_font_get_glyph_v_advances_func_t; * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * - * This method should retrieve the (X,Y) coordinates (in font units) of the + * This method should retrieve the (X,Y) coordinates (in scaled units) of the * origin for a glyph. Each coordinate must be returned in an #hb_position_t * output parameter. * @@ -349,7 +349,7 @@ typedef hb_bool_t (*hb_font_get_glyph_origin_func_t) (hb_font_t *font, void *fon * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * - * This method should retrieve the (X,Y) coordinates (in font units) of the + * This method should retrieve the (X,Y) coordinates (in scaled units) of the * origin for a glyph, for horizontal-direction text segments. Each * coordinate must be returned in an #hb_position_t output parameter. * @@ -361,13 +361,72 @@ typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_h_origin_func_t; * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * - * This method should retrieve the (X,Y) coordinates (in font units) of the + * This method should retrieve the (X,Y) coordinates (in scaled units) of the * origin for a glyph, for vertical-direction text segments. Each coordinate * must be returned in an #hb_position_t output parameter. * **/ typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_v_origin_func_t; +/** + * hb_font_get_glyph_origins_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @first_glyph: The first glyph ID to query + * @count: number of glyphs to query + * @glyph_stride: The stride between successive glyph IDs + * @first_x: (out): The first origin X coordinate retrieved + * @x_stride: The stride between successive origin X coordinates + * @first_y: (out): The first origin Y coordinate retrieved + * @y_stride: The stride between successive origin Y coordinates + * @user_data: User data pointer passed by the caller + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the (X,Y) coordinates (in scaled units) of the + * origin for each requested glyph. Each coordinate value must be returned in + * an #hb_position_t in the two output parameters. + * + * Return value: `true` if data found, `false` otherwise + * + * Since: 11.3.0 + **/ +typedef hb_bool_t (*hb_font_get_glyph_origins_func_t) (hb_font_t *font, void *font_data, + unsigned int count, + const hb_codepoint_t *first_glyph, + unsigned glyph_stride, + hb_position_t *first_x, + unsigned x_stride, + hb_position_t *first_y, + unsigned y_stride, + void *user_data); + +/** + * hb_font_get_glyph_h_origins_func_t: + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the (X,Y) coordinates (in scaled units) of the + * origin for requested glyph, for horizontal-direction text segments. Each + * coordinate must be returned in a the x/y #hb_position_t output parameters. + * + * Since: 11.3.0 + **/ +typedef hb_font_get_glyph_origins_func_t hb_font_get_glyph_h_origins_func_t; + +/** + * hb_font_get_glyph_v_origins_func_t: + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the (X,Y) coordinates (in scaled units) of the + * origin for requested glyph, for vertical-direction text segments. Each + * coordinate must be returned in a the x/y #hb_position_t output parameters. + * + * Since: 11.3.0 + **/ +typedef hb_font_get_glyph_origins_func_t hb_font_get_glyph_v_origins_func_t; + /** * hb_font_get_glyph_kerning_func_t: * @font: #hb_font_t to work upon @@ -428,7 +487,7 @@ typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *fo * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * - * This method should retrieve the (X,Y) coordinates (in font units) for a + * This method should retrieve the (X,Y) coordinates (in scaled units) for a * specified contour point in a glyph. Each coordinate must be returned as * an #hb_position_t output parameter. * @@ -498,7 +557,7 @@ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void * * * Return value: `true` if glyph was drawn, `false` otherwise * - * XSince: REPLACEME + * Since: 11.2.0 **/ typedef hb_bool_t (*hb_font_draw_glyph_or_fail_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t glyph, @@ -520,7 +579,7 @@ typedef hb_bool_t (*hb_font_draw_glyph_or_fail_func_t) (hb_font_t *font, void *f * * Return value: `true` if glyph was painted, `false` otherwise * - * XSince: REPLACEME + * Since: 11.2.0 */ typedef hb_bool_t (*hb_font_paint_glyph_or_fail_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t glyph, @@ -707,6 +766,38 @@ hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs, hb_font_get_glyph_v_origin_func_t func, void *user_data, hb_destroy_func_t destroy); +/** + * hb_font_funcs_set_glyph_h_origins_func: + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore + * + * Sets the implementation function for #hb_font_get_glyph_h_origins_func_t. + * + * Since: 11.3.0 + **/ +HB_EXTERN void +hb_font_funcs_set_glyph_h_origins_func (hb_font_funcs_t *ffuncs, + hb_font_get_glyph_h_origins_func_t func, + void *user_data, hb_destroy_func_t destroy); + +/** + * hb_font_funcs_set_glyph_v_origins_func: + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore + * + * Sets the implementation function for #hb_font_get_glyph_v_origins_func_t. + * + * Since: 11.3.0 + **/ +HB_EXTERN void +hb_font_funcs_set_glyph_v_origins_func (hb_font_funcs_t *ffuncs, + hb_font_get_glyph_v_origins_func_t func, + void *user_data, hb_destroy_func_t destroy); + /** * hb_font_funcs_set_glyph_h_kerning_func: * @ffuncs: A font-function structure @@ -796,7 +887,7 @@ hb_font_funcs_set_glyph_from_name_func (hb_font_funcs_t *ffuncs, * * Sets the implementation function for #hb_font_draw_glyph_or_fail_func_t. * - * XSince: REPLACEME + * Since: 11.2.0 **/ HB_EXTERN void hb_font_funcs_set_draw_glyph_or_fail_func (hb_font_funcs_t *ffuncs, @@ -812,7 +903,7 @@ hb_font_funcs_set_draw_glyph_or_fail_func (hb_font_funcs_t *ffuncs, * * Sets the implementation function for #hb_font_paint_glyph_or_fail_func_t. * - * XSince: REPLACEME + * Since: 11.2.0 */ HB_EXTERN void hb_font_funcs_set_paint_glyph_or_fail_func (hb_font_funcs_t *ffuncs, @@ -876,6 +967,26 @@ hb_font_get_glyph_v_origin (hb_font_t *font, hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y); +HB_EXTERN hb_bool_t +hb_font_get_glyph_h_origins (hb_font_t *font, + unsigned int count, + const hb_codepoint_t *first_glyph, + unsigned glyph_stride, + hb_position_t *first_x, + unsigned x_stride, + hb_position_t *first_y, + unsigned y_stride); + +HB_EXTERN hb_bool_t +hb_font_get_glyph_v_origins (hb_font_t *font, + unsigned int count, + const hb_codepoint_t *first_glyph, + unsigned glyph_stride, + hb_position_t *first_x, + unsigned x_stride, + hb_position_t *first_y, + unsigned y_stride); + HB_EXTERN hb_position_t hb_font_get_glyph_h_kerning (hb_font_t *font, hb_codepoint_t left_glyph, hb_codepoint_t right_glyph); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-font.hh b/src/java.desktop/share/native/libharfbuzz/hb-font.hh index 69d8d4b09df..9dd54466d7f 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-font.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-font.hh @@ -55,6 +55,8 @@ HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_advances) \ HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_origin) \ HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_origin) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_origins) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_origins) \ HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_kerning) \ HB_IF_NOT_DEPRECATED (HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_kerning)) \ HB_FONT_FUNC_IMPLEMENT (get_,glyph_extents) \ @@ -118,6 +120,8 @@ struct hb_font_t int32_t x_scale; int32_t y_scale; + bool is_synthetic; + float x_embolden; float y_embolden; bool embolden_in_place; @@ -139,6 +143,7 @@ struct hb_font_t /* Font variation coordinates. */ unsigned int instance_index; + bool has_nonzero_coords; unsigned int num_coords; int *coords; float *design_coords; @@ -430,21 +435,127 @@ struct hb_font_t } hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph, - hb_position_t *x, hb_position_t *y) + hb_position_t *x, hb_position_t *y, + bool synthetic = true) { *x = *y = 0; - return klass->get.f.glyph_h_origin (this, user_data, - glyph, x, y, - !klass->user_data ? nullptr : klass->user_data->glyph_h_origin); + bool ret = klass->get.f.glyph_h_origin (this, user_data, + glyph, x, y, + !klass->user_data ? nullptr : klass->user_data->glyph_h_origin); + + if (synthetic && ret) + { + /* Slant is ignored as it does not affect glyph origin */ + + /* Embolden */ + if (!embolden_in_place) + { + *x += x_scale < 0 ? -x_strength : x_strength; + *y += y_scale < 0 ? -y_strength : y_strength; + } + } + + return ret; } hb_bool_t get_glyph_v_origin (hb_codepoint_t glyph, - hb_position_t *x, hb_position_t *y) + hb_position_t *x, hb_position_t *y, + bool synthetic = true) { *x = *y = 0; - return klass->get.f.glyph_v_origin (this, user_data, - glyph, x, y, - !klass->user_data ? nullptr : klass->user_data->glyph_v_origin); + bool ret = klass->get.f.glyph_v_origin (this, user_data, + glyph, x, y, + !klass->user_data ? nullptr : klass->user_data->glyph_v_origin); + + if (synthetic && ret) + { + /* Slant is ignored as it does not affect glyph origin */ + + /* Embolden */ + if (!embolden_in_place) + { + *x += x_scale < 0 ? -x_strength : x_strength; + *y += y_scale < 0 ? -y_strength : y_strength; + } + } + + return ret; + } + + hb_bool_t get_glyph_h_origins (unsigned int count, + const hb_codepoint_t *first_glyph, + unsigned int glyph_stride, + hb_position_t *first_x, + unsigned int x_stride, + hb_position_t *first_y, + unsigned int y_stride, + bool synthetic = true) + + { + bool ret = klass->get.f.glyph_h_origins (this, user_data, + count, + first_glyph, glyph_stride, + first_x, x_stride, first_y, y_stride, + !klass->user_data ? nullptr : klass->user_data->glyph_h_origins); + + if (synthetic && ret) + { + hb_position_t x_shift = x_scale < 0 ? -x_strength : x_strength; + hb_position_t y_shift = y_scale < 0 ? -y_strength : y_strength; + for (unsigned i = 0; i < count; i++) + { + /* Slant is ignored as it does not affect glyph origin */ + + /* Embolden */ + if (!embolden_in_place) + { + *first_x += x_shift; + *first_y += y_shift; + } + first_x = &StructAtOffsetUnaligned (first_x, x_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); + } + } + + return ret; + } + + hb_bool_t get_glyph_v_origins (unsigned int count, + const hb_codepoint_t *first_glyph, + unsigned int glyph_stride, + hb_position_t *first_x, + unsigned int x_stride, + hb_position_t *first_y, + unsigned int y_stride, + bool synthetic = true) + + { + bool ret = klass->get.f.glyph_v_origins (this, user_data, + count, + first_glyph, glyph_stride, + first_x, x_stride, first_y, y_stride, + !klass->user_data ? nullptr : klass->user_data->glyph_v_origins); + + if (synthetic && is_synthetic && ret) + { + hb_position_t x_shift = x_scale < 0 ? -x_strength : x_strength; + hb_position_t y_shift = y_scale < 0 ? -y_strength : y_strength; + for (unsigned i = 0; i < count; i++) + { + /* Slant is ignored as it does not affect glyph origin */ + + /* Embolden */ + if (!embolden_in_place) + { + *first_x += x_shift; + *first_y += y_shift; + } + first_x = &StructAtOffsetUnaligned (first_x, x_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); + } + } + + return ret; } hb_position_t get_glyph_h_kerning (hb_codepoint_t left_glyph, @@ -486,7 +597,7 @@ struct hb_font_t extents, !klass->user_data ? nullptr : klass->user_data->glyph_extents); } - if (!is_synthetic () && + if (!is_synthetic && klass->get.f.glyph_extents (this, user_data, glyph, extents, @@ -496,6 +607,7 @@ struct hb_font_t /* Try getting extents from paint(), then draw(), *then* get_extents() * and apply synthetic settings in the last case. */ +#ifndef HB_NO_PAINT hb_paint_extents_context_t paint_extents; if (paint_glyph_or_fail (glyph, hb_paint_extents_get_funcs (), &paint_extents, @@ -504,14 +616,17 @@ struct hb_font_t *extents = paint_extents.get_extents ().to_glyph_extents (); return true; } +#endif - hb_extents_t draw_extents; +#ifndef HB_NO_DRAW + hb_extents_t<> draw_extents; if (draw_glyph_or_fail (glyph, hb_draw_extents_get_funcs (), &draw_extents)) { *extents = draw_extents.to_glyph_extents (); return true; } +#endif bool ret = klass->get.f.glyph_extents (this, user_data, glyph, @@ -575,6 +690,7 @@ struct hb_font_t hb_draw_funcs_t *draw_funcs, void *draw_data, bool synthetic = true) { +#ifndef HB_NO_DRAW #ifndef HB_NO_OUTLINE bool embolden = x_strength || y_strength; bool slanted = slant_xy; @@ -603,7 +719,13 @@ struct hb_font_t // Slant before embolden; produces nicer results. if (slanted) + { + hb_position_t xo = 0, yo = 0; + get_glyph_h_origin (glyph, &xo, &yo, false); + outline.translate (-xo, -yo); outline.slant (slant_xy); + outline.translate (xo, yo); + } if (embolden) { @@ -618,6 +740,8 @@ struct hb_font_t return true; #endif +#endif + return false; } bool paint_glyph_or_fail (hb_codepoint_t glyph, @@ -626,6 +750,7 @@ struct hb_font_t hb_color_t foreground, bool synthetic = true) { +#ifndef HB_NO_PAINT /* Slant */ if (synthetic && slant_xy) hb_paint_push_transform (paint_funcs, paint_data, @@ -643,6 +768,8 @@ struct hb_font_t hb_paint_pop_transform (paint_funcs, paint_data); return ret; +#endif + return false; } /* A bit higher-level, and with fallback */ @@ -704,6 +831,28 @@ struct hb_font_t get_glyph_v_advances (count, first_glyph, glyph_stride, first_advance, advance_stride); } + void apply_offset (hb_position_t *x, hb_position_t *y, + hb_position_t dx, hb_position_t dy, + signed mult) + { + assert (mult == -1 || mult == +1); + + *x += dx * mult; + *y += dy * mult; + } + void add_offset (hb_position_t *x, hb_position_t *y, + hb_position_t dx, hb_position_t dy) + { + *x += dx; + *y += dy; + } + void subtract_offset (hb_position_t *x, hb_position_t *y, + hb_position_t dx, hb_position_t dy) + { + *x -= dx; + *y -= dy; + } + void guess_v_origin_minus_h_origin (hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y) { @@ -714,6 +863,141 @@ struct hb_font_t *y = extents.ascender; } + void apply_glyph_h_origins_with_fallback (hb_buffer_t *buf, int mult) + { + bool has_ascender = false; + hb_position_t ascender = 0; + + struct { hb_position_t x, y; } origins[32]; + + unsigned int offset = 0; + unsigned int count = buf->len; + while (offset < count) + { + unsigned n = hb_min (count - offset, ARRAY_LENGTH (origins)); + if (!get_glyph_h_origins (n, + &buf->info[offset].codepoint, sizeof (hb_glyph_info_t), + &origins[0].x, sizeof (origins[0]), + &origins[0].y, sizeof (origins[0]))) + { + if (get_glyph_v_origins (n, + &buf->info[offset].codepoint, sizeof (hb_glyph_info_t), + &origins[0].x, sizeof (origins[0]), + &origins[0].y, sizeof (origins[0]))) + { + if (!has_ascender) + { + hb_font_extents_t extents; + get_h_extents_with_fallback (&extents); + ascender = extents.ascender; + has_ascender = true; + } + + /* We got the v_origins, adjust them to h_origins. */ + for (unsigned j = 0; j < n; j++) + { + hb_codepoint_t glyph = buf->info[offset + j].codepoint; + origins[j].x -= get_glyph_h_advance (glyph) / 2; + origins[j].y -= ascender; + } + } + else + { + for (unsigned j = 0; j < n; j++) + { + origins[j].x = 0; + origins[j].y = 0; + } + } + } + + assert (mult == -1 || mult == +1); + if (mult == +1) + for (unsigned j = 0; j < n; j++) + { + hb_glyph_position_t *pos = &buf->pos[offset + j]; + add_offset (&pos->x_offset, &pos->y_offset, + origins[j].x, origins[j].y); + } + else /* mult == -1 */ + for (unsigned j = 0; j < n; j++) + { + hb_glyph_position_t *pos = &buf->pos[offset + j]; + subtract_offset (&pos->x_offset, &pos->y_offset, + origins[j].x, origins[j].y); + } + + offset += n; + } + } + void apply_glyph_v_origins_with_fallback (hb_buffer_t *buf, int mult) + { + bool has_ascender = false; + hb_position_t ascender = 0; + + struct { hb_position_t x, y; } origins[32]; + + unsigned int offset = 0; + unsigned int count = buf->len; + while (offset < count) + { + unsigned n = hb_min (count - offset, ARRAY_LENGTH (origins)); + if (!get_glyph_v_origins (n, + &buf->info[offset].codepoint, sizeof (hb_glyph_info_t), + &origins[0].x, sizeof (origins[0]), + &origins[0].y, sizeof (origins[0]))) + { + if (get_glyph_h_origins (n, + &buf->info[offset].codepoint, sizeof (hb_glyph_info_t), + &origins[0].x, sizeof (origins[0]), + &origins[0].y, sizeof (origins[0]))) + { + if (!has_ascender) + { + hb_font_extents_t extents; + get_h_extents_with_fallback (&extents); + ascender = extents.ascender; + has_ascender = true; + } + + /* We got the h_origins, adjust them to v_origins. */ + for (unsigned j = 0; j < n; j++) + { + hb_codepoint_t glyph = buf->info[offset + j].codepoint; + origins[j].x += get_glyph_h_advance (glyph) / 2; + origins[j].y += ascender; + } + } + else + { + for (unsigned j = 0; j < n; j++) + { + origins[j].x = 0; + origins[j].y = 0; + } + } + } + + assert (mult == -1 || mult == +1); + if (mult == +1) + for (unsigned j = 0; j < n; j++) + { + hb_glyph_position_t *pos = &buf->pos[offset + j]; + add_offset (&pos->x_offset, &pos->y_offset, + origins[j].x, origins[j].y); + } + else /* mult == -1 */ + for (unsigned j = 0; j < n; j++) + { + hb_glyph_position_t *pos = &buf->pos[offset + j]; + subtract_offset (&pos->x_offset, &pos->y_offset, + origins[j].x, origins[j].y); + } + + offset += n; + } + } + void get_glyph_h_origin_with_fallback (hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y) { @@ -722,7 +1006,7 @@ struct hb_font_t { hb_position_t dx, dy; guess_v_origin_minus_h_origin (glyph, &dx, &dy); - *x -= dx; *y -= dy; + subtract_offset (x, y, dx, dy); } } void get_glyph_v_origin_with_fallback (hb_codepoint_t glyph, @@ -733,7 +1017,7 @@ struct hb_font_t { hb_position_t dx, dy; guess_v_origin_minus_h_origin (glyph, &dx, &dy); - *x += dx; *y += dy; + add_offset (x, y, dx, dy); } } @@ -747,68 +1031,38 @@ struct hb_font_t get_glyph_v_origin_with_fallback (glyph, x, y); } - void add_glyph_h_origin (hb_codepoint_t glyph, - hb_position_t *x, hb_position_t *y) + void add_glyph_h_origins (hb_buffer_t *buf) { - hb_position_t origin_x, origin_y; - - get_glyph_h_origin_with_fallback (glyph, &origin_x, &origin_y); - - *x += origin_x; - *y += origin_y; + apply_glyph_h_origins_with_fallback (buf, +1); } - void add_glyph_v_origin (hb_codepoint_t glyph, - hb_position_t *x, hb_position_t *y) + void add_glyph_v_origins (hb_buffer_t *buf) { - hb_position_t origin_x, origin_y; - - get_glyph_v_origin_with_fallback (glyph, &origin_x, &origin_y); - - *x += origin_x; - *y += origin_y; + apply_glyph_v_origins_with_fallback (buf, +1); } void add_glyph_origin_for_direction (hb_codepoint_t glyph, hb_direction_t direction, hb_position_t *x, hb_position_t *y) { hb_position_t origin_x, origin_y; - get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y); - - *x += origin_x; - *y += origin_y; + add_offset (x, y, origin_x, origin_y); } - void subtract_glyph_h_origin (hb_codepoint_t glyph, - hb_position_t *x, hb_position_t *y) + void subtract_glyph_h_origins (hb_buffer_t *buf) { - hb_position_t origin_x, origin_y; - - get_glyph_h_origin_with_fallback (glyph, &origin_x, &origin_y); - - *x -= origin_x; - *y -= origin_y; + apply_glyph_h_origins_with_fallback (buf, -1); } - void subtract_glyph_v_origin (hb_codepoint_t glyph, - hb_position_t *x, hb_position_t *y) + void subtract_glyph_v_origins (hb_buffer_t *buf) { - hb_position_t origin_x, origin_y; - - get_glyph_v_origin_with_fallback (glyph, &origin_x, &origin_y); - - *x -= origin_x; - *y -= origin_y; + apply_glyph_v_origins_with_fallback (buf, -1); } void subtract_glyph_origin_for_direction (hb_codepoint_t glyph, hb_direction_t direction, hb_position_t *x, hb_position_t *y) { hb_position_t origin_x, origin_y; - get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y); - - *x -= origin_x; - *y -= origin_y; + subtract_offset (x, y, origin_x, origin_y); } void get_glyph_kerning_for_direction (hb_codepoint_t first_glyph, hb_codepoint_t second_glyph, @@ -890,11 +1144,6 @@ struct hb_font_t return false; } - bool is_synthetic () const - { - return x_embolden || y_embolden || slant; - } - void changed () { float upem = face->get_upem (); @@ -906,6 +1155,8 @@ struct hb_font_t bool y_neg = y_scale < 0; y_mult = (y_neg ? -((int64_t) -y_scale << 16) : ((int64_t) y_scale << 16)) / upem; + is_synthetic = x_embolden || y_embolden || slant; + x_strength = roundf (abs (x_scale) * x_embolden); y_strength = roundf (abs (y_scale) * y_embolden); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-pool.hh b/src/java.desktop/share/native/libharfbuzz/hb-free-pool.hh similarity index 92% rename from src/java.desktop/share/native/libharfbuzz/hb-pool.hh rename to src/java.desktop/share/native/libharfbuzz/hb-free-pool.hh index 613c78d1973..3acd144a857 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-pool.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-free-pool.hh @@ -24,12 +24,12 @@ * Facebook Author(s): Behdad Esfahbod */ -#ifndef HB_POOL_HH -#define HB_POOL_HH +#ifndef HB_FREE_POOL_HH +#define HB_FREE_POOL_HH #include "hb.hh" -/* Memory pool for persistent allocation of small objects. +/* Memory pool for persistent alloc/free of small objects. * * Some AI musings on this, not necessarily true: * @@ -41,10 +41,10 @@ * sophisticated, use a real allocator. Or use a real language. */ template -struct hb_pool_t +struct hb_free_pool_t { - hb_pool_t () : next (nullptr) {} - ~hb_pool_t () + hb_free_pool_t () : next (nullptr) {} + ~hb_free_pool_t () { next = nullptr; @@ -104,4 +104,4 @@ struct hb_pool_t }; -#endif /* HB_POOL_HH */ +#endif /* HB_FREE_POOL_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ft.cc b/src/java.desktop/share/native/libharfbuzz/hb-ft.cc index e9c0e734a53..b90f966c57c 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ft.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ft.cc @@ -143,6 +143,9 @@ _hb_ft_font_destroy (void *data) /* hb_font changed, update FT_Face. */ static void _hb_ft_hb_font_changed (hb_font_t *font, FT_Face ft_face) { + if (unlikely (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)) + return; + hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data; float x_mult = 1.f, y_mult = 1.f; @@ -184,12 +187,14 @@ static void _hb_ft_hb_font_changed (hb_font_t *font, FT_Face ft_face) FT_Set_Transform (ft_face, &matrix, nullptr); ft_font->transform = true; } + else + FT_Set_Transform (ft_face, nullptr, nullptr); #if defined(HAVE_FT_GET_VAR_BLEND_COORDINATES) && !defined(HB_NO_VAR) - unsigned int num_coords; - const float *coords = hb_font_get_var_coords_design (font, &num_coords); - if (num_coords) + if (font->has_nonzero_coords) { + unsigned int num_coords; + const float *coords = hb_font_get_var_coords_design (font, &num_coords); FT_Fixed *ft_coords = (FT_Fixed *) hb_calloc (num_coords, sizeof (FT_Fixed)); if (ft_coords) { @@ -199,6 +204,12 @@ static void _hb_ft_hb_font_changed (hb_font_t *font, FT_Face ft_face) hb_free (ft_coords); } } + else if (font->num_coords) + { + // Some old versions of FreeType crash if we + // call this function on non-variable fonts. + FT_Set_Var_Design_Coordinates (ft_face, 0, nullptr); + } #endif } @@ -1093,6 +1104,10 @@ _hb_ft_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data FT_ULong length = 0; FT_Error error; + /* In new FreeType, a tag value of 1 loads the SFNT table directory. Reject it. */ + if (tag == 1) + return nullptr; + /* Note: FreeType like HarfBuzz uses the NONE tag for fetching the entire blob */ error = FT_Load_Sfnt_Table (ft_face, tag, 0, nullptr, &length); @@ -1366,7 +1381,7 @@ hb_ft_font_changed (hb_font_t *font) for (unsigned int i = 0; i < mm_var->num_axis; ++i) { - coords[i] = ft_coords[i] >>= 2; + coords[i] = (ft_coords[i] + 2) >> 2; nonzero = nonzero || coords[i]; } @@ -1717,7 +1732,12 @@ hb_ft_font_set_funcs (hb_font_t *font) ft_face->generic.finalizer = _release_blob; // And the FT_Library to the blob - hb_blob_set_user_data (blob, &ft_library_key, ft_library, destroy_ft_library, true); + if (unlikely (!hb_blob_set_user_data (blob, &ft_library_key, ft_library, destroy_ft_library, true))) + { + DEBUG_MSG (FT, font, "hb_blob_set_user_data() failed"); + FT_Done_Face (ft_face); + return; + } _hb_ft_font_set_funcs (font, ft_face, true); hb_ft_font_set_load_flags (font, FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-geometry.hh b/src/java.desktop/share/native/libharfbuzz/hb-geometry.hh index 795f29f6ab0..0de062df68e 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-geometry.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-geometry.hh @@ -26,7 +26,10 @@ #include "hb.hh" +#include "hb-algs.hh" + +template struct hb_extents_t { hb_extents_t () {} @@ -35,7 +38,7 @@ struct hb_extents_t ymin (hb_min (extents.y_bearing, extents.y_bearing + extents.height)), xmax (hb_max (extents.x_bearing, extents.x_bearing + extents.width)), ymax (hb_max (extents.y_bearing, extents.y_bearing + extents.height)) {} - hb_extents_t (float xmin, float ymin, float xmax, float ymax) : + hb_extents_t (Float xmin, Float ymin, Float xmax, Float ymax) : xmin (xmin), ymin (ymin), xmax (xmax), ymax (ymax) {} bool is_empty () const { return xmin >= xmax || ymin >= ymax; } @@ -69,7 +72,7 @@ struct hb_extents_t } void - add_point (float x, float y) + add_point (Float x, Float y) { if (unlikely (is_void ())) { @@ -97,62 +100,69 @@ struct hb_extents_t yneg ? y1 - y0 : y0 - y1}; } - float xmin = 0.f; - float ymin = 0.f; - float xmax = -1.f; - float ymax = -1.f; + Float xmin = 0; + Float ymin = 0; + Float xmax = -1; + Float ymax = -1; }; +template struct hb_transform_t { hb_transform_t () {} - hb_transform_t (float xx, float yx, - float xy, float yy, - float x0, float y0) : + hb_transform_t (Float xx, Float yx, + Float xy, Float yy, + Float x0, Float y0) : xx (xx), yx (yx), xy (xy), yy (yy), x0 (x0), y0 (y0) {} bool is_identity () const { - return xx == 1.f && yx == 0.f && - xy == 0.f && yy == 1.f && - x0 == 0.f && y0 == 0.f; + return xx == 1 && yx == 0 && + xy == 0 && yy == 1 && + x0 == 0 && y0 == 0; + } + bool is_translation () const + { + return xx == 1 && yx == 0 && + xy == 0 && yy == 1; } - void multiply (const hb_transform_t &o) + void multiply (const hb_transform_t &o, bool before=false) { - /* Copied from cairo, with "o" being "a" there and "this" being "b" there. */ - hb_transform_t r; - - r.xx = o.xx * xx + o.yx * xy; - r.yx = o.xx * yx + o.yx * yy; - - r.xy = o.xy * xx + o.yy * xy; - r.yy = o.xy * yx + o.yy * yy; - - r.x0 = o.x0 * xx + o.y0 * xy + x0; - r.y0 = o.x0 * yx + o.y0 * yy + y0; - - *this = r; + // Copied from cairo-matrix.c + const hb_transform_t &a = before ? o : *this; + const hb_transform_t &b = before ? *this : o; + *this = { + a.xx * b.xx + a.xy * b.yx, + a.yx * b.xx + a.yy * b.yx, + a.xx * b.xy + a.xy * b.yy, + a.yx * b.xy + a.yy * b.yy, + a.xx * b.x0 + a.xy * b.y0 + a.x0, + a.yx * b.x0 + a.yy * b.y0 + a.y0 + }; } - void transform_distance (float &dx, float &dy) const + HB_ALWAYS_INLINE + void transform_distance (Float &dx, Float &dy) const { - float new_x = xx * dx + xy * dy; - float new_y = yx * dx + yy * dy; + Float new_x = xx * dx + xy * dy; + Float new_y = yx * dx + yy * dy; dx = new_x; dy = new_y; } - void transform_point (float &x, float &y) const + HB_ALWAYS_INLINE + void transform_point (Float &x, Float &y) const { - transform_distance (x, y); - x += x0; - y += y0; + Float new_x = x0 + xx * x + xy * y; + Float new_y = y0 + yx * x + yy * y; + x = new_x; + y = new_y; } - void transform_extents (hb_extents_t &extents) const + void transform_extents (hb_extents_t &extents) const { - float quad_x[4], quad_y[4]; + Float quad_x[4], quad_y[4]; quad_x[0] = extents.xmin; quad_y[0] = extents.ymin; @@ -163,7 +173,7 @@ struct hb_transform_t quad_x[3] = extents.xmax; quad_y[3] = extents.ymax; - extents = hb_extents_t {}; + extents = hb_extents_t {}; for (unsigned i = 0; i < 4; i++) { transform_point (quad_x[i], quad_y[i]); @@ -171,20 +181,36 @@ struct hb_transform_t } } - void transform (const hb_transform_t &o) { multiply (o); } + void transform (const hb_transform_t &o, bool before=false) { multiply (o, before); } - void translate (float x, float y) + static hb_transform_t translation (Float x, Float y) { - if (x == 0.f && y == 0.f) - return; + return {1, 0, 0, 1, x, y}; + } + void translate (Float x, Float y, bool before=false) + { + if (before) + { + x0 += x; + y0 += y; + } + else + { + if (x == 0 && y == 0) + return; - x0 += xx * x + xy * y; - y0 += yx * x + yy * y; + x0 += xx * x + xy * y; + y0 += yx * x + yy * y; + } } - void scale (float scaleX, float scaleY) + static hb_transform_t scaling (Float scaleX, Float scaleY) { - if (scaleX == 1.f && scaleY == 1.f) + return {scaleX, 0, 0, scaleY, 0, 0}; + } + void scale (Float scaleX, Float scaleY) + { + if (scaleX == 1 && scaleY == 1) return; xx *= scaleX; @@ -192,52 +218,94 @@ struct hb_transform_t xy *= scaleY; yy *= scaleY; } - - void rotate (float rotation) + static hb_transform_t scaling_around_center (Float scaleX, Float scaleY, Float center_x, Float center_y) { - if (rotation == 0.f) + return {scaleX, 0, 0, scaleY, + center_x ? (1 - scaleX) * center_x : 0, + center_y ? (1 - scaleY) * center_y : 0}; + } + void scale_around_center (Float scaleX, Float scaleY, Float center_x, Float center_y) + { + if (scaleX == 1 && scaleY == 1) return; + transform (scaling_around_center (scaleX, scaleY, center_x, center_y)); + } + + static hb_transform_t rotation (Float radians) + { // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L240 - rotation = rotation * HB_PI; - float c; - float s; -#ifdef HAVE_SINCOSF - sincosf (rotation, &s, &c); -#else - c = cosf (rotation); - s = sinf (rotation); -#endif - auto other = hb_transform_t{c, s, -s, c, 0.f, 0.f}; - transform (other); + Float c; + Float s; + hb_sincos (radians, s, c); + return {c, s, -s, c, 0, 0}; } - - void skew (float skewX, float skewY) + void rotate (Float radians, bool before=false) { - if (skewX == 0.f && skewY == 0.f) + if (radians == 0) return; - // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L255 - skewX = skewX * HB_PI; - skewY = skewY * HB_PI; - auto other = hb_transform_t{1.f, - skewY ? tanf (skewY) : 0.f, - skewX ? tanf (skewX) : 0.f, - 1.f, - 0.f, 0.f}; - transform (other); + transform (rotation (radians), before); } - float xx = 1.f; - float yx = 0.f; - float xy = 0.f; - float yy = 1.f; - float x0 = 0.f; - float y0 = 0.f; + static hb_transform_t rotation_around_center (Float radians, Float center_x, Float center_y) + { + Float s, c; + hb_sincos (radians, s, c); + return { + c, s, -s, c, + (1 - c) * center_x + s * center_y, + -s * center_x + (1 - c) * center_y + }; + } + void rotate_around_center (Float radians, Float center_x, Float center_y, bool before=false) + { + if (radians == 0) + return; + + transform (rotation_around_center (radians, center_x, center_y), before); + } + + static hb_transform_t skewing (Float skewX, Float skewY) + { + return {1, skewY ? tanf (skewY) : 0, skewX ? tanf (skewX) : 0, 1, 0, 0}; + } + void skew (Float skewX, Float skewY) + { + if (skewX == 0 && skewY == 0) + return; + + transform (skewing (skewX, skewY)); + } + static hb_transform_t skewing_around_center (Float skewX, Float skewY, Float center_x, Float center_y) + { + skewX = skewX ? tanf (skewX) : 0; + skewY = skewY ? tanf (skewY) : 0; + return { + 1, skewY, skewX, 1, + center_y ? -skewX * center_y : 0, + center_x ? -skewY * center_x : 0 + }; + } + void skew_around_center (Float skewX, Float skewY, Float center_x, Float center_y) + { + if (skewX == 0 && skewY == 0) + return; + + transform (skewing_around_center (skewX, skewY, center_x, center_y)); + } + + Float xx = 1; + Float yx = 0; + Float xy = 0; + Float yy = 1; + Float x0 = 0; + Float y0 = 0; }; -#define HB_TRANSFORM_IDENTITY hb_transform_t{1.f, 0.f, 0.f, 1.f, 0.f, 0.f} +#define HB_TRANSFORM_IDENTITY {1, 0, 0, 1, 0, 0} +template struct hb_bounds_t { enum status_t { @@ -247,7 +315,7 @@ struct hb_bounds_t }; hb_bounds_t (status_t status = UNBOUNDED) : status (status) {} - hb_bounds_t (const hb_extents_t &extents) : + hb_bounds_t (const hb_extents_t &extents) : status (extents.is_empty () ? EMPTY : BOUNDED), extents (extents) {} void union_ (const hb_bounds_t &o) @@ -281,20 +349,21 @@ struct hb_bounds_t } status_t status; - hb_extents_t extents; + hb_extents_t extents; }; +template struct hb_transform_decomposed_t { - float translateX = 0; - float translateY = 0; - float rotation = 0; // in degrees, counter-clockwise - float scaleX = 1; - float scaleY = 1; - float skewX = 0; // in degrees, counter-clockwise - float skewY = 0; // in degrees, counter-clockwise - float tCenterX = 0; - float tCenterY = 0; + Float translateX = 0; + Float translateY = 0; + Float rotation = 0; // in radians, counter-clockwise + Float scaleX = 1; + Float scaleY = 1; + Float skewX = 0; // in radians, counter-clockwise + Float skewY = 0; // in radians, counter-clockwise + Float tCenterX = 0; + Float tCenterY = 0; operator bool () const { @@ -305,9 +374,9 @@ struct hb_transform_decomposed_t tCenterX || tCenterY; } - hb_transform_t to_transform () const + hb_transform_t to_transform () const { - hb_transform_t t; + hb_transform_t t; t.translate (translateX + tCenterX, translateY + tCenterY); t.rotate (rotation); t.scale (scaleX, scaleY); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-iter.hh b/src/java.desktop/share/native/libharfbuzz/hb-iter.hh index 21d9544a74b..661e6771a4a 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-iter.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-iter.hh @@ -772,8 +772,9 @@ struct hb_iota_iter_t : template auto inc (hb_type_identity s, hb_priority<1>) - -> hb_void_t (s), hb_declval ()))> - { v = hb_invoke (std::forward (s), v); } + -> hb_void_t> (s), + hb_declval ()))> + { v = hb_invoke (std::forward> (s), v); } void inc (S s, hb_priority<0>) @@ -972,7 +973,7 @@ struct Proj&& f = hb_identity) const { for (auto it = hb_iter (c); it; ++it) - if (!hb_match (std::forward (p), hb_get (std::forward (f), *it))) + if (!hb_match (p, hb_get (f, *it))) return false; return true; } @@ -989,7 +990,7 @@ struct Proj&& f = hb_identity) const { for (auto it = hb_iter (c); it; ++it) - if (hb_match (std::forward (p), hb_get (std::forward (f), *it))) + if (hb_match (p, hb_get (f, *it))) return true; return false; } @@ -1006,7 +1007,7 @@ struct Proj&& f = hb_identity) const { for (auto it = hb_iter (c); it; ++it) - if (hb_match (std::forward (p), hb_get (std::forward (f), *it))) + if (hb_match (p, hb_get (f, *it))) return false; return true; } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-kern.hh b/src/java.desktop/share/native/libharfbuzz/hb-kern.hh index 1f2c8d5811b..cf08c16689f 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-kern.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-kern.hh @@ -70,7 +70,7 @@ struct hb_kern_machine_t continue; } - skippy_iter.reset (idx); + skippy_iter.reset_fast (idx); unsigned unsafe_to; if (!skippy_iter.next (&unsafe_to)) { diff --git a/src/java.desktop/share/native/libharfbuzz/hb-limits.hh b/src/java.desktop/share/native/libharfbuzz/hb-limits.hh index fbc7bbe764e..857e183737f 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-limits.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-limits.hh @@ -29,20 +29,20 @@ #ifndef HB_BUFFER_MAX_LEN_FACTOR -#define HB_BUFFER_MAX_LEN_FACTOR 64 +#define HB_BUFFER_MAX_LEN_FACTOR 256 #endif #ifndef HB_BUFFER_MAX_LEN_MIN -#define HB_BUFFER_MAX_LEN_MIN 16384 +#define HB_BUFFER_MAX_LEN_MIN 65536 #endif #ifndef HB_BUFFER_MAX_LEN_DEFAULT #define HB_BUFFER_MAX_LEN_DEFAULT 0x3FFFFFFF /* Shaping more than a billion chars? Let us know! */ #endif #ifndef HB_BUFFER_MAX_OPS_FACTOR -#define HB_BUFFER_MAX_OPS_FACTOR 1024 +#define HB_BUFFER_MAX_OPS_FACTOR 4096 #endif #ifndef HB_BUFFER_MAX_OPS_MIN -#define HB_BUFFER_MAX_OPS_MIN 16384 +#define HB_BUFFER_MAX_OPS_MIN 65536 #endif #ifndef HB_BUFFER_MAX_OPS_DEFAULT #define HB_BUFFER_MAX_OPS_DEFAULT 0x1FFFFFFF /* Shaping more than a billion operations? Let us know! */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-machinery.hh b/src/java.desktop/share/native/libharfbuzz/hb-machinery.hh index ffbb8f3d301..8fa32ea8eaa 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-machinery.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-machinery.hh @@ -66,13 +66,22 @@ static inline Type& StructAtOffsetUnaligned(void *P, unsigned int offset) } /* StructAfter(X) returns the struct T& that is placed after X. - * Works with X of variable size also. X must implement get_size() */ -template -static inline const Type& StructAfter(const TObject &X) -{ return StructAtOffset(&X, X.get_size()); } -template -static inline Type& StructAfter(TObject &X) -{ return StructAtOffset(&X, X.get_size()); } + * Works with X of variable size also. X must implement get_size(). + * Any extra arguments are forwarded to get_size, so for example + * it can work with UnsizedArrayOf<> as well. */ +template +static inline auto StructAfter(const TObject &X, Ts... args) HB_AUTO_RETURN(( + StructAtOffset(&X, X.get_size(std::forward (args)...)) +)) +/* The is_const shenanigans is to avoid ambiguous overload with gcc-8. + * It disables this path when TObject is const. + * See: https://github.com/harfbuzz/harfbuzz/issues/5429 */ +template +static inline auto StructAfter(TObject &X, Ts... args) HB_AUTO_RETURN(( + sizeof(int[std::is_const::value ? -1 : +1]) > 0 ? + StructAtOffset(&X, X.get_size(std::forward (args)...)) + : *reinterpret_cast (0) +)) /* @@ -132,7 +141,6 @@ static inline Type& StructAfter(TObject &X) DEFINE_SIZE_ARRAY(size, array) - /* * Lazy loaders. * diff --git a/src/java.desktop/share/native/libharfbuzz/hb-map.hh b/src/java.desktop/share/native/libharfbuzz/hb-map.hh index 76206342f57..4c76622df7a 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-map.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-map.hh @@ -47,11 +47,11 @@ struct hb_hashmap_t hb_hashmap_t () { init (); } ~hb_hashmap_t () { fini (); } - hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () + void _copy (const hb_hashmap_t& o) { if (unlikely (!o.mask)) return; - if (item_t::is_trivial) + if (hb_is_trivially_copy_assignable (item_t)) { items = (item_t *) hb_malloc (sizeof (item_t) * (o.mask + 1)); if (unlikely (!items)) @@ -70,8 +70,16 @@ struct hb_hashmap_t alloc (o.population); hb_copy (o, *this); } + + hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () { _copy (o); } + hb_hashmap_t& operator= (const hb_hashmap_t& o) + { + reset (); + if (!items) { _copy (o); return *this; } + alloc (o.population); hb_copy (o, *this); return *this; + } + hb_hashmap_t (hb_hashmap_t&& o) noexcept : hb_hashmap_t () { hb_swap (*this, o); } - hb_hashmap_t& operator= (const hb_hashmap_t& o) { reset (); alloc (o.population); hb_copy (o, *this); return *this; } hb_hashmap_t& operator= (hb_hashmap_t&& o) noexcept { hb_swap (*this, o); return *this; } hb_hashmap_t (std::initializer_list> lst) : hb_hashmap_t () @@ -130,10 +138,7 @@ struct hb_hashmap_t uint32_t total_hash () const { return (hash * 31u) + hb_hash (value); } - static constexpr bool is_trivial = hb_is_trivially_constructible(K) && - hb_is_trivially_destructible(K) && - hb_is_trivially_constructible(V) && - hb_is_trivially_destructible(V); + static constexpr bool is_trivially_constructible = (hb_is_trivially_constructible(K) && hb_is_trivially_constructible(V)); }; hb_object_header_t header; @@ -174,19 +179,19 @@ struct hb_hashmap_t if (likely (items)) { unsigned size = mask + 1; - if (!item_t::is_trivial) - for (unsigned i = 0; i < size; i++) - items[i].~item_t (); + for (unsigned i = 0; i < size; i++) + items[i].~item_t (); hb_free (items); items = nullptr; } population = occupancy = 0; } - void reset () + hb_hashmap_t& reset () { successful = true; clear (); + return *this; } bool in_error () const { return !successful; } @@ -197,7 +202,7 @@ struct hb_hashmap_t if (new_population != 0 && (new_population + new_population / 2) < mask) return true; - unsigned int power = hb_bit_storage (hb_max ((unsigned) population, new_population) * 2 + 8); + unsigned int power = hb_bit_storage (hb_max (hb_max ((unsigned) population, new_population) * 2, 4u)); unsigned int new_size = 1u << power; item_t *new_items = (item_t *) hb_malloc ((size_t) new_size * sizeof (item_t)); if (unlikely (!new_items)) @@ -205,7 +210,7 @@ struct hb_hashmap_t successful = false; return false; } - if (!item_t::is_trivial) + if (!item_t::is_trivially_constructible) for (auto &_ : hb_iter (new_items, new_size)) new (&_) item_t (); else @@ -231,9 +236,8 @@ struct hb_hashmap_t std::move (old_items[i].value)); } } - if (!item_t::is_trivial) - for (unsigned int i = 0; i < old_size; i++) - old_items[i].~item_t (); + for (unsigned int i = 0; i < old_size; i++) + old_items[i].~item_t (); hb_free (old_items); @@ -335,7 +339,13 @@ struct hb_hashmap_t bool has (const K &key, VV **vp = nullptr) const { if (!items) return false; - auto *item = fetch_item (key, hb_hash (key)); + return has_with_hash (key, hb_hash (key), vp); + } + template + bool has_with_hash (const K &key, uint32_t hash, VV **vp = nullptr) const + { + if (!items) return false; + auto *item = fetch_item (key, hash); if (item) { if (vp) *vp = std::addressof (item->value); @@ -481,10 +491,17 @@ struct hb_hashmap_t /* Sink interface. */ hb_hashmap_t& operator << (const hb_pair_t& v) { set (v.first, v.second); return *this; } + template hb_hashmap_t& operator << (const hb_pair_t& v) { set (v.first, std::move (v.second)); return *this; } + template hb_hashmap_t& operator << (const hb_pair_t& v) { set (std::move (v.first), v.second); return *this; } + template hb_hashmap_t& operator << (const hb_pair_t& v) { set (std::move (v.first), std::move (v.second)); return *this; } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-number-parser.hh b/src/java.desktop/share/native/libharfbuzz/hb-number-parser.hh index 9d2867e4835..07f3ebe0c7d 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-number-parser.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-number-parser.hh @@ -31,7 +31,7 @@ #include "hb.hh" -#line 35 "hb-number-parser.hh" +#line 32 "hb-number-parser.hh" static const unsigned char _double_parser_trans_keys[] = { 0u, 0u, 43u, 57u, 46u, 57u, 48u, 57u, 43u, 57u, 48u, 57u, 48u, 101u, 48u, 57u, 46u, 101u, 0 @@ -135,12 +135,12 @@ strtod_rl (const char *p, const char **end_ptr /* IN/OUT */) int cs; -#line 139 "hb-number-parser.hh" +#line 132 "hb-number-parser.hh" { cs = double_parser_start; } -#line 144 "hb-number-parser.hh" +#line 135 "hb-number-parser.hh" { int _slen; int _trans; @@ -198,7 +198,7 @@ _resume: exp_overflow = true; } break; -#line 202 "hb-number-parser.hh" +#line 187 "hb-number-parser.hh" } _again: diff --git a/src/java.desktop/share/native/libharfbuzz/hb-open-file.hh b/src/java.desktop/share/native/libharfbuzz/hb-open-file.hh index 382ee2ddaf2..538240b6416 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-open-file.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-open-file.hh @@ -465,11 +465,11 @@ struct OpenTypeFontFile Typ1Tag = HB_TAG ('t','y','p','1') /* Obsolete Apple Type1 font in SFNT container */ }; - hb_tag_t get_tag () const { return u.tag; } + hb_tag_t get_tag () const { return u.tag.v; } unsigned int get_face_count () const { - switch (u.tag) { + switch (u.tag.v) { case CFFTag: /* All the non-collection tags */ case TrueTag: case Typ1Tag: @@ -483,7 +483,7 @@ struct OpenTypeFontFile { if (base_offset) *base_offset = 0; - switch (u.tag) { + switch (u.tag.v) { /* Note: for non-collection SFNT data we ignore index. This is because * Apple dfont container is a container of SFNT's. So each SFNT is a * non-TTC, but the index is more than zero. */ @@ -512,9 +512,9 @@ struct OpenTypeFontFile bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!u.tag.sanitize (c))) return_trace (false); + if (unlikely (!u.tag.v.sanitize (c))) return_trace (false); hb_barrier (); - switch (u.tag) { + switch (u.tag.v) { case CFFTag: /* All the non-collection tags */ case TrueTag: case Typ1Tag: @@ -527,13 +527,13 @@ struct OpenTypeFontFile protected: union { - Tag tag; /* 4-byte identifier. */ + struct { Tag v; } tag; /* 4-byte identifier. */ OpenTypeFontFace fontFace; TTCHeader ttcHeader; ResourceForkHeader rfHeader; } u; public: - DEFINE_SIZE_UNION (4, tag); + DEFINE_SIZE_UNION (4, tag.v); }; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh b/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh index 75d87f11ea5..ad831b66d56 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh @@ -54,35 +54,41 @@ namespace OT { */ /* Integer types in big-endian order and no alignment requirement */ -template -struct IntType +struct NumType { typedef Type type; - - IntType () = default; - explicit constexpr IntType (Type V) : v {V} {} - IntType& operator = (Type i) { v = i; return *this; } /* For reason we define cast out operator for signed/unsigned, instead of Type, see: * https://github.com/harfbuzz/harfbuzz/pull/2875/commits/09836013995cab2b9f07577a179ad7b024130467 */ - operator typename std::conditional::value, signed, unsigned>::type () const { return v; } + typedef typename std::conditional::value && sizeof (Type) <= sizeof(int), + typename std::conditional::value, signed, unsigned>::type, + Type>::type WideType; - bool operator == (const IntType &o) const { return (Type) v == (Type) o.v; } - bool operator != (const IntType &o) const { return !(*this == o); } + NumType () = default; + explicit constexpr NumType (Type V) : v {V} {} + NumType& operator = (Type V) { v = V; return *this; } - IntType& operator += (unsigned count) { *this = *this + count; return *this; } - IntType& operator -= (unsigned count) { *this = *this - count; return *this; } - IntType& operator ++ () { *this += 1; return *this; } - IntType& operator -- () { *this -= 1; return *this; } - IntType operator ++ (int) { IntType c (*this); ++*this; return c; } - IntType operator -- (int) { IntType c (*this); --*this; return c; } + operator WideType () const { return v; } - HB_INTERNAL static int cmp (const IntType *a, const IntType *b) + bool operator == (const NumType &o) const { return (Type) v == (Type) o.v; } + bool operator != (const NumType &o) const { return !(*this == o); } + + NumType& operator += (WideType count) { *this = *this + count; return *this; } + NumType& operator -= (WideType count) { *this = *this - count; return *this; } + NumType& operator ++ () { *this += 1; return *this; } + NumType& operator -- () { *this -= 1; return *this; } + NumType operator ++ (int) { NumType c (*this); ++*this; return c; } + NumType operator -- (int) { NumType c (*this); --*this; return c; } + + uint32_t hash () const { return hb_array ((const char *) &v, sizeof (v)).hash (); } + HB_INTERNAL static int cmp (const NumType *a, const NumType *b) { return b->cmp (*a); } HB_INTERNAL static int cmp (const void *a, const void *b) { - IntType *pa = (IntType *) a; - IntType *pb = (IntType *) b; + NumType *pa = (NumType *) a; + NumType *pb = (NumType *) b; return pb->cmp (*pa); } @@ -99,20 +105,36 @@ struct IntType return_trace (c->check_struct (this)); } protected: - BEInt v; + typename std::conditional::value, + HBInt, + HBFloat>::type v; public: DEFINE_SIZE_STATIC (Size); }; -typedef IntType HBUINT8; /* 8-bit unsigned integer. */ -typedef IntType HBINT8; /* 8-bit signed integer. */ -typedef IntType HBUINT16; /* 16-bit unsigned integer. */ -typedef IntType HBINT16; /* 16-bit signed integer. */ -typedef IntType HBUINT32; /* 32-bit unsigned integer. */ -typedef IntType HBINT32; /* 32-bit signed integer. */ +typedef NumType HBUINT8; /* 8-bit big-endian unsigned integer. */ +typedef NumType HBINT8; /* 8-bit big-endian signed integer. */ +typedef NumType HBUINT16; /* 16-bit big-endian unsigned integer. */ +typedef NumType HBINT16; /* 16-bit big-endian signed integer. */ +typedef NumType HBUINT32; /* 32-bit big-endian unsigned integer. */ +typedef NumType HBINT32; /* 32-bit big-endian signed integer. */ +typedef NumType HBUINT64; /* 64-bit big-endian unsigned integer. */ +typedef NumType HBINT64; /* 64-bit big-endian signed integer. */ /* Note: we cannot defined a signed HBINT24 because there's no corresponding C type. * Works for unsigned, but not signed, since we rely on compiler for sign-extension. */ -typedef IntType HBUINT24; /* 24-bit unsigned integer. */ +typedef NumType HBUINT24; /* 24-bit big-endian unsigned integer. */ + +typedef NumType HBUINT16LE; /* 16-bit little-endian unsigned integer. */ +typedef NumType HBINT16LE; /* 16-bit little-endian signed integer. */ +typedef NumType HBUINT32LE; /* 32-bit little-endian unsigned integer. */ +typedef NumType HBINT32LE; /* 32-bit little-endian signed integer. */ +typedef NumType HBUINT64LE; /* 64-bit little-endian unsigned integer. */ +typedef NumType HBINT64LE; /* 64-bit little-endian signed integer. */ + +typedef NumType HBFLOAT32BE; /* 32-bit little-endian floating point number. */ +typedef NumType HBFLOAT64BE; /* 64-bit little-endian floating point number. */ +typedef NumType HBFLOAT32LE; /* 32-bit little-endian floating point number. */ +typedef NumType HBFLOAT64LE; /* 64-bit little-endian floating point number. */ /* 15-bit unsigned number; top bit used for extension. */ struct HBUINT15 : HBUINT16 @@ -218,7 +240,7 @@ typedef HBUINT16 UFWORD; template struct HBFixed : Type { - static constexpr float shift = (float) (1 << fraction_bits); + static constexpr float mult = 1.f / (1 << fraction_bits); static_assert (Type::static_size * 8 > fraction_bits, ""); operator signed () const = delete; @@ -226,8 +248,8 @@ struct HBFixed : Type explicit operator float () const { return to_float (); } typename Type::type to_int () const { return Type::v; } void set_int (typename Type::type i ) { Type::v = i; } - float to_float (float offset = 0) const { return ((int32_t) Type::v + offset) / shift; } - void set_float (float f) { Type::v = roundf (f * shift); } + float to_float (float offset = 0) const { return ((int32_t) Type::v + offset) * mult; } + void set_float (float f) { Type::v = roundf (f / mult); } public: DEFINE_SIZE_STATIC (Type::static_size); }; @@ -504,16 +526,9 @@ struct OffsetTo : Offset return_trace (sanitize_shallow (c, base) && hb_barrier () && (this->is_null () || - c->dispatch (StructAtOffset (base, *this), std::forward (ds)...) || - neuter (c))); + c->dispatch (StructAtOffset (base, *this), std::forward (ds)...))); } - /* Set the offset to Null */ - bool neuter (hb_sanitize_context_t *c) const - { - if (!has_null) return false; - return c->try_set (this, 0); - } DEFINE_SIZE_STATIC (sizeof (OffsetType)); }; /* Partial specializations. */ @@ -1481,8 +1496,8 @@ struct TupleValues VALUE_RUN_COUNT_MASK = 0x3F }; - static unsigned compile (hb_array_t values, /* IN */ - hb_array_t encoded_bytes /* OUT */) + static unsigned compile_unsafe (hb_array_t values, /* IN */ + unsigned char *encoded_bytes /* OUT */) { unsigned num_values = values.length; unsigned encoded_len = 0; @@ -1491,24 +1506,23 @@ struct TupleValues { int val = values.arrayZ[i]; if (val == 0) - encoded_len += encode_value_run_as_zeroes (i, encoded_bytes.sub_array (encoded_len), values); - else if (val >= -128 && val <= 127) - encoded_len += encode_value_run_as_bytes (i, encoded_bytes.sub_array (encoded_len), values); - else if (val >= -32768 && val <= 32767) - encoded_len += encode_value_run_as_words (i, encoded_bytes.sub_array (encoded_len), values); + encoded_len += encode_value_run_as_zeroes (i, encoded_bytes + encoded_len, values); + else if ((int8_t) val == val) + encoded_len += encode_value_run_as_bytes (i, encoded_bytes + encoded_len, values); + else if ((int16_t) val == val) + encoded_len += encode_value_run_as_words (i, encoded_bytes + encoded_len, values); else - encoded_len += encode_value_run_as_longs (i, encoded_bytes.sub_array (encoded_len), values); + encoded_len += encode_value_run_as_longs (i, encoded_bytes + encoded_len, values); } return encoded_len; } static unsigned encode_value_run_as_zeroes (unsigned& i, - hb_array_t encoded_bytes, + unsigned char *it, hb_array_t values) { unsigned num_values = values.length; unsigned run_length = 0; - auto it = encoded_bytes.iter (); unsigned encoded_len = 0; while (i < num_values && values.arrayZ[i] == 0) { @@ -1532,7 +1546,7 @@ struct TupleValues } static unsigned encode_value_run_as_bytes (unsigned &i, - hb_array_t encoded_bytes, + unsigned char *it, hb_array_t values) { unsigned start = i; @@ -1540,7 +1554,7 @@ struct TupleValues while (i < num_values) { int val = values.arrayZ[i]; - if (val > 127 || val < -128) + if ((int8_t) val != val) break; /* from fonttools: if there're 2 or more zeros in a sequence, @@ -1553,7 +1567,6 @@ struct TupleValues unsigned run_length = i - start; unsigned encoded_len = 0; - auto it = encoded_bytes.iter (); while (run_length >= 64) { @@ -1561,10 +1574,9 @@ struct TupleValues encoded_len++; for (unsigned j = 0; j < 64; j++) - { - *it++ = static_cast (values.arrayZ[start + j]); - encoded_len++; - } + it[j] = static_cast (values.arrayZ[start + j]); + it += 64; + encoded_len += 64; start += 64; run_length -= 64; @@ -1575,18 +1587,16 @@ struct TupleValues *it++ = (VALUES_ARE_BYTES | (run_length - 1)); encoded_len++; - while (start < i) - { - *it++ = static_cast (values.arrayZ[start++]); - encoded_len++; - } + for (unsigned j = 0; j < run_length; j++) + it[j] = static_cast (values.arrayZ[start + j]); + encoded_len += run_length; } return encoded_len; } static unsigned encode_value_run_as_words (unsigned &i, - hb_array_t encoded_bytes, + unsigned char *it, hb_array_t values) { unsigned start = i; @@ -1595,22 +1605,24 @@ struct TupleValues { int val = values.arrayZ[i]; - /* start a new run for a single zero value*/ + if ((int16_t) val != val) + break; + + /* start a new run for a single zero value. */ if (val == 0) break; - /* from fonttools: continue word-encoded run if there's only one + /* From fonttools: continue word-encoded run if there's only one * single value in the range [-128, 127] because it is more compact. * Only start a new run when there're 2 continuous such values. */ - if (val >= -128 && val <= 127 && + if ((int8_t) val == val && i + 1 < num_values && - values.arrayZ[i+1] >= -128 && values.arrayZ[i+1] <= 127) + (int8_t) values.arrayZ[i+1] == values.arrayZ[i+1]) break; i++; } unsigned run_length = i - start; - auto it = encoded_bytes.iter (); unsigned encoded_len = 0; while (run_length >= 64) { @@ -1647,7 +1659,7 @@ struct TupleValues } static unsigned encode_value_run_as_longs (unsigned &i, - hb_array_t encoded_bytes, + unsigned char *it, hb_array_t values) { unsigned start = i; @@ -1656,14 +1668,13 @@ struct TupleValues { int val = values.arrayZ[i]; - if (val >= -32768 && val <= 32767) + if ((int16_t) val == val) break; i++; } unsigned run_length = i - start; - auto it = encoded_bytes.iter (); unsigned encoded_len = 0; while (run_length >= 64) { @@ -1704,10 +1715,14 @@ struct TupleValues } template +#ifndef HB_OPTIMIZE_SIZE + HB_ALWAYS_INLINE +#endif static bool decompile (const HBUINT8 *&p /* IN/OUT */, hb_vector_t &values /* IN/OUT */, const HBUINT8 *end, - bool consume_all = false) + bool consume_all = false, + unsigned start = 0) { unsigned i = 0; unsigned count = consume_all ? UINT_MAX : values.length; @@ -1720,19 +1735,24 @@ struct TupleValues unsigned run_count = (control & VALUE_RUN_COUNT_MASK) + 1; if (consume_all) { - if (unlikely (!values.resize (values.length + run_count, false))) + if (unlikely (!values.resize_dirty (values.length + run_count))) return false; } unsigned stop = i + run_count; if (unlikely (stop > count)) return false; + + unsigned skip = i < start ? hb_min (start - i, run_count) : 0; + i += skip; + if ((control & VALUES_SIZE_MASK) == VALUES_ARE_ZEROS) { - for (; i < stop; i++) - values.arrayZ[i] = 0; + hb_memset (&values.arrayZ[i], 0, (stop - i) * sizeof (T)); + i = stop; } else if ((control & VALUES_SIZE_MASK) == VALUES_ARE_WORDS) { if (unlikely (p + run_count * HBINT16::static_size > end)) return false; + p += skip * HBINT16::static_size; #ifndef HB_OPTIMIZE_SIZE for (; i + 3 < stop; i += 4) { @@ -1755,6 +1775,7 @@ struct TupleValues else if ((control & VALUES_SIZE_MASK) == VALUES_ARE_LONGS) { if (unlikely (p + run_count * HBINT32::static_size > end)) return false; + p += skip * HBINT32::static_size; for (; i < stop; i++) { values.arrayZ[i] = * (const HBINT32 *) p; @@ -1764,6 +1785,7 @@ struct TupleValues else if ((control & VALUES_SIZE_MASK) == VALUES_ARE_BYTES) { if (unlikely (p + run_count > end)) return false; + p += skip * HBINT8::static_size; #ifndef HB_OPTIMIZE_SIZE for (; i + 3 < stop; i += 4) { @@ -1784,7 +1806,7 @@ struct TupleValues { iter_t (const unsigned char *p_, unsigned len_) : p (p_), endp (p_ + len_) - { if (ensure_run ()) read_value (); } + { if (likely (ensure_run ())) read_value (); } private: const unsigned char *p; @@ -1793,10 +1815,14 @@ struct TupleValues signed run_count = 0; unsigned width = 0; + HB_ALWAYS_INLINE bool ensure_run () { if (likely (run_count > 0)) return true; - + return _ensure_run (); + } + bool _ensure_run () + { if (unlikely (p >= endp)) { run_count = 0; @@ -1886,10 +1912,15 @@ struct TupleValues signed run_count = 0; unsigned width = 0; + HB_ALWAYS_INLINE bool ensure_run () { - if (run_count > 0) return true; + if (likely (run_count > 0)) return true; + return _ensure_run (); + } + bool _ensure_run () + { if (unlikely (p >= end)) { run_count = 0; @@ -2013,7 +2044,10 @@ struct TupleValues } #ifndef HB_OPTIMIZE_SIZE - if (scale == 1.0f) + // The following branch is supposed to speed things up by avoiding + // the multiplication in _add_to<> if scale is 1.0f. + // But in practice it seems to bloat the code and slow things down. + if (false && scale == 1.0f) _add_to (out); else #endif @@ -2038,6 +2072,23 @@ struct TupleList : CFF2Index }; +// Alignment + +template +struct Align +{ + unsigned get_size (const void *base) const + { + unsigned offset = (const char *) this - (const char *) base; + return (alignment - offset) & (alignment - 1); + } + + public: + DEFINE_SIZE_MIN (0); +}; + + + } /* namespace OT */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff-common.hh index 1e3e0be5106..ec018efe645 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff-common.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff-common.hh @@ -79,7 +79,7 @@ struct Dict : UnsizedByteStr { TRACE_SERIALIZE (this); for (unsigned int i = 0; i < dictval.get_count (); i++) - if (unlikely (!opszr.serialize (c, dictval[i], std::forward (ds)...))) + if (unlikely (!opszr.serialize (c, dictval[i], ds...))) return_trace (false); return_trace (true); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-std-str.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-std-str.hh index 65d56ae18b5..bf56abb975c 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-std-str.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-std-str.hh @@ -30,396 +30,396 @@ #include "hb.hh" #endif -_S(".notdef") -_S("space") -_S("exclam") -_S("quotedbl") -_S("numbersign") -_S("dollar") -_S("percent") -_S("ampersand") -_S("quoteright") -_S("parenleft") -_S("parenright") -_S("asterisk") -_S("plus") -_S("comma") -_S("hyphen") -_S("period") -_S("slash") -_S("zero") -_S("one") -_S("two") -_S("three") -_S("four") -_S("five") -_S("six") -_S("seven") -_S("eight") -_S("nine") -_S("colon") -_S("semicolon") -_S("less") -_S("equal") -_S("greater") -_S("question") -_S("at") -_S("A") -_S("B") -_S("C") -_S("D") -_S("E") -_S("F") -_S("G") -_S("H") -_S("I") -_S("J") -_S("K") -_S("L") -_S("M") -_S("N") -_S("O") -_S("P") -_S("Q") -_S("R") -_S("S") -_S("T") -_S("U") -_S("V") -_S("W") -_S("X") -_S("Y") -_S("Z") -_S("bracketleft") -_S("backslash") -_S("bracketright") -_S("asciicircum") -_S("underscore") -_S("quoteleft") -_S("a") -_S("b") -_S("c") -_S("d") -_S("e") -_S("f") -_S("g") -_S("h") -_S("i") -_S("j") -_S("k") -_S("l") -_S("m") -_S("n") -_S("o") -_S("p") -_S("q") -_S("r") -_S("s") -_S("t") -_S("u") -_S("v") -_S("w") -_S("x") -_S("y") -_S("z") -_S("braceleft") -_S("bar") -_S("braceright") -_S("asciitilde") -_S("exclamdown") -_S("cent") -_S("sterling") -_S("fraction") -_S("yen") -_S("florin") -_S("section") -_S("currency") -_S("quotesingle") -_S("quotedblleft") -_S("guillemotleft") -_S("guilsinglleft") -_S("guilsinglright") -_S("fi") -_S("fl") -_S("endash") -_S("dagger") -_S("daggerdbl") -_S("periodcentered") -_S("paragraph") -_S("bullet") -_S("quotesinglbase") -_S("quotedblbase") -_S("quotedblright") -_S("guillemotright") -_S("ellipsis") -_S("perthousand") -_S("questiondown") -_S("grave") -_S("acute") -_S("circumflex") -_S("tilde") -_S("macron") -_S("breve") -_S("dotaccent") -_S("dieresis") -_S("ring") -_S("cedilla") -_S("hungarumlaut") -_S("ogonek") -_S("caron") -_S("emdash") -_S("AE") -_S("ordfeminine") -_S("Lslash") -_S("Oslash") -_S("OE") -_S("ordmasculine") -_S("ae") -_S("dotlessi") -_S("lslash") -_S("oslash") -_S("oe") -_S("germandbls") -_S("onesuperior") -_S("logicalnot") -_S("mu") -_S("trademark") -_S("Eth") -_S("onehalf") -_S("plusminus") -_S("Thorn") -_S("onequarter") -_S("divide") -_S("brokenbar") -_S("degree") -_S("thorn") -_S("threequarters") -_S("twosuperior") -_S("registered") -_S("minus") -_S("eth") -_S("multiply") -_S("threesuperior") -_S("copyright") -_S("Aacute") -_S("Acircumflex") -_S("Adieresis") -_S("Agrave") -_S("Aring") -_S("Atilde") -_S("Ccedilla") -_S("Eacute") -_S("Ecircumflex") -_S("Edieresis") -_S("Egrave") -_S("Iacute") -_S("Icircumflex") -_S("Idieresis") -_S("Igrave") -_S("Ntilde") -_S("Oacute") -_S("Ocircumflex") -_S("Odieresis") -_S("Ograve") -_S("Otilde") -_S("Scaron") -_S("Uacute") -_S("Ucircumflex") -_S("Udieresis") -_S("Ugrave") -_S("Yacute") -_S("Ydieresis") -_S("Zcaron") -_S("aacute") -_S("acircumflex") -_S("adieresis") -_S("agrave") -_S("aring") -_S("atilde") -_S("ccedilla") -_S("eacute") -_S("ecircumflex") -_S("edieresis") -_S("egrave") -_S("iacute") -_S("icircumflex") -_S("idieresis") -_S("igrave") -_S("ntilde") -_S("oacute") -_S("ocircumflex") -_S("odieresis") -_S("ograve") -_S("otilde") -_S("scaron") -_S("uacute") -_S("ucircumflex") -_S("udieresis") -_S("ugrave") -_S("yacute") -_S("ydieresis") -_S("zcaron") -_S("exclamsmall") -_S("Hungarumlautsmall") -_S("dollaroldstyle") -_S("dollarsuperior") -_S("ampersandsmall") -_S("Acutesmall") -_S("parenleftsuperior") -_S("parenrightsuperior") -_S("twodotenleader") -_S("onedotenleader") -_S("zerooldstyle") -_S("oneoldstyle") -_S("twooldstyle") -_S("threeoldstyle") -_S("fouroldstyle") -_S("fiveoldstyle") -_S("sixoldstyle") -_S("sevenoldstyle") -_S("eightoldstyle") -_S("nineoldstyle") -_S("commasuperior") -_S("threequartersemdash") -_S("periodsuperior") -_S("questionsmall") -_S("asuperior") -_S("bsuperior") -_S("centsuperior") -_S("dsuperior") -_S("esuperior") -_S("isuperior") -_S("lsuperior") -_S("msuperior") -_S("nsuperior") -_S("osuperior") -_S("rsuperior") -_S("ssuperior") -_S("tsuperior") -_S("ff") -_S("ffi") -_S("ffl") -_S("parenleftinferior") -_S("parenrightinferior") -_S("Circumflexsmall") -_S("hyphensuperior") -_S("Gravesmall") -_S("Asmall") -_S("Bsmall") -_S("Csmall") -_S("Dsmall") -_S("Esmall") -_S("Fsmall") -_S("Gsmall") -_S("Hsmall") -_S("Ismall") -_S("Jsmall") -_S("Ksmall") -_S("Lsmall") -_S("Msmall") -_S("Nsmall") -_S("Osmall") -_S("Psmall") -_S("Qsmall") -_S("Rsmall") -_S("Ssmall") -_S("Tsmall") -_S("Usmall") -_S("Vsmall") -_S("Wsmall") -_S("Xsmall") -_S("Ysmall") -_S("Zsmall") -_S("colonmonetary") -_S("onefitted") -_S("rupiah") -_S("Tildesmall") -_S("exclamdownsmall") -_S("centoldstyle") -_S("Lslashsmall") -_S("Scaronsmall") -_S("Zcaronsmall") -_S("Dieresissmall") -_S("Brevesmall") -_S("Caronsmall") -_S("Dotaccentsmall") -_S("Macronsmall") -_S("figuredash") -_S("hypheninferior") -_S("Ogoneksmall") -_S("Ringsmall") -_S("Cedillasmall") -_S("questiondownsmall") -_S("oneeighth") -_S("threeeighths") -_S("fiveeighths") -_S("seveneighths") -_S("onethird") -_S("twothirds") -_S("zerosuperior") -_S("foursuperior") -_S("fivesuperior") -_S("sixsuperior") -_S("sevensuperior") -_S("eightsuperior") -_S("ninesuperior") -_S("zeroinferior") -_S("oneinferior") -_S("twoinferior") -_S("threeinferior") -_S("fourinferior") -_S("fiveinferior") -_S("sixinferior") -_S("seveninferior") -_S("eightinferior") -_S("nineinferior") -_S("centinferior") -_S("dollarinferior") -_S("periodinferior") -_S("commainferior") -_S("Agravesmall") -_S("Aacutesmall") -_S("Acircumflexsmall") -_S("Atildesmall") -_S("Adieresissmall") -_S("Aringsmall") -_S("AEsmall") -_S("Ccedillasmall") -_S("Egravesmall") -_S("Eacutesmall") -_S("Ecircumflexsmall") -_S("Edieresissmall") -_S("Igravesmall") -_S("Iacutesmall") -_S("Icircumflexsmall") -_S("Idieresissmall") -_S("Ethsmall") -_S("Ntildesmall") -_S("Ogravesmall") -_S("Oacutesmall") -_S("Ocircumflexsmall") -_S("Otildesmall") -_S("Odieresissmall") -_S("OEsmall") -_S("Oslashsmall") -_S("Ugravesmall") -_S("Uacutesmall") -_S("Ucircumflexsmall") -_S("Udieresissmall") -_S("Yacutesmall") -_S("Thornsmall") -_S("Ydieresissmall") -_S("001.000") -_S("001.001") -_S("001.002") -_S("001.003") -_S("Black") -_S("Bold") -_S("Book") -_S("Light") -_S("Medium") -_S("Regular") -_S("Roman") -_S("Semibold") +HB_STR(".notdef") +HB_STR("space") +HB_STR("exclam") +HB_STR("quotedbl") +HB_STR("numbersign") +HB_STR("dollar") +HB_STR("percent") +HB_STR("ampersand") +HB_STR("quoteright") +HB_STR("parenleft") +HB_STR("parenright") +HB_STR("asterisk") +HB_STR("plus") +HB_STR("comma") +HB_STR("hyphen") +HB_STR("period") +HB_STR("slash") +HB_STR("zero") +HB_STR("one") +HB_STR("two") +HB_STR("three") +HB_STR("four") +HB_STR("five") +HB_STR("six") +HB_STR("seven") +HB_STR("eight") +HB_STR("nine") +HB_STR("colon") +HB_STR("semicolon") +HB_STR("less") +HB_STR("equal") +HB_STR("greater") +HB_STR("question") +HB_STR("at") +HB_STR("A") +HB_STR("B") +HB_STR("C") +HB_STR("D") +HB_STR("E") +HB_STR("F") +HB_STR("G") +HB_STR("H") +HB_STR("I") +HB_STR("J") +HB_STR("K") +HB_STR("L") +HB_STR("M") +HB_STR("N") +HB_STR("O") +HB_STR("P") +HB_STR("Q") +HB_STR("R") +HB_STR("S") +HB_STR("T") +HB_STR("U") +HB_STR("V") +HB_STR("W") +HB_STR("X") +HB_STR("Y") +HB_STR("Z") +HB_STR("bracketleft") +HB_STR("backslash") +HB_STR("bracketright") +HB_STR("asciicircum") +HB_STR("underscore") +HB_STR("quoteleft") +HB_STR("a") +HB_STR("b") +HB_STR("c") +HB_STR("d") +HB_STR("e") +HB_STR("f") +HB_STR("g") +HB_STR("h") +HB_STR("i") +HB_STR("j") +HB_STR("k") +HB_STR("l") +HB_STR("m") +HB_STR("n") +HB_STR("o") +HB_STR("p") +HB_STR("q") +HB_STR("r") +HB_STR("s") +HB_STR("t") +HB_STR("u") +HB_STR("v") +HB_STR("w") +HB_STR("x") +HB_STR("y") +HB_STR("z") +HB_STR("braceleft") +HB_STR("bar") +HB_STR("braceright") +HB_STR("asciitilde") +HB_STR("exclamdown") +HB_STR("cent") +HB_STR("sterling") +HB_STR("fraction") +HB_STR("yen") +HB_STR("florin") +HB_STR("section") +HB_STR("currency") +HB_STR("quotesingle") +HB_STR("quotedblleft") +HB_STR("guillemotleft") +HB_STR("guilsinglleft") +HB_STR("guilsinglright") +HB_STR("fi") +HB_STR("fl") +HB_STR("endash") +HB_STR("dagger") +HB_STR("daggerdbl") +HB_STR("periodcentered") +HB_STR("paragraph") +HB_STR("bullet") +HB_STR("quotesinglbase") +HB_STR("quotedblbase") +HB_STR("quotedblright") +HB_STR("guillemotright") +HB_STR("ellipsis") +HB_STR("perthousand") +HB_STR("questiondown") +HB_STR("grave") +HB_STR("acute") +HB_STR("circumflex") +HB_STR("tilde") +HB_STR("macron") +HB_STR("breve") +HB_STR("dotaccent") +HB_STR("dieresis") +HB_STR("ring") +HB_STR("cedilla") +HB_STR("hungarumlaut") +HB_STR("ogonek") +HB_STR("caron") +HB_STR("emdash") +HB_STR("AE") +HB_STR("ordfeminine") +HB_STR("Lslash") +HB_STR("Oslash") +HB_STR("OE") +HB_STR("ordmasculine") +HB_STR("ae") +HB_STR("dotlessi") +HB_STR("lslash") +HB_STR("oslash") +HB_STR("oe") +HB_STR("germandbls") +HB_STR("onesuperior") +HB_STR("logicalnot") +HB_STR("mu") +HB_STR("trademark") +HB_STR("Eth") +HB_STR("onehalf") +HB_STR("plusminus") +HB_STR("Thorn") +HB_STR("onequarter") +HB_STR("divide") +HB_STR("brokenbar") +HB_STR("degree") +HB_STR("thorn") +HB_STR("threequarters") +HB_STR("twosuperior") +HB_STR("registered") +HB_STR("minus") +HB_STR("eth") +HB_STR("multiply") +HB_STR("threesuperior") +HB_STR("copyright") +HB_STR("Aacute") +HB_STR("Acircumflex") +HB_STR("Adieresis") +HB_STR("Agrave") +HB_STR("Aring") +HB_STR("Atilde") +HB_STR("Ccedilla") +HB_STR("Eacute") +HB_STR("Ecircumflex") +HB_STR("Edieresis") +HB_STR("Egrave") +HB_STR("Iacute") +HB_STR("Icircumflex") +HB_STR("Idieresis") +HB_STR("Igrave") +HB_STR("Ntilde") +HB_STR("Oacute") +HB_STR("Ocircumflex") +HB_STR("Odieresis") +HB_STR("Ograve") +HB_STR("Otilde") +HB_STR("Scaron") +HB_STR("Uacute") +HB_STR("Ucircumflex") +HB_STR("Udieresis") +HB_STR("Ugrave") +HB_STR("Yacute") +HB_STR("Ydieresis") +HB_STR("Zcaron") +HB_STR("aacute") +HB_STR("acircumflex") +HB_STR("adieresis") +HB_STR("agrave") +HB_STR("aring") +HB_STR("atilde") +HB_STR("ccedilla") +HB_STR("eacute") +HB_STR("ecircumflex") +HB_STR("edieresis") +HB_STR("egrave") +HB_STR("iacute") +HB_STR("icircumflex") +HB_STR("idieresis") +HB_STR("igrave") +HB_STR("ntilde") +HB_STR("oacute") +HB_STR("ocircumflex") +HB_STR("odieresis") +HB_STR("ograve") +HB_STR("otilde") +HB_STR("scaron") +HB_STR("uacute") +HB_STR("ucircumflex") +HB_STR("udieresis") +HB_STR("ugrave") +HB_STR("yacute") +HB_STR("ydieresis") +HB_STR("zcaron") +HB_STR("exclamsmall") +HB_STR("Hungarumlautsmall") +HB_STR("dollaroldstyle") +HB_STR("dollarsuperior") +HB_STR("ampersandsmall") +HB_STR("Acutesmall") +HB_STR("parenleftsuperior") +HB_STR("parenrightsuperior") +HB_STR("twodotenleader") +HB_STR("onedotenleader") +HB_STR("zerooldstyle") +HB_STR("oneoldstyle") +HB_STR("twooldstyle") +HB_STR("threeoldstyle") +HB_STR("fouroldstyle") +HB_STR("fiveoldstyle") +HB_STR("sixoldstyle") +HB_STR("sevenoldstyle") +HB_STR("eightoldstyle") +HB_STR("nineoldstyle") +HB_STR("commasuperior") +HB_STR("threequartersemdash") +HB_STR("periodsuperior") +HB_STR("questionsmall") +HB_STR("asuperior") +HB_STR("bsuperior") +HB_STR("centsuperior") +HB_STR("dsuperior") +HB_STR("esuperior") +HB_STR("isuperior") +HB_STR("lsuperior") +HB_STR("msuperior") +HB_STR("nsuperior") +HB_STR("osuperior") +HB_STR("rsuperior") +HB_STR("ssuperior") +HB_STR("tsuperior") +HB_STR("ff") +HB_STR("ffi") +HB_STR("ffl") +HB_STR("parenleftinferior") +HB_STR("parenrightinferior") +HB_STR("Circumflexsmall") +HB_STR("hyphensuperior") +HB_STR("Gravesmall") +HB_STR("Asmall") +HB_STR("Bsmall") +HB_STR("Csmall") +HB_STR("Dsmall") +HB_STR("Esmall") +HB_STR("Fsmall") +HB_STR("Gsmall") +HB_STR("Hsmall") +HB_STR("Ismall") +HB_STR("Jsmall") +HB_STR("Ksmall") +HB_STR("Lsmall") +HB_STR("Msmall") +HB_STR("Nsmall") +HB_STR("Osmall") +HB_STR("Psmall") +HB_STR("Qsmall") +HB_STR("Rsmall") +HB_STR("Ssmall") +HB_STR("Tsmall") +HB_STR("Usmall") +HB_STR("Vsmall") +HB_STR("Wsmall") +HB_STR("Xsmall") +HB_STR("Ysmall") +HB_STR("Zsmall") +HB_STR("colonmonetary") +HB_STR("onefitted") +HB_STR("rupiah") +HB_STR("Tildesmall") +HB_STR("exclamdownsmall") +HB_STR("centoldstyle") +HB_STR("Lslashsmall") +HB_STR("Scaronsmall") +HB_STR("Zcaronsmall") +HB_STR("Dieresissmall") +HB_STR("Brevesmall") +HB_STR("Caronsmall") +HB_STR("Dotaccentsmall") +HB_STR("Macronsmall") +HB_STR("figuredash") +HB_STR("hypheninferior") +HB_STR("Ogoneksmall") +HB_STR("Ringsmall") +HB_STR("Cedillasmall") +HB_STR("questiondownsmall") +HB_STR("oneeighth") +HB_STR("threeeighths") +HB_STR("fiveeighths") +HB_STR("seveneighths") +HB_STR("onethird") +HB_STR("twothirds") +HB_STR("zerosuperior") +HB_STR("foursuperior") +HB_STR("fivesuperior") +HB_STR("sixsuperior") +HB_STR("sevensuperior") +HB_STR("eightsuperior") +HB_STR("ninesuperior") +HB_STR("zeroinferior") +HB_STR("oneinferior") +HB_STR("twoinferior") +HB_STR("threeinferior") +HB_STR("fourinferior") +HB_STR("fiveinferior") +HB_STR("sixinferior") +HB_STR("seveninferior") +HB_STR("eightinferior") +HB_STR("nineinferior") +HB_STR("centinferior") +HB_STR("dollarinferior") +HB_STR("periodinferior") +HB_STR("commainferior") +HB_STR("Agravesmall") +HB_STR("Aacutesmall") +HB_STR("Acircumflexsmall") +HB_STR("Atildesmall") +HB_STR("Adieresissmall") +HB_STR("Aringsmall") +HB_STR("AEsmall") +HB_STR("Ccedillasmall") +HB_STR("Egravesmall") +HB_STR("Eacutesmall") +HB_STR("Ecircumflexsmall") +HB_STR("Edieresissmall") +HB_STR("Igravesmall") +HB_STR("Iacutesmall") +HB_STR("Icircumflexsmall") +HB_STR("Idieresissmall") +HB_STR("Ethsmall") +HB_STR("Ntildesmall") +HB_STR("Ogravesmall") +HB_STR("Oacutesmall") +HB_STR("Ocircumflexsmall") +HB_STR("Otildesmall") +HB_STR("Odieresissmall") +HB_STR("OEsmall") +HB_STR("Oslashsmall") +HB_STR("Ugravesmall") +HB_STR("Uacutesmall") +HB_STR("Ucircumflexsmall") +HB_STR("Udieresissmall") +HB_STR("Yacutesmall") +HB_STR("Thornsmall") +HB_STR("Ydieresissmall") +HB_STR("001.000") +HB_STR("001.001") +HB_STR("001.002") +HB_STR("001.003") +HB_STR("Black") +HB_STR("Bold") +HB_STR("Book") +HB_STR("Light") +HB_STR("Medium") +HB_STR("Regular") +HB_STR("Roman") +HB_STR("Semibold") #endif /* HB_OT_CFF1_STD_STR_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh index 27c4d31b9ce..778167eeb23 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh @@ -326,7 +326,7 @@ struct Charset0 void collect_glyph_to_sid_map (glyph_to_sid_map_t *mapping, unsigned int num_glyphs) const { - mapping->resize (num_glyphs, false); + mapping->resize_dirty (num_glyphs); for (hb_codepoint_t gid = 1; gid < num_glyphs; gid++) mapping->arrayZ[gid] = {sids[gid - 1], gid}; } @@ -426,7 +426,7 @@ struct Charset1_2 { void collect_glyph_to_sid_map (glyph_to_sid_map_t *mapping, unsigned int num_glyphs) const { - mapping->resize (num_glyphs, false); + mapping->resize_dirty (num_glyphs); hb_codepoint_t gid = 1; if (gid >= num_glyphs) return; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.cc index b2702106ecc..499bd942cde 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.cc @@ -202,7 +202,11 @@ struct cff2_cs_opset_path_t : cff2_cs_opset_tcoords, font->num_coords)); + return get_path_at (font, + glyph, + draw_session, + hb_array (font->coords, + font->has_nonzero_coords ? font->num_coords : 0)); } bool OT::cff2::accelerator_t::get_path_at (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session, hb_array_t coords) const diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh index 6bf37c062fc..93e9c0a2697 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh @@ -501,10 +501,6 @@ struct CmapSubtableFormat4 this->length = c->length () - table_initpos; if ((long long) this->length != (long long) c->length () - table_initpos) { - // Length overflowed. Discard the current object before setting the error condition, otherwise - // discard is a noop which prevents the higher level code from reverting the serializer to the - // pre-error state in cmap4 overflow handling code. - c->pop_discard (); c->err (HB_SERIALIZE_ERROR_INT_OVERFLOW); return; } @@ -701,16 +697,7 @@ struct CmapSubtableFormat4 hb_barrier (); if (unlikely (!c->check_range (this, length))) - { - /* Some broken fonts have too long of a "length" value. - * If that is the case, just change the value to truncate - * the subtable at the end of the blob. */ - uint16_t new_length = (uint16_t) hb_min ((uintptr_t) 65535, - (uintptr_t) (c->end - - (char *) this)); - if (!c->try_set (&length, new_length)) - return_trace (false); - } + return_trace (false); return_trace (16 + 4 * (unsigned int) segCountX2 <= length); } @@ -1500,7 +1487,7 @@ struct CmapSubtable bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const { - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); return u.format0 .get_glyph (codepoint, glyph); case 4: hb_barrier (); return u.format4 .get_glyph (codepoint, glyph); case 6: hb_barrier (); return u.format6 .get_glyph (codepoint, glyph); @@ -1513,7 +1500,7 @@ struct CmapSubtable } void collect_unicodes (hb_set_t *out, unsigned int num_glyphs = UINT_MAX) const { - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); u.format0 .collect_unicodes (out); return; case 4: hb_barrier (); u.format4 .collect_unicodes (out); return; case 6: hb_barrier (); u.format6 .collect_unicodes (out); return; @@ -1529,7 +1516,7 @@ struct CmapSubtable hb_map_t *mapping, /* OUT */ unsigned num_glyphs = UINT_MAX) const { - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); u.format0 .collect_mapping (unicodes, mapping); return; case 4: hb_barrier (); u.format4 .collect_mapping (unicodes, mapping); return; case 6: hb_barrier (); u.format6 .collect_mapping (unicodes, mapping); return; @@ -1543,7 +1530,7 @@ struct CmapSubtable unsigned get_language () const { - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); return u.format0 .get_language (); case 4: hb_barrier (); return u.format4 .get_language (); case 6: hb_barrier (); return u.format6 .get_language (); @@ -1574,9 +1561,9 @@ struct CmapSubtable bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return_trace (false); + if (!u.format.v.sanitize (c)) return_trace (false); hb_barrier (); - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); return_trace (u.format0 .sanitize (c)); case 4: hb_barrier (); return_trace (u.format4 .sanitize (c)); case 6: hb_barrier (); return_trace (u.format6 .sanitize (c)); @@ -1590,7 +1577,7 @@ struct CmapSubtable public: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ CmapSubtableFormat0 format0; CmapSubtableFormat4 format4; CmapSubtableFormat6 format6; @@ -1600,7 +1587,7 @@ struct CmapSubtable CmapSubtableFormat14 format14; } u; public: - DEFINE_SIZE_UNION (2, format); + DEFINE_SIZE_UNION (2, format.v); }; @@ -1646,7 +1633,7 @@ struct EncodingRecord CmapSubtable *cmapsubtable = c->push (); unsigned origin_length = c->length (); cmapsubtable->serialize (c, it, format, plan, &(base+subtable)); - if (c->length () - origin_length > 0) *objidx = c->pop_pack (); + if (c->length () - origin_length > 0 && !c->in_error()) *objidx = c->pop_pack (); else c->pop_discard (); } @@ -1683,6 +1670,10 @@ struct SubtableUnicodesCache { { SubtableUnicodesCache* cache = (SubtableUnicodesCache*) hb_malloc (sizeof(SubtableUnicodesCache)); + + if (unlikely (!cache)) + return nullptr; + new (cache) SubtableUnicodesCache (source_table); return cache; } @@ -1776,6 +1767,10 @@ struct cmap ; SubtableUnicodesCache* cache = SubtableUnicodesCache::create(source_table); + + if (unlikely (!cache)) + return nullptr; + for (const EncodingRecord& _ : it) cache->set_for(&_); // populate the cache for this encoding record. @@ -1810,7 +1805,7 @@ struct cmap if (c->in_error ()) return false; - unsigned format = (base+_.subtable).u.format; + unsigned format = (base+_.subtable).u.format.v; if (format != 4 && format != 12 && format != 14) continue; const hb_set_t* unicodes_set = unicodes_cache->set_for (&_, local_unicodes_cache); @@ -1912,7 +1907,7 @@ struct cmap + hb_iter (encodingRecord) | hb_map (&EncodingRecord::subtable) | hb_map (hb_add (this)) - | hb_filter ([&] (const CmapSubtable& _) { return _.u.format == 14; }) + | hb_filter ([&] (const CmapSubtable& _) { return _.u.format.v == 14; }) | hb_apply ([=] (const CmapSubtable& _) { _.u.format14.closure_glyphs (unicodes, glyphset); }) ; } @@ -1937,7 +1932,7 @@ struct cmap for (const EncodingRecord& _ : encodingrec_iter) { - unsigned format = (this + _.subtable).u.format; + unsigned format = (this + _.subtable).u.format.v; if (format == 12) has_format12 = true; const EncodingRecord *table = std::addressof (_); @@ -2025,7 +2020,7 @@ struct cmap this->subtable_uvs = &Null (CmapSubtableFormat14); { const CmapSubtable *st = table->find_subtable (0, 5); - if (st && st->u.format == 14) + if (st && st->u.format.v == 14) subtable_uvs = &st->u.format14; } @@ -2069,7 +2064,7 @@ struct cmap else #endif { - switch (subtable->u.format) { + switch (subtable->u.format.v) { /* Accelerate format 4 and format 12. */ default: this->get_glyph_funcZ = get_glyph_from; @@ -2276,7 +2271,7 @@ struct cmap (_.platformID == 0 && _.encodingID == 4) || (_.platformID == 3 && _.encodingID == 1) || (_.platformID == 3 && _.encodingID == 10) || - (cmap + _.subtable).u.format == 14; + (cmap + _.subtable).u.format.v == 14; } protected: diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc index 0238bb346a9..8add9209f37 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc @@ -37,6 +37,7 @@ #include "hb-ot-cmap-table.hh" #include "hb-ot-glyf-table.hh" +#include "hb-ot-var-gvar-table.hh" #include "hb-ot-cff2-table.hh" #include "hb-ot-cff1-table.hh" #include "hb-ot-hmtx-table.hh" @@ -64,18 +65,22 @@ using hb_ot_font_advance_cache_t = hb_cache_t<24, 16>; static_assert (sizeof (hb_ot_font_advance_cache_t) == 1024, ""); +using hb_ot_font_origin_cache_t = hb_cache_t<20, 20>; +static_assert (sizeof (hb_ot_font_origin_cache_t) == 1024, ""); + struct hb_ot_font_t { const hb_ot_face_t *ot_face; - /* h_advance caching */ + mutable hb_atomic_t cached_serial; mutable hb_atomic_t cached_coords_serial; - struct advance_cache_t + + struct direction_cache_t { mutable hb_atomic_t advance_cache; - mutable hb_atomic_t varStore_cache; + mutable hb_atomic_t varStore_cache; - ~advance_cache_t () + ~direction_cache_t () { clear (); } @@ -116,7 +121,7 @@ struct hb_ot_font_t goto retry; } - OT::ItemVariationStore::cache_t *acquire_varStore_cache (const OT::ItemVariationStore &varStore) const + OT::hb_scalar_cache_t *acquire_varStore_cache (const OT::ItemVariationStore &varStore) const { retry: auto *cache = varStore_cache.get_acquire (); @@ -127,7 +132,7 @@ struct hb_ot_font_t else goto retry; } - void release_varStore_cache (OT::ItemVariationStore::cache_t *cache) const + void release_varStore_cache (OT::hb_scalar_cache_t *cache) const { if (!cache) return; @@ -154,17 +159,157 @@ struct hb_ot_font_t } h, v; + struct origin_cache_t + { + mutable hb_atomic_t origin_cache; + mutable hb_atomic_t varStore_cache; + + ~origin_cache_t () + { + clear (); + } + + hb_ot_font_origin_cache_t *acquire_origin_cache () const + { + retry: + auto *cache = origin_cache.get_acquire (); + if (!cache) + { + cache = (hb_ot_font_origin_cache_t *) hb_malloc (sizeof (hb_ot_font_origin_cache_t)); + if (!cache) + return nullptr; + new (cache) hb_ot_font_origin_cache_t; + return cache; + } + if (origin_cache.cmpexch (cache, nullptr)) + return cache; + else + goto retry; + } + void release_origin_cache (hb_ot_font_origin_cache_t *cache) const + { + if (!cache) + return; + if (!origin_cache.cmpexch (nullptr, cache)) + hb_free (cache); + } + void clear_origin_cache () const + { + retry: + auto *cache = origin_cache.get_acquire (); + if (!cache) + return; + if (origin_cache.cmpexch (cache, nullptr)) + hb_free (cache); + else + goto retry; + } + + OT::hb_scalar_cache_t *acquire_varStore_cache (const OT::ItemVariationStore &varStore) const + { + retry: + auto *cache = varStore_cache.get_acquire (); + if (!cache) + return varStore.create_cache (); + if (varStore_cache.cmpexch (cache, nullptr)) + return cache; + else + goto retry; + } + void release_varStore_cache (OT::hb_scalar_cache_t *cache) const + { + if (!cache) + return; + if (!varStore_cache.cmpexch (nullptr, cache)) + OT::ItemVariationStore::destroy_cache (cache); + } + void clear_varStore_cache () const + { + retry: + auto *cache = varStore_cache.get_acquire (); + if (!cache) + return; + if (varStore_cache.cmpexch (cache, nullptr)) + OT::ItemVariationStore::destroy_cache (cache); + else + goto retry; + } + + void clear () const + { + clear_origin_cache (); + clear_varStore_cache (); + } + } v_origin; + + struct draw_cache_t + { + mutable hb_atomic_t gvar_cache; + + ~draw_cache_t () + { + clear (); + } + + OT::hb_scalar_cache_t *acquire_gvar_cache (const OT::gvar_accelerator_t &gvar) const + { + retry: + auto *cache = gvar_cache.get_acquire (); + if (!cache) + return gvar.create_cache (); + if (gvar_cache.cmpexch (cache, nullptr)) + return cache; + else + goto retry; + } + void release_gvar_cache (OT::hb_scalar_cache_t *cache) const + { + if (!cache) + return; + if (!gvar_cache.cmpexch (nullptr, cache)) + OT::gvar_accelerator_t::destroy_cache (cache); + } + void clear_gvar_cache () const + { + retry: + auto *cache = gvar_cache.get_acquire (); + if (!cache) + return; + if (gvar_cache.cmpexch (cache, nullptr)) + OT::gvar_accelerator_t::destroy_cache (cache); + else + goto retry; + } + + void clear () const + { + clear_gvar_cache (); + } + } draw; + void check_serial (hb_font_t *font) const { int font_serial = font->serial_coords.get_acquire (); + if (cached_serial.get_acquire () != font_serial) + { + /* These caches are dependent on scale and synthetic settings. + * Any change to the font invalidates them. */ + v_origin.clear (); - if (cached_coords_serial.get_acquire () == font_serial) - return; + cached_serial.set_release (font_serial); + } - h.clear (); - v.clear (); + int font_serial_coords = font->serial_coords.get_acquire (); + if (cached_coords_serial.get_acquire () != font_serial_coords) + { + /* These caches are independent of scale or synthetic settings. + * Just variation changes will invalidate them. */ + h.clear (); + v.clear (); + draw.clear (); - cached_coords_serial.set_release (font_serial); + cached_coords_serial.set_release (font_serial_coords); + } } }; @@ -242,37 +387,59 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, unsigned advance_stride, void *user_data HB_UNUSED) { + // Duplicated in v_advances. Ugly. Keep in sync'ish. const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; const hb_ot_face_t *ot_face = ot_font->ot_face; const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx; - ot_font->check_serial (font); - const OT::HVAR &HVAR = *hmtx.var_table; - const OT::ItemVariationStore &varStore = &HVAR + HVAR.varStore; - OT::ItemVariationStore::cache_t *varStore_cache = ot_font->h.acquire_varStore_cache (varStore); - - hb_ot_font_advance_cache_t *advance_cache = nullptr; - - bool use_cache = font->num_coords; - if (use_cache) - { - advance_cache = ot_font->h.acquire_advance_cache (); - if (!advance_cache) - use_cache = false; - } - - if (!use_cache) + if (unlikely (!hmtx.has_data ())) { + hb_position_t advance = font->face->get_upem () / 2; + advance = font->em_scale_x (advance); for (unsigned int i = 0; i < count; i++) { - *first_advance = font->em_scale_x (hmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache)); + *first_advance = advance; + first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); + } + return; + } + +#ifndef HB_NO_VAR + if (!font->has_nonzero_coords) + { + fallback: +#else + { +#endif + // Just plain htmx data. No need to cache. + for (unsigned int i = 0; i < count; i++) + { + *first_advance = font->em_scale_x (hmtx.get_advance_without_var_unscaled (*first_glyph)); first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } + return; } - else - { /* Use cache. */ + +#ifndef HB_NO_VAR + /* has_nonzero_coords. */ + + ot_font->check_serial (font); + hb_ot_font_advance_cache_t *advance_cache = ot_font->h.acquire_advance_cache (); + if (!advance_cache) + { + // malloc failure. Just use the fallback non-variable path. + goto fallback; + } + + /* If HVAR is present, use it.*/ + const OT::HVAR &HVAR = *hmtx.var_table; + if (HVAR.has_data ()) + { + const OT::ItemVariationStore &varStore = &HVAR + HVAR.varStore; + OT::hb_scalar_cache_t *varStore_cache = ot_font->h.acquire_varStore_cache (varStore); + for (unsigned int i = 0; i < count; i++) { hb_position_t v; @@ -289,10 +456,49 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } + ot_font->h.release_varStore_cache (varStore_cache); ot_font->h.release_advance_cache (advance_cache); + return; } - ot_font->h.release_varStore_cache (varStore_cache); + const auto &gvar = *ot_face->gvar; + if (gvar.has_data ()) + { + const auto &glyf = *ot_face->glyf; + auto *scratch = glyf.acquire_scratch (); + if (unlikely (!scratch)) + { + ot_font->h.release_advance_cache (advance_cache); + goto fallback; + } + OT::hb_scalar_cache_t *gvar_cache = ot_font->draw.acquire_gvar_cache (gvar); + + for (unsigned int i = 0; i < count; i++) + { + hb_position_t v; + unsigned cv; + if (advance_cache->get (*first_glyph, &cv)) + v = cv; + else + { + v = glyf.get_advance_with_var_unscaled (*first_glyph, font, false, *scratch, gvar_cache); + advance_cache->set (*first_glyph, v); + } + *first_advance = font->em_scale_x (v); + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); + } + + ot_font->draw.release_gvar_cache (gvar_cache); + glyf.release_scratch (scratch); + ot_font->h.release_advance_cache (advance_cache); + return; + } + + ot_font->h.release_advance_cache (advance_cache); + // No HVAR or GVAR. Just use the fallback non-variable path. + goto fallback; +#endif } #ifndef HB_NO_VERTICAL @@ -305,99 +511,290 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, unsigned advance_stride, void *user_data HB_UNUSED) { + // Duplicated from h_advances. Ugly. Keep in sync'ish. + const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; const hb_ot_face_t *ot_face = ot_font->ot_face; const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; - if (vmtx.has_data ()) + if (unlikely (!vmtx.has_data ())) + { + hb_font_extents_t font_extents; + font->get_h_extents_with_fallback (&font_extents); + hb_position_t advance = font_extents.descender - font_extents.ascender; + for (unsigned int i = 0; i < count; i++) + { + *first_advance = advance; + first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); + } + return; + } + +#ifndef HB_NO_VAR + if (!font->has_nonzero_coords) + { + fallback: +#else + { +#endif + // Just plain vtmx data. No need to cache. + for (unsigned int i = 0; i < count; i++) + { + *first_advance = font->em_scale_y (- (int) vmtx.get_advance_without_var_unscaled (*first_glyph)); + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); + } + return; + } + +#ifndef HB_NO_VAR + /* has_nonzero_coords. */ + + ot_font->check_serial (font); + hb_ot_font_advance_cache_t *advance_cache = ot_font->v.acquire_advance_cache (); + if (!advance_cache) + { + // malloc failure. Just use the fallback non-variable path. + goto fallback; + } + + /* If VVAR is present, use it.*/ + const OT::VVAR &VVAR = *vmtx.var_table; + if (VVAR.has_data ()) { - ot_font->check_serial (font); - const OT::VVAR &VVAR = *vmtx.var_table; const OT::ItemVariationStore &varStore = &VVAR + VVAR.varStore; - OT::ItemVariationStore::cache_t *varStore_cache = ot_font->v.acquire_varStore_cache (varStore); - // TODO Use advance_cache. + OT::hb_scalar_cache_t *varStore_cache = ot_font->v.acquire_varStore_cache (varStore); for (unsigned int i = 0; i < count; i++) { - *first_advance = font->em_scale_y (-(int) vmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache)); + hb_position_t v; + unsigned cv; + if (advance_cache->get (*first_glyph, &cv)) + v = cv; + else + { + v = vmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache); + advance_cache->set (*first_glyph, v); + } + *first_advance = font->em_scale_y (- (int) v); first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } ot_font->v.release_varStore_cache (varStore_cache); + ot_font->v.release_advance_cache (advance_cache); + return; } - else + + const auto &gvar = *ot_face->gvar; + if (gvar.has_data ()) { - hb_font_extents_t font_extents; - font->get_h_extents_with_fallback (&font_extents); - hb_position_t advance = -(font_extents.ascender - font_extents.descender); + const auto &glyf = *ot_face->glyf; + auto *scratch = glyf.acquire_scratch (); + if (unlikely (!scratch)) + { + ot_font->v.release_advance_cache (advance_cache); + goto fallback; + } + OT::hb_scalar_cache_t *gvar_cache = ot_font->draw.acquire_gvar_cache (gvar); for (unsigned int i = 0; i < count; i++) { - *first_advance = advance; + hb_position_t v; + unsigned cv; + if (advance_cache->get (*first_glyph, &cv)) + v = cv; + else + { + v = glyf.get_advance_with_var_unscaled (*first_glyph, font, true, *scratch, gvar_cache); + advance_cache->set (*first_glyph, v); + } + *first_advance = font->em_scale_y (- (int) v); first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } + + ot_font->draw.release_gvar_cache (gvar_cache); + glyf.release_scratch (scratch); + ot_font->v.release_advance_cache (advance_cache); + return; } + + ot_font->v.release_advance_cache (advance_cache); + // No VVAR or GVAR. Just use the fallback non-variable path. + goto fallback; +#endif } #endif #ifndef HB_NO_VERTICAL +HB_HOT static hb_bool_t -hb_ot_get_glyph_v_origin (hb_font_t *font, - void *font_data, - hb_codepoint_t glyph, - hb_position_t *x, - hb_position_t *y, - void *user_data HB_UNUSED) +hb_ot_get_glyph_v_origins (hb_font_t *font, + void *font_data, + unsigned int count, + const hb_codepoint_t *first_glyph, + unsigned glyph_stride, + hb_position_t *first_x, + unsigned x_stride, + hb_position_t *first_y, + unsigned y_stride, + void *user_data HB_UNUSED) { const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; const hb_ot_face_t *ot_face = ot_font->ot_face; - *x = font->get_glyph_h_advance (glyph) / 2; - - const OT::VORG &VORG = *ot_face->VORG; - if (VORG.has_data ()) + /* First, set all the x values to half the advance width. */ + font->get_glyph_h_advances (count, + first_glyph, glyph_stride, + first_x, x_stride); + for (unsigned i = 0; i < count; i++) { - float delta = 0; + *first_x /= 2; + first_x = &StructAtOffsetUnaligned (first_x, x_stride); + } + /* The vertical origin business is messy... + * + * We allocate the cache, then have various code paths that use the cache. + * Each one is responsible to free it before returning. + */ + hb_ot_font_origin_cache_t *origin_cache = ot_font->v_origin.acquire_origin_cache (); + + /* If there is VORG, always use it. It uses VVAR for variations if necessary. */ + const OT::VORG &VORG = *ot_face->VORG; + if (origin_cache && VORG.has_data ()) + { #ifndef HB_NO_VAR - const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; - const OT::VVAR &VVAR = *vmtx.var_table; - if (font->num_coords) - VVAR.get_vorg_delta_unscaled (glyph, - font->coords, font->num_coords, - &delta); + if (!font->has_nonzero_coords) #endif + { + for (unsigned i = 0; i < count; i++) + { + hb_position_t origin; + unsigned cv; + if (origin_cache->get (*first_glyph, &cv)) + origin = font->y_scale < 0 ? -static_cast(cv) : static_cast(cv); + else + { + origin = font->em_scalef_y (VORG.get_y_origin (*first_glyph)); + origin_cache->set (*first_glyph, font->y_scale < 0 ? -origin : origin); + } - *y = font->em_scalef_y (VORG.get_y_origin (glyph) + delta); + *first_y = origin; + + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); + } + } +#ifndef HB_NO_VAR + else + { + const OT::VVAR &VVAR = *ot_face->vmtx->var_table; + const auto &varStore = &VVAR + VVAR.varStore; + auto *varStore_cache = ot_font->v_origin.acquire_varStore_cache (varStore); + for (unsigned i = 0; i < count; i++) + { + hb_position_t origin; + unsigned cv; + if (origin_cache->get (*first_glyph, &cv)) + origin = font->y_scale < 0 ? -static_cast(cv) : static_cast(cv); + else + { + origin = font->em_scalef_y (VORG.get_y_origin (*first_glyph) + + VVAR.get_vorg_delta_unscaled (*first_glyph, + font->coords, font->num_coords, + varStore_cache)); + origin_cache->set (*first_glyph, font->y_scale < 0 ? -origin : origin); + } + + *first_y = origin; + + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); + } + ot_font->v_origin.release_varStore_cache (varStore_cache); + } +#endif + ot_font->v_origin.release_origin_cache (origin_cache); return true; } - hb_glyph_extents_t extents = {0}; - - if (hb_font_get_glyph_extents (font, glyph, &extents)) + /* If and only if `vmtx` is present and it's a `glyf` font, + * we use the top phantom point, deduced from vmtx,glyf[,gvar]. */ + const auto &vmtx = *ot_face->vmtx; + const auto &glyf = *ot_face->glyf; + if (origin_cache && vmtx.has_data() && glyf.has_data ()) { - const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; - int tsb = 0; - if (vmtx.get_leading_bearing_with_var_unscaled (font, glyph, &tsb)) + auto *scratch = glyf.acquire_scratch (); + if (unlikely (!scratch)) { - *y = extents.y_bearing + font->em_scale_y (tsb); - return true; + ot_font->v_origin.release_origin_cache (origin_cache); + return false; + } + OT::hb_scalar_cache_t *gvar_cache = font->has_nonzero_coords ? + ot_font->draw.acquire_gvar_cache (*ot_face->gvar) : + nullptr; + + for (unsigned i = 0; i < count; i++) + { + hb_position_t origin; + unsigned cv; + if (origin_cache->get (*first_glyph, &cv)) + origin = font->y_scale < 0 ? -static_cast(cv) : static_cast(cv); + else + { + origin = font->em_scalef_y (glyf.get_v_origin_with_var_unscaled (*first_glyph, font, *scratch, gvar_cache)); + origin_cache->set (*first_glyph, font->y_scale < 0 ? -origin : origin); + } + + *first_y = origin; + + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); } - hb_font_extents_t font_extents; - font->get_h_extents_with_fallback (&font_extents); - hb_position_t advance = font_extents.ascender - font_extents.descender; - hb_position_t diff = advance - -extents.height; - *y = extents.y_bearing + (diff >> 1); + if (gvar_cache) + ot_font->draw.release_gvar_cache (gvar_cache); + glyf.release_scratch (scratch); + ot_font->v_origin.release_origin_cache (origin_cache); return true; } - hb_font_extents_t font_extents; - font->get_h_extents_with_fallback (&font_extents); - *y = font_extents.ascender; + /* Otherwise, use glyph extents to center the glyph vertically. + * If getting glyph extents failed, just use the font ascender. */ + if (origin_cache && font->has_glyph_extents_func ()) + { + hb_font_extents_t font_extents; + font->get_h_extents_with_fallback (&font_extents); + hb_position_t font_advance = font_extents.ascender - font_extents.descender; + for (unsigned i = 0; i < count; i++) + { + hb_position_t origin; + unsigned cv; + + if (origin_cache->get (*first_glyph, &cv)) + origin = font->y_scale < 0 ? -static_cast(cv) : static_cast(cv); + else + { + hb_glyph_extents_t extents = {0}; + if (likely (font->get_glyph_extents (*first_glyph, &extents))) + origin = extents.y_bearing + ((font_advance - -extents.height) >> 1); + else + origin = font_extents.ascender; + + origin_cache->set (*first_glyph, font->y_scale < 0 ? -origin : origin); + } + + *first_y = origin; + + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); + } + } + + ot_font->v_origin.release_origin_cache (origin_cache); return true; } #endif @@ -498,17 +895,33 @@ hb_ot_draw_glyph_or_fail (hb_font_t *font, hb_draw_funcs_t *draw_funcs, void *draw_data, void *user_data) { + const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; hb_draw_session_t draw_session {draw_funcs, draw_data}; + bool ret = false; + + OT::hb_scalar_cache_t *gvar_cache = nullptr; + if (font->num_coords) + { + ot_font->check_serial (font); + gvar_cache = ot_font->draw.acquire_gvar_cache (*ot_font->ot_face->gvar); + } + #ifndef HB_NO_VAR_COMPOSITES - if (font->face->table.VARC->get_path (font, glyph, draw_session)) return true; + if (font->face->table.VARC->get_path (font, glyph, draw_session)) { ret = true; goto done; } #endif // Keep the following in synch with VARC::get_path_at() - if (font->face->table.glyf->get_path (font, glyph, draw_session)) return true; + if (font->face->table.glyf->get_path (font, glyph, draw_session, gvar_cache)) { ret = true; goto done; } + #ifndef HB_NO_CFF - if (font->face->table.cff2->get_path (font, glyph, draw_session)) return true; - if (font->face->table.cff1->get_path (font, glyph, draw_session)) return true; + if (font->face->table.cff2->get_path (font, glyph, draw_session)) { ret = true; goto done; } + if (font->face->table.cff1->get_path (font, glyph, draw_session)) { ret = true; goto done; } #endif - return false; + +done: + + ot_font->draw.release_gvar_cache (gvar_cache); + + return ret; } #endif @@ -548,12 +961,11 @@ static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_tplan->new_to_old_gid_list) - | hb_map ([c, &_mtx, mtx_map] (hb_codepoint_pair_t _) + | hb_map ([&_mtx, mtx_map] (hb_codepoint_pair_t _) { hb_codepoint_t new_gid = _.first; hb_codepoint_t old_gid = _.second; @@ -246,8 +236,7 @@ struct hmtxvmtx if (!mtx_map->has (new_gid, &v)) { int lsb = 0; - if (!_mtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb)) - (void) _glyf_get_leading_bearing_without_var_unscaled (c->plan->source, old_gid, !T::is_horizontal, &lsb); + _mtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb); return hb_pair (_mtx.get_advance_without_var_unscaled (old_gid), +lsb); } return *v; @@ -326,49 +315,23 @@ struct hmtxvmtx bool has_data () const { return (bool) num_bearings; } - bool get_leading_bearing_without_var_unscaled (hb_codepoint_t glyph, + void get_leading_bearing_without_var_unscaled (hb_codepoint_t glyph, int *lsb) const { if (glyph < num_long_metrics) { *lsb = table->longMetricZ[glyph].sb; - return true; + return; } if (unlikely (glyph >= num_bearings)) - return false; + { + *lsb = 0; + return; + } const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_long_metrics]; *lsb = bearings[glyph - num_long_metrics]; - return true; - } - - bool get_leading_bearing_with_var_unscaled (hb_font_t *font, - hb_codepoint_t glyph, - int *lsb) const - { - if (!font->num_coords) - return get_leading_bearing_without_var_unscaled (glyph, lsb); - -#ifndef HB_NO_VAR - float delta; - if (var_table->get_lsb_delta_unscaled (glyph, font->coords, font->num_coords, &delta) && - get_leading_bearing_without_var_unscaled (glyph, lsb)) - { - *lsb += roundf (delta); - return true; - } - - // If there's no vmtx data, the phantom points from glyf table are not accurate, - // so we cannot take the next path. - bool is_vertical = T::tableTag == HB_OT_TAG_vmtx; - if (is_vertical && !has_data ()) - return false; - - return _glyf_get_leading_bearing_with_var_unscaled (font, glyph, is_vertical, lsb); -#else - return false; -#endif } unsigned int get_advance_without_var_unscaled (hb_codepoint_t glyph) const @@ -402,27 +365,17 @@ struct hmtxvmtx return advances[hb_min (glyph - num_bearings, num_advances - num_bearings - 1)]; } - unsigned get_advance_with_var_unscaled (hb_codepoint_t glyph, - hb_font_t *font, - ItemVariationStore::cache_t *store_cache = nullptr) const +#ifndef HB_NO_VAR + unsigned get_advance_with_var_unscaled (hb_codepoint_t glyph, + hb_font_t *font, + hb_scalar_cache_t *store_cache = nullptr) const { unsigned int advance = get_advance_without_var_unscaled (glyph); - -#ifndef HB_NO_VAR - if (unlikely (glyph >= num_bearings) || !font->num_coords) - return advance; - - if (var_table.get_length ()) - return advance + roundf (var_table->get_advance_delta_unscaled (glyph, - font->coords, font->num_coords, - store_cache)); - - unsigned glyf_advance = _glyf_get_advance_with_var_unscaled (font, glyph, T::tableTag == HB_OT_TAG_vmtx); - return glyf_advance ? glyf_advance : advance; -#else - return advance; -#endif + return hb_max(0.0f, advance + roundf (var_table->get_advance_delta_unscaled (glyph, + font->coords, font->num_coords, + store_cache))); } +#endif protected: // 0 <= num_long_metrics <= num_bearings <= num_advances <= num_glyphs diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-kern-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-kern-table.hh index 97d012e58b8..42326adcad2 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-kern-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-kern-table.hh @@ -90,11 +90,11 @@ struct KernSubTableFormat3 template void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const { - set_t set; if (likely (glyphCount)) - set.add_range (0, glyphCount - 1); - left_set.union_ (set); - right_set.union_ (set); + { + left_set.add_range (0, num_glyphs - 1); + right_set.add_range (0, num_glyphs - 1); + } } protected: @@ -306,8 +306,8 @@ struct kern { static constexpr hb_tag_t tableTag = HB_OT_TAG_kern; - bool has_data () const { return u.version32; } - unsigned get_type () const { return u.major; } + bool has_data () const { return u.version32.v; } + unsigned get_type () const { return u.major.v; } bool has_state_machine () const { @@ -363,7 +363,7 @@ struct kern bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.version32.sanitize (c)) return_trace (false); + if (!u.version32.v.sanitize (c)) return_trace (false); hb_barrier (); return_trace (dispatch (c)); } @@ -406,15 +406,15 @@ struct kern protected: union { - HBUINT32 version32; - HBUINT16 major; + struct { HBUINT32 v; } version32; + struct { HBUINT16 v; } major; KernOT ot; #ifndef HB_NO_AAT_SHAPE KernAAT aat; #endif } u; public: - DEFINE_SIZE_UNION (4, version32); + DEFINE_SIZE_UNION (4, version32.v); }; struct kern_accelerator_t : kern::accelerator_t { diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh index 04a79a93a89..b9baaca2a23 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh @@ -165,13 +165,13 @@ struct BaseCoordFormat3 struct BaseCoord { - bool has_data () const { return u.format; } + bool has_data () const { return u.format.v; } hb_position_t get_coord (hb_font_t *font, const ItemVariationStore &var_store, hb_direction_t direction) const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.get_coord (font, direction); case 2: hb_barrier (); return u.format2.get_coord (font, direction); case 3: hb_barrier (); return u.format3.get_coord (font, var_store, direction); @@ -181,7 +181,7 @@ struct BaseCoord void collect_variation_indices (hb_set_t& varidx_set /* OUT */) const { - switch (u.format) { + switch (u.format.v) { case 3: hb_barrier (); u.format3.collect_variation_indices (varidx_set); return; default:return; } @@ -190,9 +190,9 @@ struct BaseCoord template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward (ds)...)); case 2: hb_barrier (); return_trace (c->dispatch (u.format2, std::forward (ds)...)); case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward (ds)...)); @@ -203,9 +203,9 @@ struct BaseCoord bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!u.format.sanitize (c))) return_trace (false); + if (unlikely (!u.format.v.sanitize (c))) return_trace (false); hb_barrier (); - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return_trace (u.format1.sanitize (c)); case 2: hb_barrier (); return_trace (u.format2.sanitize (c)); case 3: hb_barrier (); return_trace (u.format3.sanitize (c)); @@ -215,13 +215,13 @@ struct BaseCoord protected: union { - HBUINT16 format; + struct { HBUINT16 v; } format; BaseCoordFormat1 format1; BaseCoordFormat2 format2; BaseCoordFormat3 format3; } u; public: - DEFINE_SIZE_UNION (2, format); + DEFINE_SIZE_UNION (2, format.v); }; struct FeatMinMaxRecord diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh index 7ee34185575..dcacc9cb86c 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh @@ -141,6 +141,7 @@ struct hb_subset_layout_context_t : const hb_map_t *lookup_index_map; const hb_hashmap_t> *script_langsys_map; const hb_map_t *feature_index_map; + const hb_map_t *feature_map_w_duplicates; const hb_hashmap_t *feature_substitutes_map; hb_hashmap_t> *feature_record_cond_idx_map; const hb_set_t *catch_all_record_feature_idxes; @@ -165,6 +166,7 @@ struct hb_subset_layout_context_t : lookup_index_map = &c_->plan->gsub_lookups; script_langsys_map = &c_->plan->gsub_langsys; feature_index_map = &c_->plan->gsub_features; + feature_map_w_duplicates = &c_->plan->gsub_features_w_duplicates; feature_substitutes_map = &c_->plan->gsub_feature_substitutes_map; feature_record_cond_idx_map = c_->plan->user_axes_location.is_empty () ? nullptr : &c_->plan->gsub_feature_record_cond_idx_map; catch_all_record_feature_idxes = &c_->plan->gsub_old_features; @@ -175,6 +177,7 @@ struct hb_subset_layout_context_t : lookup_index_map = &c_->plan->gpos_lookups; script_langsys_map = &c_->plan->gpos_langsys; feature_index_map = &c_->plan->gpos_features; + feature_map_w_duplicates = &c_->plan->gpos_features_w_duplicates; feature_substitutes_map = &c_->plan->gpos_feature_substitutes_map; feature_record_cond_idx_map = c_->plan->user_axes_location.is_empty () ? nullptr : &c_->plan->gpos_feature_record_cond_idx_map; catch_all_record_feature_idxes = &c_->plan->gpos_old_features; @@ -825,46 +828,9 @@ struct Feature const Record_sanitize_closure_t *closure = nullptr) const { TRACE_SANITIZE (this); - if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c)))) - return_trace (false); - hb_barrier (); - - /* Some earlier versions of Adobe tools calculated the offset of the - * FeatureParams subtable from the beginning of the FeatureList table! - * - * If sanitizing "failed" for the FeatureParams subtable, try it with the - * alternative location. We would know sanitize "failed" if old value - * of the offset was non-zero, but it's zeroed now. - * - * Only do this for the 'size' feature, since at the time of the faulty - * Adobe tools, only the 'size' feature had FeatureParams defined. - */ - - if (likely (featureParams.is_null ())) - return_trace (true); - - unsigned int orig_offset = featureParams; - if (unlikely (!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE))) - return_trace (false); - hb_barrier (); - - if (featureParams == 0 && closure && - closure->tag == HB_TAG ('s','i','z','e') && - closure->list_base && closure->list_base < this) - { - unsigned int new_offset_int = orig_offset - - (((char *) this) - ((char *) closure->list_base)); - - Offset16To new_offset; - /* Check that it would not overflow. */ - new_offset = new_offset_int; - if (new_offset == new_offset_int && - c->try_set (&featureParams, new_offset_int) && - !featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE)) - return_trace (false); - } - - return_trace (true); + return_trace (c->check_struct (this) && + featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE) && + lookupIndex.sanitize (c)); } Offset16To @@ -1082,15 +1048,15 @@ struct LangSys if (unlikely (!c->serializer->extend_min (out))) return_trace (false); const uint32_t *v; - out->reqFeatureIndex = l->feature_index_map->has (reqFeatureIndex, &v) ? *v : 0xFFFFu; + out->reqFeatureIndex = l->feature_map_w_duplicates->has (reqFeatureIndex, &v) ? *v : 0xFFFFu; if (!l->visitFeatureIndex (featureIndex.len)) return_trace (false); auto it = + hb_iter (featureIndex) - | hb_filter (l->feature_index_map) - | hb_map (l->feature_index_map) + | hb_filter (l->feature_map_w_duplicates) + | hb_map (l->feature_map_w_duplicates) ; bool ret = bool (it); @@ -1337,7 +1303,7 @@ struct Lookup TRACE_DISPATCH (this, lookup_type); unsigned int count = get_subtable_count (); for (unsigned int i = 0; i < count; i++) { - typename context_t::return_t r = get_subtable (i).dispatch (c, lookup_type, std::forward (ds)...); + typename context_t::return_t r = get_subtable (i).dispatch (c, lookup_type, ds...); if (c->stop_sublookup_iteration (r)) return_trace (r); } @@ -1387,6 +1353,11 @@ struct Lookup { unsigned new_flag = lookupFlag; new_flag &= ~LookupFlag::UseMarkFilteringSet; + // https://github.com/harfbuzz/harfbuzz/issues/5499 + // If we remove UseMarkFilteringSet flag because the set is now empty, + // we need to add IgnoreMarks flag, otherwise the lookup will not + // ignore any marks, which changes the behavior. + new_flag |= LookupFlag::IgnoreMarks; out->lookupFlag = new_flag; } else @@ -1425,7 +1396,7 @@ struct Lookup if (unlikely (!get_subtables ().sanitize (c, this, get_type ()))) return_trace (false); - if (unlikely (get_type () == TSubTable::Extension && !c->get_edit_count ())) + if (unlikely (get_type () == TSubTable::Extension)) { hb_barrier (); @@ -1433,11 +1404,6 @@ struct Lookup * have the same type, which shall not be the Extension type * itself (but we already checked for that). * This is specially important if one has a reverse type! - * - * We only do this if sanitizer edit_count is zero. Otherwise, - * some of the subtables might have become insane after they - * were sanity-checked by the edits of subsequent subtables. - * https://bugs.chromium.org/p/chromium/issues/detail?id=960331 */ unsigned int type = get_subtable (0).u.extension.get_type (); for (unsigned int i = 1; i < subtables; i++) @@ -2067,7 +2033,7 @@ struct ClassDef unsigned int get (hb_codepoint_t k) const { return get_class (k); } unsigned int get_class (hb_codepoint_t glyph_id) const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.get_class (glyph_id); case 2: hb_barrier (); return u.format2.get_class (glyph_id); #ifndef HB_NO_BEYOND_64K @@ -2078,7 +2044,7 @@ struct ClassDef } } unsigned int get_class (hb_codepoint_t glyph_id, - hb_ot_lookup_cache_t *cache) const + hb_ot_layout_mapping_cache_t *cache) const { unsigned klass; if (cache && cache->get (glyph_id, &klass)) return klass; @@ -2089,7 +2055,7 @@ struct ClassDef unsigned get_population () const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.get_population (); case 2: hb_barrier (); return u.format2.get_population (); #ifndef HB_NO_BEYOND_64K @@ -2142,7 +2108,7 @@ struct ClassDef #ifndef HB_NO_BEYOND_64K if (glyph_max > 0xFFFFu) - u.format += 2; + u.format.v += 2; if (unlikely (glyph_max > 0xFFFFFFu)) #else if (unlikely (glyph_max > 0xFFFFu)) @@ -2152,9 +2118,9 @@ struct ClassDef return_trace (false); } - u.format = format; + u.format.v = format; - switch (u.format) + switch (u.format.v) { case 1: hb_barrier (); return_trace (u.format1.serialize (c, it)); case 2: hb_barrier (); return_trace (u.format2.serialize (c, it)); @@ -2173,7 +2139,7 @@ struct ClassDef const Coverage* glyph_filter = nullptr) const { TRACE_SUBSET (this); - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return_trace (u.format1.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); case 2: hb_barrier (); return_trace (u.format2.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); #ifndef HB_NO_BEYOND_64K @@ -2187,9 +2153,9 @@ struct ClassDef bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return_trace (false); + if (!u.format.v.sanitize (c)) return_trace (false); hb_barrier (); - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return_trace (u.format1.sanitize (c)); case 2: hb_barrier (); return_trace (u.format2.sanitize (c)); #ifndef HB_NO_BEYOND_64K @@ -2202,7 +2168,7 @@ struct ClassDef unsigned cost () const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.cost (); case 2: hb_barrier (); return u.format2.cost (); #ifndef HB_NO_BEYOND_64K @@ -2218,7 +2184,7 @@ struct ClassDef template bool collect_coverage (set_t *glyphs) const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.collect_coverage (glyphs); case 2: hb_barrier (); return u.format2.collect_coverage (glyphs); #ifndef HB_NO_BEYOND_64K @@ -2234,7 +2200,7 @@ struct ClassDef template bool collect_class (set_t *glyphs, unsigned int klass) const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.collect_class (glyphs, klass); case 2: hb_barrier (); return u.format2.collect_class (glyphs, klass); #ifndef HB_NO_BEYOND_64K @@ -2247,7 +2213,7 @@ struct ClassDef bool intersects (const hb_set_t *glyphs) const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.intersects (glyphs); case 2: hb_barrier (); return u.format2.intersects (glyphs); #ifndef HB_NO_BEYOND_64K @@ -2259,7 +2225,7 @@ struct ClassDef } bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.intersects_class (glyphs, klass); case 2: hb_barrier (); return u.format2.intersects_class (glyphs, klass); #ifndef HB_NO_BEYOND_64K @@ -2272,7 +2238,7 @@ struct ClassDef void intersected_class_glyphs (const hb_set_t *glyphs, unsigned klass, hb_set_t *intersect_glyphs) const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.intersected_class_glyphs (glyphs, klass, intersect_glyphs); case 2: hb_barrier (); return u.format2.intersected_class_glyphs (glyphs, klass, intersect_glyphs); #ifndef HB_NO_BEYOND_64K @@ -2285,7 +2251,7 @@ struct ClassDef void intersected_classes (const hb_set_t *glyphs, hb_set_t *intersect_classes) const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.intersected_classes (glyphs, intersect_classes); case 2: hb_barrier (); return u.format2.intersected_classes (glyphs, intersect_classes); #ifndef HB_NO_BEYOND_64K @@ -2299,7 +2265,7 @@ struct ClassDef protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ ClassDefFormat1_3 format1; ClassDefFormat2_4 format2; #ifndef HB_NO_BEYOND_64K @@ -2308,7 +2274,7 @@ struct ClassDef #endif } u; public: - DEFINE_SIZE_UNION (2, format); + DEFINE_SIZE_UNION (2, format.v); }; template @@ -2326,151 +2292,177 @@ struct delta_row_encoding_t { /* each byte represents a region, value is one of 0/1/2/4, which means bytes * needed for this region */ - hb_vector_t chars; + struct chars_t : hb_vector_t + { + int cmp (const chars_t& other) const + { + return as_array ().cmp (other.as_array ()); + } + + hb_pair_t get_width () + { + unsigned width = 0; + unsigned columns = 0; + for (unsigned i = 0; i < length; i++) + { + unsigned v = arrayZ[i]; + width += v; + columns += (v != 0); + } + return hb_pair (width, columns); + } + + HB_HOT + hb_pair_t combine_width (const chars_t& other) const + { + unsigned combined_width = 0; + unsigned combined_columns = 0; + for (unsigned i = 0; i < length; i++) + { + unsigned v = hb_max (arrayZ[i], other.arrayZ[i]); + combined_width += v; + combined_columns += (v != 0); + } + return hb_pair (combined_width, combined_columns); + } + }; + + hb_pair_t combine_width (const delta_row_encoding_t& other_encoding) const { return chars.combine_width (other_encoding.chars); } + + // Actual data + + chars_t chars; unsigned width = 0; - hb_vector_t columns; unsigned overhead = 0; hb_vector_t*> items; delta_row_encoding_t () = default; - delta_row_encoding_t (hb_vector_t&& chars_, - const hb_vector_t* row = nullptr) : - delta_row_encoding_t () - + delta_row_encoding_t (hb_vector_t*> &&rows, unsigned num_cols) { - chars = std::move (chars_); - width = get_width (); - columns = get_columns (); - overhead = get_chars_overhead (columns); - if (row) items.push (row); + assert (rows); + + items = std::move (rows); + + if (unlikely (!chars.resize (num_cols))) + return; + + calculate_chars (); + } + + void merge (const delta_row_encoding_t& other) + { + items.alloc (items.length + other.items.length); + for (auto &row : other.items) + add_row (row); + + // Merge chars + assert (chars.length == other.chars.length); + for (unsigned i = 0; i < chars.length; i++) + chars.arrayZ[i] = hb_max (chars.arrayZ[i], other.chars.arrayZ[i]); + chars_changed (); + } + + void chars_changed () + { + auto _ = chars.get_width (); + width = _.first; + overhead = get_chars_overhead (_.second); + } + + void calculate_chars () + { + assert (items); + + bool long_words = false; + + for (auto &row : items) + { + assert (row->length == chars.length); + + /* 0/1/2 byte encoding */ + for (unsigned i = 0; i < row->length; i++) + { + int v = row->arrayZ[i]; + if (v == 0) + continue; + else if (v > 32767 || v < -32768) + { + long_words = true; + chars.arrayZ[i] = hb_max (chars.arrayZ[i], 4); + } + else if (v > 127 || v < -128) + chars.arrayZ[i] = hb_max (chars.arrayZ[i], 2); + else + chars.arrayZ[i] = hb_max (chars.arrayZ[i], 1); + } + } + + if (long_words) + { + // Convert 1s to 2s + for (auto &v : chars) + if (v == 1) + v = 2; + } + + chars_changed (); } bool is_empty () const { return !items; } - static hb_vector_t get_row_chars (const hb_vector_t& row) - { - hb_vector_t ret; - if (!ret.alloc (row.length)) return ret; - - bool long_words = false; - - /* 0/1/2 byte encoding */ - for (int i = row.length - 1; i >= 0; i--) - { - int v = row.arrayZ[i]; - if (v == 0) - ret.push (0); - else if (v > 32767 || v < -32768) - { - long_words = true; - break; - } - else if (v > 127 || v < -128) - ret.push (2); - else - ret.push (1); - } - - if (!long_words) - return ret; - - /* redo, 0/2/4 bytes encoding */ - ret.reset (); - for (int i = row.length - 1; i >= 0; i--) - { - int v = row.arrayZ[i]; - if (v == 0) - ret.push (0); - else if (v > 32767 || v < -32768) - ret.push (4); - else - ret.push (2); - } - return ret; - } - - inline unsigned get_width () - { - unsigned ret = + hb_iter (chars) - | hb_reduce (hb_add, 0u) - ; - return ret; - } - - hb_vector_t get_columns () - { - hb_vector_t cols; - cols.alloc (chars.length); - for (auto v : chars) - { - uint8_t flag = v ? 1 : 0; - cols.push (flag); - } - return cols; - } - - static inline unsigned get_chars_overhead (const hb_vector_t& cols) + static inline unsigned get_chars_overhead (unsigned num_columns) { unsigned c = 4 + 6; // 4 bytes for LOffset, 6 bytes for VarData header - unsigned cols_bit_count = 0; - for (auto v : cols) - if (v) cols_bit_count++; - return c + cols_bit_count * 2; + return c + num_columns * 2; } - unsigned get_gain () const + unsigned get_gain (unsigned additional_bytes_per_rows = 1) const { int count = items.length; - return hb_max (0, (int) overhead - count); + return hb_max (0, (int) overhead - count * (int) additional_bytes_per_rows); } int gain_from_merging (const delta_row_encoding_t& other_encoding) const { - int combined_width = 0; - for (unsigned i = 0; i < chars.length; i++) - combined_width += hb_max (chars.arrayZ[i], other_encoding.chars.arrayZ[i]); + // Back of the envelope calculations to reject early. + signed additional_bytes_per_rows = other_encoding.width - width; + if (additional_bytes_per_rows > 0) + { + if (get_gain (additional_bytes_per_rows) == 0) + return 0; + } + else + { + if (other_encoding.get_gain (-additional_bytes_per_rows) == 0) + return 0; + } - hb_vector_t combined_columns; - combined_columns.alloc (columns.length); - for (unsigned i = 0; i < columns.length; i++) - combined_columns.push (columns.arrayZ[i] | other_encoding.columns.arrayZ[i]); + auto pair = combine_width (other_encoding); + unsigned combined_width = pair.first; + unsigned combined_columns = pair.second; - int combined_overhead = get_chars_overhead (combined_columns); - int combined_gain = (int) overhead + (int) other_encoding.overhead - combined_overhead - - (combined_width - (int) width) * items.length - - (combined_width - (int) other_encoding.width) * other_encoding.items.length; + int combined_gain = (int) overhead + (int) other_encoding.overhead; + combined_gain -= (combined_width - (int) width) * items.length; + combined_gain -= (combined_width - (int) other_encoding.width) * other_encoding.items.length; + combined_gain -= get_chars_overhead (combined_columns); return combined_gain; } + bool add_row (const hb_vector_t* row) + { return items.push (row); } + static int cmp (const void *pa, const void *pb) { const delta_row_encoding_t *a = (const delta_row_encoding_t *)pa; const delta_row_encoding_t *b = (const delta_row_encoding_t *)pb; - int gain_a = a->get_gain (); - int gain_b = b->get_gain (); - - if (gain_a != gain_b) - return gain_a - gain_b; - - return (b->chars).as_array ().cmp ((a->chars).as_array ()); - } - - static int cmp_width (const void *pa, const void *pb) - { - const delta_row_encoding_t *a = (const delta_row_encoding_t *)pa; - const delta_row_encoding_t *b = (const delta_row_encoding_t *)pb; - if (a->width != b->width) return (int) a->width - (int) b->width; - return (b->chars).as_array ().cmp ((a->chars).as_array ()); + return b->chars.cmp (a->chars); } - - bool add_row (const hb_vector_t* row) - { return items.push (row); } }; struct VarRegionAxis @@ -2548,32 +2540,112 @@ struct SparseVarRegionAxis DEFINE_SIZE_STATIC (8); }; -#define REGION_CACHE_ITEM_CACHE_INVALID INT_MIN -#define REGION_CACHE_ITEM_MULTIPLIER (float (1 << ((sizeof (int) * 8) - 2))) -#define REGION_CACHE_ITEM_DIVISOR (1.f / float (1 << ((sizeof (int) * 8) - 2))) +struct hb_scalar_cache_t +{ + private: + static constexpr unsigned STATIC_LENGTH = 16; + static constexpr int INVALID = INT_MIN; + static constexpr float MULTIPLIER = 1 << ((sizeof (int) * 8) - 2); + static constexpr float DIVISOR = 1.f / MULTIPLIER; + + public: + hb_scalar_cache_t () : length (STATIC_LENGTH) { clear (); } + + hb_scalar_cache_t (const hb_scalar_cache_t&) = delete; + hb_scalar_cache_t (hb_scalar_cache_t&&) = delete; + hb_scalar_cache_t& operator= (const hb_scalar_cache_t&) = delete; + hb_scalar_cache_t& operator= (hb_scalar_cache_t&&) = delete; + + static hb_scalar_cache_t *create (unsigned int count, + hb_scalar_cache_t *scratch_cache = nullptr) + { + if (!count) return (hb_scalar_cache_t *) &Null(hb_scalar_cache_t); + + if (scratch_cache && count <= scratch_cache->length) + { + scratch_cache->clear (); + return scratch_cache; + } + + auto *cache = (hb_scalar_cache_t *) hb_malloc (sizeof (hb_scalar_cache_t) - sizeof (static_values) + sizeof (static_values[0]) * count); + if (unlikely (!cache)) return (hb_scalar_cache_t *) &Null(hb_scalar_cache_t); + + cache->length = count; + cache->clear (); + + return cache; + } + + static void destroy (hb_scalar_cache_t *cache, + hb_scalar_cache_t *scratch_cache = nullptr) + { + if (cache != &Null(hb_scalar_cache_t) && cache != scratch_cache) + hb_free (cache); + } + + void clear () + { + auto *values = &static_values[0]; + unsigned i = 0; +#ifndef HB_OPTIMIZE_SIZE + for (; i + 3 < length; i += 4) + { + values[i + 0] = INVALID; + values[i + 1] = INVALID; + values[i + 2] = INVALID; + values[i + 3] = INVALID; + } +#endif + for (; i < length; i++) + values[i] = INVALID; + } + + HB_ALWAYS_INLINE + bool get (unsigned i, float *value) const + { + if (unlikely (i >= length)) + { + *value = 0.f; + return true; + } + auto *values = &static_values[0]; + auto *cached_value = &values[i]; + // Super hot. Most common path is that we have a cached value of 0. + int v = *cached_value; + if (likely (!v)) + { + *value = 0.f; + return true; + } + if (v == INVALID) + return false; + *value = v * DIVISOR; + return true; + } + + HB_ALWAYS_INLINE + void set (unsigned i, float value) + { + if (unlikely (i >= length)) return; + auto *values = &static_values[0]; + auto *cached_value = &values[i]; + *cached_value = roundf(value * MULTIPLIER); + } + + private: + unsigned length; + mutable hb_atomic_t static_values[STATIC_LENGTH]; +}; struct VarRegionList { - using cache_t = hb_atomic_t; - - float evaluate (unsigned int region_index, - const int *coords, unsigned int coord_len, - cache_t *cache = nullptr) const + private: + float evaluate_impl (unsigned int region_index, + const int *coords, unsigned int coord_len) const { - if (unlikely (region_index >= regionCount)) - return 0.; - - cache_t *cached_value = nullptr; - if (cache) - { - cached_value = &(cache[region_index]); - if (*cached_value != REGION_CACHE_ITEM_CACHE_INVALID) - return *cached_value * REGION_CACHE_ITEM_DIVISOR; - } - const VarRegionAxis *axes = axesZ.arrayZ + (region_index * axisCount); + float v = 1.f; - float v = 1.; unsigned int count = axisCount; for (unsigned int i = 0; i < count; i++) { @@ -2581,15 +2653,32 @@ struct VarRegionList float factor = axes[i].evaluate (coord); if (factor == 0.f) { - if (cache) - *cached_value = 0.; - return 0.; + v = 0.f; + break; } v *= factor; } + return v; + } + + public: + HB_ALWAYS_INLINE + float evaluate (unsigned int region_index, + const int *coords, unsigned int coord_len, + hb_scalar_cache_t *cache = nullptr) const + { + if (unlikely (region_index >= regionCount)) + return 0.; + + float v; + if (cache && cache->get (region_index, &v)) + return v; + + v = evaluate_impl (region_index, coords, coord_len); + if (cache) - *cached_value = v * REGION_CACHE_ITEM_MULTIPLIER; + cache->set (region_index, v); return v; } @@ -2732,29 +2821,24 @@ struct SparseVariationRegion : Array16Of struct SparseVarRegionList { - using cache_t = hb_atomic_t; - + HB_ALWAYS_INLINE float evaluate (unsigned int region_index, const int *coords, unsigned int coord_len, - cache_t *cache = nullptr) const + hb_scalar_cache_t *cache = nullptr) const { if (unlikely (region_index >= regions.len)) return 0.; - cache_t *cached_value = nullptr; - if (cache) - { - cached_value = &(cache[region_index]); - if (*cached_value != REGION_CACHE_ITEM_CACHE_INVALID) - return *cached_value * REGION_CACHE_ITEM_DIVISOR; - } + float v; + if (cache && cache->get (region_index, &v)) + return v; const SparseVariationRegion ®ion = this+regions[region_index]; - float v = region.evaluate (coords, coord_len); - + v = region.evaluate (coords, coord_len); if (cache) - *cached_value = v * REGION_CACHE_ITEM_MULTIPLIER; + cache->set (region_index, v); + return v; } @@ -2792,46 +2876,62 @@ struct VarData + itemCount * get_row_size (); } - float get_delta (unsigned int inner, - const int *coords, unsigned int coord_count, - const VarRegionList ®ions, - VarRegionList::cache_t *cache = nullptr) const + float _get_delta (unsigned int inner, + const int *coords, unsigned int coord_count, + const VarRegionList ®ions, + hb_scalar_cache_t *cache = nullptr) const { if (unlikely (inner >= itemCount)) return 0.; + bool is_long = longWords (); + unsigned int count = regionIndices.len; + unsigned word_count = wordCount (); + unsigned int scount = is_long ? count : word_count; + unsigned int lcount = is_long ? word_count : 0; - unsigned int count = regionIndices.len; - bool is_long = longWords (); - unsigned word_count = wordCount (); - unsigned int scount = is_long ? count : word_count; - unsigned int lcount = is_long ? word_count : 0; + const HBUINT8 *bytes = get_delta_bytes (); + const HBUINT8 *row = bytes + inner * get_row_size (); - const HBUINT8 *bytes = get_delta_bytes (); - const HBUINT8 *row = bytes + inner * get_row_size (); + float delta = 0.; + unsigned int i = 0; - float delta = 0.; - unsigned int i = 0; + const HBINT32 *lcursor = reinterpret_cast (row); + for (; i < lcount; i++) + { + float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache); + if (scalar) + delta += scalar * *lcursor; + lcursor++; + } + const HBINT16 *scursor = reinterpret_cast (lcursor); + for (; i < scount; i++) + { + float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache); + if (scalar) + delta += scalar * *scursor; + scursor++; + } + const HBINT8 *bcursor = reinterpret_cast (scursor); + for (; i < count; i++) + { + float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache); + if (scalar) + delta += scalar * *bcursor; + bcursor++; + } - const HBINT32 *lcursor = reinterpret_cast (row); - for (; i < lcount; i++) - { - float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache); - delta += scalar * *lcursor++; - } - const HBINT16 *scursor = reinterpret_cast (lcursor); - for (; i < scount; i++) - { - float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache); - delta += scalar * *scursor++; - } - const HBINT8 *bcursor = reinterpret_cast (scursor); - for (; i < count; i++) - { - float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache); - delta += scalar * *bcursor++; - } + return delta; + } - return delta; + HB_ALWAYS_INLINE + float get_delta (unsigned int inner, + const int *coords, unsigned int coord_count, + const VarRegionList ®ions, + hb_scalar_cache_t *cache = nullptr) const + { + unsigned int count = regionIndices.len; + if (!count) return 0.f; // This is quite common, so optimize it. + return _get_delta (inner, coords, coord_count, regions, cache); } void get_region_scalars (const int *coords, unsigned int coord_count, @@ -3150,7 +3250,7 @@ struct MultiVarData const int *coords, unsigned int coord_count, const SparseVarRegionList ®ions, hb_array_t out, - SparseVarRegionList::cache_t *cache = nullptr) const + hb_scalar_cache_t *cache = nullptr) const { auto &deltaSets = StructAfter (regionIndices); @@ -3187,31 +3287,24 @@ struct MultiVarData struct ItemVariationStore { friend struct item_variations_t; - using cache_t = VarRegionList::cache_t; - cache_t *create_cache () const + hb_scalar_cache_t *create_cache () const { #ifdef HB_NO_VAR - return nullptr; + return hb_scalar_cache_t::create (0); #endif - unsigned count = (this+regions).regionCount; - if (!count) return nullptr; - - cache_t *cache = (cache_t *) hb_malloc (sizeof (float) * count); - if (unlikely (!cache)) return nullptr; - - for (unsigned i = 0; i < count; i++) - cache[i] = REGION_CACHE_ITEM_CACHE_INVALID; - - return cache; + return hb_scalar_cache_t::create ((this+regions).regionCount); } - static void destroy_cache (cache_t *cache) { hb_free (cache); } + static void destroy_cache (hb_scalar_cache_t *cache) + { + hb_scalar_cache_t::destroy (cache); + } private: float get_delta (unsigned int outer, unsigned int inner, const int *coords, unsigned int coord_count, - VarRegionList::cache_t *cache = nullptr) const + hb_scalar_cache_t *cache = nullptr) const { #ifdef HB_NO_VAR return 0.f; @@ -3229,7 +3322,7 @@ struct ItemVariationStore public: float get_delta (unsigned int index, const int *coords, unsigned int coord_count, - VarRegionList::cache_t *cache = nullptr) const + hb_scalar_cache_t *cache = nullptr) const { unsigned int outer = index >> 16; unsigned int inner = index & 0xFFFF; @@ -3237,7 +3330,7 @@ struct ItemVariationStore } float get_delta (unsigned int index, hb_array_t coords, - VarRegionList::cache_t *cache = nullptr) const + hb_scalar_cache_t *cache = nullptr) const { return get_delta (index, coords.arrayZ, coords.length, @@ -3356,7 +3449,7 @@ struct ItemVariationStore for (unsigned i = 0; i < count; i++) { hb_inc_bimap_t *map = inner_maps.push (); - if (!c->propagate_error(inner_maps)) + if (unlikely (!c->propagate_error(inner_maps))) return_trace(nullptr); auto &data = this+dataSets[i]; @@ -3445,43 +3538,28 @@ struct ItemVariationStore struct MultiItemVariationStore { - using cache_t = SparseVarRegionList::cache_t; - - cache_t *create_cache (hb_array_t static_cache = hb_array_t ()) const + hb_scalar_cache_t *create_cache (hb_scalar_cache_t *static_cache = nullptr) const { #ifdef HB_NO_VAR - return nullptr; + return hb_scalar_cache_t::create (0); #endif auto &r = this+regions; unsigned count = r.regions.len; - cache_t *cache; - if (count <= static_cache.length) - cache = static_cache.arrayZ; - else - { - cache = (cache_t *) hb_malloc (sizeof (float) * count); - if (unlikely (!cache)) return nullptr; - } - - for (unsigned i = 0; i < count; i++) - cache[i] = REGION_CACHE_ITEM_CACHE_INVALID; - - return cache; + return hb_scalar_cache_t::create (count, static_cache); } - static void destroy_cache (cache_t *cache, - hb_array_t static_cache = hb_array_t ()) + static void destroy_cache (hb_scalar_cache_t *cache, + hb_scalar_cache_t *static_cache = nullptr) { - if (cache != static_cache.arrayZ) - hb_free (cache); + hb_scalar_cache_t::destroy (cache, static_cache); } private: void get_delta (unsigned int outer, unsigned int inner, const int *coords, unsigned int coord_count, hb_array_t out, - VarRegionList::cache_t *cache = nullptr) const + hb_scalar_cache_t *cache = nullptr) const { #ifdef HB_NO_VAR return; @@ -3501,7 +3579,7 @@ struct MultiItemVariationStore void get_delta (unsigned int index, const int *coords, unsigned int coord_count, hb_array_t out, - VarRegionList::cache_t *cache = nullptr) const + hb_scalar_cache_t *cache = nullptr) const { unsigned int outer = index >> 16; unsigned int inner = index & 0xFFFF; @@ -3510,7 +3588,7 @@ struct MultiItemVariationStore void get_delta (unsigned int index, hb_array_t coords, hb_array_t out, - VarRegionList::cache_t *cache = nullptr) const + hb_scalar_cache_t *cache = nullptr) const { return get_delta (index, coords.arrayZ, coords.length, @@ -3540,8 +3618,6 @@ struct MultiItemVariationStore DEFINE_SIZE_ARRAY_SIZED (8, dataSets); }; -#undef REGION_CACHE_ITEM_CACHE_INVALID - template struct DeltaSetIndexMapFormat01 { @@ -3592,13 +3668,19 @@ struct DeltaSetIndexMapFormat01 return_trace (true); } + HB_ALWAYS_INLINE uint32_t map (unsigned int v) const /* Returns 16.16 outer.inner. */ { /* If count is zero, pass value unchanged. This takes * care of direct mapping for advance map. */ if (!mapCount) return v; + return _map (v); + } + HB_HOT + uint32_t _map (unsigned int v) const /* Returns 16.16 outer.inner. */ + { if (v >= mapCount) v = mapCount - 1; @@ -3654,8 +3736,8 @@ struct DeltaSetIndexMap { TRACE_SERIALIZE (this); unsigned length = plan.get_output_map ().length; - u.format = length <= 0xFFFF ? 0 : 1; - switch (u.format) { + u.format.v = length <= 0xFFFF ? 0 : 1; + switch (u.format.v) { case 0: hb_barrier (); return_trace (u.format0.serialize (c, plan)); case 1: hb_barrier (); return_trace (u.format1.serialize (c, plan)); default:return_trace (false); @@ -3664,7 +3746,7 @@ struct DeltaSetIndexMap uint32_t map (unsigned v) const { - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); return (u.format0.map (v)); case 1: hb_barrier (); return (u.format1.map (v)); default:return v; @@ -3673,7 +3755,7 @@ struct DeltaSetIndexMap unsigned get_map_count () const { - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); return u.format0.get_map_count (); case 1: hb_barrier (); return u.format1.get_map_count (); default:return 0; @@ -3682,7 +3764,7 @@ struct DeltaSetIndexMap unsigned get_width () const { - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); return u.format0.get_width (); case 1: hb_barrier (); return u.format1.get_width (); default:return 0; @@ -3691,7 +3773,7 @@ struct DeltaSetIndexMap unsigned get_inner_bit_count () const { - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); return u.format0.get_inner_bit_count (); case 1: hb_barrier (); return u.format1.get_inner_bit_count (); default:return 0; @@ -3701,9 +3783,9 @@ struct DeltaSetIndexMap bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return_trace (false); + if (!u.format.v.sanitize (c)) return_trace (false); hb_barrier (); - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); return_trace (u.format0.sanitize (c)); case 1: hb_barrier (); return_trace (u.format1.sanitize (c)); default:return_trace (true); @@ -3713,7 +3795,7 @@ struct DeltaSetIndexMap DeltaSetIndexMap* copy (hb_serialize_context_t *c) const { TRACE_SERIALIZE (this); - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); return_trace (reinterpret_cast (u.format0.copy (c))); case 1: hb_barrier (); return_trace (reinterpret_cast (u.format1.copy (c))); default:return_trace (nullptr); @@ -3722,12 +3804,12 @@ struct DeltaSetIndexMap protected: union { - HBUINT8 format; /* Format identifier */ + struct { HBUINT8 v; } format; /* Format identifier */ DeltaSetIndexMapFormat01 format0; DeltaSetIndexMapFormat01 format1; } u; public: - DEFINE_SIZE_UNION (1, format); + DEFINE_SIZE_UNION (1, format.v); }; @@ -3736,7 +3818,7 @@ struct ItemVarStoreInstancer ItemVarStoreInstancer (const ItemVariationStore *varStore_, const DeltaSetIndexMap *varIdxMap, hb_array_t coords, - VarRegionList::cache_t *cache = nullptr) : + hb_scalar_cache_t *cache = nullptr) : varStore (varStore_), varIdxMap (varIdxMap), coords (coords), cache (cache) { if (!varStore) @@ -3762,7 +3844,7 @@ struct ItemVarStoreInstancer const ItemVariationStore *varStore; const DeltaSetIndexMap *varIdxMap; hb_array_t coords; - VarRegionList::cache_t *cache; + hb_scalar_cache_t *cache; }; struct MultiItemVarStoreInstancer @@ -3770,7 +3852,7 @@ struct MultiItemVarStoreInstancer MultiItemVarStoreInstancer (const MultiItemVariationStore *varStore, const DeltaSetIndexMap *varIdxMap, hb_array_t coords, - SparseVarRegionList::cache_t *cache = nullptr) : + hb_scalar_cache_t *cache = nullptr) : varStore (varStore), varIdxMap (varIdxMap), coords (coords), cache (cache) { if (!varStore) @@ -3803,7 +3885,7 @@ struct MultiItemVarStoreInstancer const MultiItemVariationStore *varStore; const DeltaSetIndexMap *varIdxMap; hb_array_t coords; - SparseVarRegionList::cache_t *cache; + hb_scalar_cache_t *cache; }; @@ -4130,7 +4212,7 @@ struct Condition bool evaluate (const int *coords, unsigned int coord_len, Instancer *instancer) const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.evaluate (coords, coord_len, instancer); case 2: hb_barrier (); return u.format2.evaluate (coords, coord_len, instancer); case 3: hb_barrier (); return u.format3.evaluate (coords, coord_len, instancer); @@ -4143,7 +4225,7 @@ struct Condition Cond_with_Var_flag_t keep_with_variations (hb_collect_feature_substitutes_with_var_context_t *c, hb_map_t *condition_map /* OUT */) const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.keep_with_variations (c, condition_map); // TODO(subset) default: c->apply = false; return KEEP_COND_WITH_VAR; @@ -4153,9 +4235,9 @@ struct Condition template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward (ds)...)); case 2: hb_barrier (); return_trace (c->dispatch (u.format2, std::forward (ds)...)); case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward (ds)...)); @@ -4168,9 +4250,9 @@ struct Condition bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return_trace (false); + if (!u.format.v.sanitize (c)) return_trace (false); hb_barrier (); - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return_trace (u.format1.sanitize (c)); case 2: hb_barrier (); return_trace (u.format2.sanitize (c)); case 3: hb_barrier (); return_trace (u.format3.sanitize (c)); @@ -4182,7 +4264,7 @@ struct Condition protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ ConditionAxisRange format1; ConditionValue format2; ConditionAnd format3; @@ -4190,7 +4272,7 @@ struct Condition ConditionNegate format5; } u; public: - DEFINE_SIZE_UNION (2, format); + DEFINE_SIZE_UNION (2, format.v); }; template @@ -4353,7 +4435,7 @@ struct FeatureTableSubstitutionRecord if (unlikely (!s->extend_min (this))) return_trace (false); uint32_t *new_feature_idx; - if (!c->feature_index_map->has (feature_index, &new_feature_idx)) + if (!c->feature_map_w_duplicates->has (feature_index, &new_feature_idx)) return_trace (false); if (!s->check_assign (featureIndex, *new_feature_idx, HB_SERIALIZE_ERROR_INT_OVERFLOW)) @@ -4371,7 +4453,7 @@ struct FeatureTableSubstitutionRecord { TRACE_SUBSET (this); uint32_t *new_feature_index; - if (!c->feature_index_map->has (featureIndex, &new_feature_index)) + if (!c->feature_map_w_duplicates->has (featureIndex, &new_feature_index)) return_trace (false); auto *out = c->subset_context->serializer->embed (this); @@ -4645,7 +4727,7 @@ struct FeatureVariations int keep_up_to = -1; for (int i = varRecords.len - 1; i >= 0; i--) { - if (varRecords[i].intersects_features (this, l->feature_index_map)) { + if (varRecords[i].intersects_features (this, l->feature_map_w_duplicates)) { keep_up_to = i; break; } @@ -4783,13 +4865,13 @@ struct VariationDevice hb_position_t get_x_delta (hb_font_t *font, const ItemVariationStore &store, - ItemVariationStore::cache_t *store_cache = nullptr) const - { return !font->num_coords ? 0 : font->em_scalef_x (get_delta (font, store, store_cache)); } + hb_scalar_cache_t *store_cache = nullptr) const + { return !font->has_nonzero_coords ? 0 : font->em_scalef_x (get_delta (font, store, store_cache)); } hb_position_t get_y_delta (hb_font_t *font, const ItemVariationStore &store, - ItemVariationStore::cache_t *store_cache = nullptr) const - { return !font->num_coords ? 0 : font->em_scalef_y (get_delta (font, store, store_cache)); } + hb_scalar_cache_t *store_cache = nullptr) const + { return !font->has_nonzero_coords ? 0 : font->em_scalef_y (get_delta (font, store, store_cache)); } VariationDevice* copy (hb_serialize_context_t *c, const hb_hashmap_t> *layout_variation_idx_delta_map) const @@ -4823,9 +4905,9 @@ struct VariationDevice float get_delta (hb_font_t *font, const ItemVariationStore &store, - ItemVariationStore::cache_t *store_cache = nullptr) const + hb_scalar_cache_t *store_cache = nullptr) const { - return store.get_delta (varIdx, font->coords, font->num_coords, (ItemVariationStore::cache_t *) store_cache); + return store.get_delta (varIdx, font->coords, font->num_coords, store_cache); } protected: @@ -4850,7 +4932,7 @@ struct Device { hb_position_t get_x_delta (hb_font_t *font, const ItemVariationStore &store=Null (ItemVariationStore), - ItemVariationStore::cache_t *store_cache = nullptr) const + hb_scalar_cache_t *store_cache = nullptr) const { switch (u.b.format) { @@ -4868,7 +4950,7 @@ struct Device } hb_position_t get_y_delta (hb_font_t *font, const ItemVariationStore &store=Null (ItemVariationStore), - ItemVariationStore::cache_t *store_cache = nullptr) const + hb_scalar_cache_t *store_cache = nullptr) const { switch (u.b.format) { @@ -4954,6 +5036,18 @@ struct Device } } + bool is_variation_device () const + { + switch (u.b.format) { +#ifndef HB_NO_VAR + case 0x8000: + return true; +#endif + default: + return false; + } + } + protected: union { DeviceHeader b; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gpos-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gpos-table.hh index 0cfa139a260..f6aabc84ac9 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gpos-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gpos-table.hh @@ -63,12 +63,20 @@ inline bool PosLookup::dispatch_recurse_func (hb_ot_apply c->set_lookup_index (lookup_index); c->set_lookup_props (l.get_props ()); + uint32_t stack_match_positions[8]; + hb_vector_t saved_match_positions; + saved_match_positions.set_storage (stack_match_positions); + hb_swap (c->match_positions, saved_match_positions); + bool ret = false; auto *accel = gpos->get_accel (lookup_index); - ret = accel && accel->apply (c, l.get_subtable_count (), false); + ret = accel && accel->apply (c, false); c->set_lookup_index (saved_lookup_index); c->set_lookup_props (saved_lookup_props); + + hb_swap (c->match_positions, saved_match_positions); + return ret; } #endif diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsub-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsub-table.hh index fd8a68be02d..8d5e1f18638 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsub-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsub-table.hh @@ -76,12 +76,20 @@ inline bool SubstLookup::dispatch_recurse_func (hb_ot_app c->set_lookup_index (lookup_index); c->set_lookup_props (l.get_props ()); + uint32_t stack_match_positions[8]; + hb_vector_t saved_match_positions; + saved_match_positions.set_storage (stack_match_positions); + hb_swap (c->match_positions, saved_match_positions); + bool ret = false; auto *accel = gsub->get_accel (lookup_index); - ret = accel && accel->apply (c, l.get_subtable_count (), false); + ret = accel && accel->apply (c, false); c->set_lookup_index (saved_lookup_index); c->set_lookup_props (saved_lookup_props); + + hb_swap (c->match_positions, saved_match_positions); + return ret; } #endif diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh index 072e5cdba26..05bbf3395bf 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh @@ -397,303 +397,311 @@ struct hb_collect_coverage_context_t : set_t *set; }; -struct hb_ot_apply_context_t : - hb_dispatch_context_t +struct matcher_t { - struct matcher_t + typedef bool (*match_func_t) (hb_glyph_info_t &info, unsigned value, const void *data); + + template + void init (const context_t *c, bool context_match = false) { - typedef bool (*match_func_t) (hb_glyph_info_t &info, unsigned value, const void *data); + set_match_func (nullptr, nullptr); + lookup_props = c->lookup_props; + /* Ignore ZWNJ if we are matching GPOS, or matching GSUB context and asked to. */ + ignore_zwnj = c->table_index == 1 || (context_match && c->auto_zwnj); + /* Ignore ZWJ if we are matching context, or asked to. */ + ignore_zwj = context_match || c->auto_zwj; + /* Ignore hidden glyphs (like CGJ) during GPOS. */ + ignore_hidden = c->table_index == 1; + mask = context_match ? -1 : c->lookup_mask; + /* Per syllable matching is only for GSUB. */ + per_syllable = c->table_index == 0 && c->per_syllable; + syllable = 0; + } - void set_ignore_zwnj (bool ignore_zwnj_) { ignore_zwnj = ignore_zwnj_; } - void set_ignore_zwj (bool ignore_zwj_) { ignore_zwj = ignore_zwj_; } - void set_ignore_hidden (bool ignore_hidden_) { ignore_hidden = ignore_hidden_; } - void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; } - void set_mask (hb_mask_t mask_) { mask = mask_; } - void set_per_syllable (bool per_syllable_) { per_syllable = per_syllable_; } - void set_syllable (uint8_t syllable_) { syllable = per_syllable ? syllable_ : 0; } - void set_match_func (match_func_t match_func_, - const void *match_data_) - { match_func = match_func_; match_data = match_data_; } + void set_match_func (match_func_t match_func_, + const void *match_data_) + { match_func = match_func_; match_data = match_data_; } - enum may_match_t { - MATCH_NO, - MATCH_YES, - MATCH_MAYBE - }; - -#ifndef HB_OPTIMIZE_SIZE - HB_ALWAYS_INLINE -#endif - may_match_t may_match (hb_glyph_info_t &info, - hb_codepoint_t glyph_data) const - { - if (!(info.mask & mask) || - (syllable && syllable != info.syllable ())) - return MATCH_NO; - - if (match_func) - return match_func (info, glyph_data, match_data) ? MATCH_YES : MATCH_NO; - - return MATCH_MAYBE; - } - - enum may_skip_t { - SKIP_NO, - SKIP_YES, - SKIP_MAYBE - }; - -#ifndef HB_OPTIMIZE_SIZE - HB_ALWAYS_INLINE -#endif - may_skip_t may_skip (const hb_ot_apply_context_t *c, - const hb_glyph_info_t &info) const - { - if (!c->check_glyph_property (&info, lookup_props)) - return SKIP_YES; - - if (unlikely (_hb_glyph_info_is_default_ignorable (&info) && - (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) && - (ignore_zwj || !_hb_glyph_info_is_zwj (&info)) && - (ignore_hidden || !_hb_glyph_info_is_hidden (&info)))) - return SKIP_MAYBE; - - return SKIP_NO; - } - - protected: - unsigned int lookup_props = 0; - hb_mask_t mask = -1; - bool ignore_zwnj = false; - bool ignore_zwj = false; - bool ignore_hidden = false; - bool per_syllable = false; - uint8_t syllable = 0; - match_func_t match_func = nullptr; - const void *match_data = nullptr; + enum may_match_t { + MATCH_NO, + MATCH_YES, + MATCH_MAYBE }; - struct skipping_iterator_t +#ifndef HB_OPTIMIZE_SIZE + HB_ALWAYS_INLINE +#endif + may_match_t may_match (hb_glyph_info_t &info, + hb_codepoint_t glyph_data) const { - void init (hb_ot_apply_context_t *c_, bool context_match = false) - { - c = c_; - end = c->buffer->len; - match_glyph_data16 = nullptr; + if (!(info.mask & mask) || + (per_syllable && syllable && syllable != info.syllable ())) + return MATCH_NO; + + if (match_func) + return match_func (info, glyph_data, match_data) ? MATCH_YES : MATCH_NO; + + return MATCH_MAYBE; + } + + enum may_skip_t { + SKIP_NO, + SKIP_YES, + SKIP_MAYBE + }; + + template +#ifndef HB_OPTIMIZE_SIZE + HB_ALWAYS_INLINE +#endif + may_skip_t may_skip (const context_t *c, + const hb_glyph_info_t &info) const + { + if (!c->check_glyph_property (&info, lookup_props)) + return SKIP_YES; + + if (unlikely (_hb_glyph_info_is_default_ignorable (&info) && + (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) && + (ignore_zwj || !_hb_glyph_info_is_zwj (&info)) && + (ignore_hidden || !_hb_glyph_info_is_hidden (&info)))) + return SKIP_MAYBE; + + return SKIP_NO; + } + + public: + unsigned int lookup_props = 0; + hb_mask_t mask = -1; + bool ignore_zwnj = false; + bool ignore_zwj = false; + bool ignore_hidden = false; + bool per_syllable = false; + uint8_t syllable = 0; + match_func_t match_func = nullptr; + const void *match_data = nullptr; +}; + +template +struct skipping_iterator_t +{ + void init (context_t *c_, bool context_match = false) + { + c = c_; + end = c->buffer->len; + match_glyph_data16 = nullptr; #ifndef HB_NO_BEYOND_64K - match_glyph_data24 = nullptr; + match_glyph_data24 = nullptr; #endif - matcher.set_match_func (nullptr, nullptr); - matcher.set_lookup_props (c->lookup_props); - /* Ignore ZWNJ if we are matching GPOS, or matching GSUB context and asked to. */ - matcher.set_ignore_zwnj (c->table_index == 1 || (context_match && c->auto_zwnj)); - /* Ignore ZWJ if we are matching context, or asked to. */ - matcher.set_ignore_zwj (context_match || c->auto_zwj); - /* Ignore hidden glyphs (like CGJ) during GPOS. */ - matcher.set_ignore_hidden (c->table_index == 1); - matcher.set_mask (context_match ? -1 : c->lookup_mask); - /* Per syllable matching is only for GSUB. */ - matcher.set_per_syllable (c->table_index == 0 && c->per_syllable); - matcher.set_syllable (0); - } - void set_lookup_props (unsigned int lookup_props) - { - matcher.set_lookup_props (lookup_props); - } - void set_match_func (matcher_t::match_func_t match_func_, - const void *match_data_) - { - matcher.set_match_func (match_func_, match_data_); - } - void set_glyph_data (const HBUINT16 glyph_data[]) - { - match_glyph_data16 = glyph_data; + matcher.init (c, context_match); + } + void set_lookup_props (unsigned int lookup_props) + { + matcher.lookup_props = lookup_props; + } + void set_match_func (matcher_t::match_func_t match_func_, + const void *match_data_) + { + matcher.set_match_func (match_func_, match_data_); + } + void set_glyph_data (const HBUINT16 glyph_data[]) + { + match_glyph_data16 = glyph_data; #ifndef HB_NO_BEYOND_64K - match_glyph_data24 = nullptr; + match_glyph_data24 = nullptr; #endif - } + } #ifndef HB_NO_BEYOND_64K - void set_glyph_data (const HBUINT24 glyph_data[]) - { - match_glyph_data16 = nullptr; - match_glyph_data24 = glyph_data; - } + void set_glyph_data (const HBUINT24 glyph_data[]) + { + match_glyph_data16 = nullptr; + match_glyph_data24 = glyph_data; + } #endif #ifndef HB_OPTIMIZE_SIZE - HB_ALWAYS_INLINE + HB_ALWAYS_INLINE #endif - void reset (unsigned int start_index_) - { - idx = start_index_; - end = c->buffer->len; - matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0); - } - -#ifndef HB_OPTIMIZE_SIZE - HB_ALWAYS_INLINE -#endif - void reset_fast (unsigned int start_index_) - { - // Doesn't set end or syllable. Used by GPOS which doesn't care / change. - idx = start_index_; - } - - void reject () - { - backup_glyph_data (); - } - - matcher_t::may_skip_t -#ifndef HB_OPTIMIZE_SIZE - HB_ALWAYS_INLINE -#endif - may_skip (const hb_glyph_info_t &info) const - { return matcher.may_skip (c, info); } - - enum match_t { - MATCH, - NOT_MATCH, - SKIP - }; - -#ifndef HB_OPTIMIZE_SIZE - HB_ALWAYS_INLINE -#endif - match_t match (hb_glyph_info_t &info) - { - matcher_t::may_skip_t skip = matcher.may_skip (c, info); - if (unlikely (skip == matcher_t::SKIP_YES)) - return SKIP; - - matcher_t::may_match_t match = matcher.may_match (info, get_glyph_data ()); - if (match == matcher_t::MATCH_YES || - (match == matcher_t::MATCH_MAYBE && - skip == matcher_t::SKIP_NO)) - return MATCH; - - if (skip == matcher_t::SKIP_NO) - return NOT_MATCH; - - return SKIP; + void reset (unsigned int start_index_) + { + // For GSUB forward iterator + idx = start_index_; + end = c->buffer->len; + matcher.syllable = c->buffer->cur().syllable(); + } + void reset_back (unsigned int start_index_, bool from_out_buffer = false) + { + // For GSUB backward iterator + idx = start_index_; + matcher.syllable = c->buffer->cur().syllable(); } #ifndef HB_OPTIMIZE_SIZE - HB_ALWAYS_INLINE + HB_ALWAYS_INLINE #endif - bool next (unsigned *unsafe_to = nullptr) - { - const signed stop = (signed) end - 1; - while ((signed) idx < stop) - { - idx++; - switch (match (c->buffer->info[idx])) - { - case MATCH: - { - advance_glyph_data (); - return true; - } - case NOT_MATCH: - { - if (unsafe_to) - *unsafe_to = idx + 1; - return false; - } - case SKIP: - continue; - } - } - if (unsafe_to) - *unsafe_to = end; - return false; - } + void reset_fast (unsigned int start_index_) + { + // Doesn't set end or syllable. Used by GPOS which doesn't care / change. + idx = start_index_; + } + #ifndef HB_OPTIMIZE_SIZE - HB_ALWAYS_INLINE + HB_ALWAYS_INLINE #endif - bool prev (unsigned *unsafe_from = nullptr) - { - const unsigned stop = 0; - while (idx > stop) - { - idx--; - switch (match (c->buffer->out_info[idx])) - { - case MATCH: - { - advance_glyph_data (); - return true; - } - case NOT_MATCH: - { - if (unsafe_from) - *unsafe_from = hb_max (1u, idx) - 1u; - return false; - } - case SKIP: - continue; - } - } - if (unsafe_from) - *unsafe_from = 0; - return false; - } + matcher_t::may_skip_t may_skip (const hb_glyph_info_t &info) const + { return matcher.may_skip (c, info); } - HB_ALWAYS_INLINE - hb_codepoint_t - get_glyph_data () - { - if (match_glyph_data16) return *match_glyph_data16; -#ifndef HB_NO_BEYOND_64K - else - if (match_glyph_data24) return *match_glyph_data24; -#endif - return 0; - } - HB_ALWAYS_INLINE - void - advance_glyph_data () - { - if (match_glyph_data16) match_glyph_data16++; -#ifndef HB_NO_BEYOND_64K - else - if (match_glyph_data24) match_glyph_data24++; -#endif - } - void - backup_glyph_data () - { - if (match_glyph_data16) match_glyph_data16--; -#ifndef HB_NO_BEYOND_64K - else - if (match_glyph_data24) match_glyph_data24--; -#endif - } - - unsigned int idx; - protected: - hb_ot_apply_context_t *c; - matcher_t matcher; - const HBUINT16 *match_glyph_data16; -#ifndef HB_NO_BEYOND_64K - const HBUINT24 *match_glyph_data24; -#endif - - unsigned int end; + enum match_t { + MATCH, + NOT_MATCH, + SKIP }; +#ifndef HB_OPTIMIZE_SIZE + HB_ALWAYS_INLINE +#endif + match_t match (hb_glyph_info_t &info) + { + matcher_t::may_skip_t skip = matcher.may_skip (c, info); + if (unlikely (skip == matcher_t::SKIP_YES)) + return SKIP; + matcher_t::may_match_t match = matcher.may_match (info, get_glyph_data ()); + if (match == matcher_t::MATCH_YES || + (match == matcher_t::MATCH_MAYBE && + skip == matcher_t::SKIP_NO)) + return MATCH; + + if (skip == matcher_t::SKIP_NO) + return NOT_MATCH; + + return SKIP; + } + +#ifndef HB_OPTIMIZE_SIZE + HB_ALWAYS_INLINE +#endif + bool next (unsigned *unsafe_to = nullptr) + { + auto *info = c->buffer->info; + const signed stop = (signed) end - 1; + while ((signed) idx < stop) + { + idx++; + switch (match (info[idx])) + { + case MATCH: + { + advance_glyph_data (); + return true; + } + case NOT_MATCH: + { + if (unsafe_to) + *unsafe_to = idx + 1; + return false; + } + case SKIP: + continue; + } + } + if (unsafe_to) + *unsafe_to = end; + return false; + } +#ifndef HB_OPTIMIZE_SIZE + HB_ALWAYS_INLINE +#endif + bool prev (unsigned *unsafe_from = nullptr) + { + auto *out_info = c->buffer->out_info; + const unsigned stop = 0; + while (idx > stop) + { + idx--; + switch (match (out_info[idx])) + { + case MATCH: + { + advance_glyph_data (); + return true; + } + case NOT_MATCH: + { + if (unsafe_from) + *unsafe_from = hb_max (1u, idx) - 1u; + return false; + } + case SKIP: + continue; + } + } + if (unsafe_from) + *unsafe_from = 0; + return false; + } + + HB_ALWAYS_INLINE + hb_codepoint_t + get_glyph_data () + { + if (match_glyph_data16) return *match_glyph_data16; +#ifndef HB_NO_BEYOND_64K + else + if (match_glyph_data24) return *match_glyph_data24; +#endif + return 0; + } + HB_ALWAYS_INLINE + void + advance_glyph_data () + { + if (match_glyph_data16) match_glyph_data16++; +#ifndef HB_NO_BEYOND_64K + else + if (match_glyph_data24) match_glyph_data24++; +#endif + } + + unsigned int idx; + protected: + context_t *c; + matcher_t matcher; + const HBUINT16 *match_glyph_data16; +#ifndef HB_NO_BEYOND_64K + const HBUINT24 *match_glyph_data24; +#endif + + unsigned int end; +}; + +struct hb_ot_apply_context_t : + hb_dispatch_context_t +{ const char *get_name () { return "APPLY"; } typedef return_t (*recurse_func_t) (hb_ot_apply_context_t *c, unsigned int lookup_index); + template - return_t dispatch (const T &obj) { return obj.apply (this); } + static inline auto apply_ (const T &obj, hb_ot_apply_context_t *c, hb_priority<1>) HB_RETURN (return_t, obj.apply (c, nullptr) ) + template + static inline auto apply_ (const T &obj, hb_ot_apply_context_t *c, hb_priority<0>) HB_RETURN (return_t, obj.apply (c) ) + template + return_t dispatch (const T &obj) { return apply_(obj, this, hb_prioritize); } + static return_t default_return_value () { return false; } bool stop_sublookup_iteration (return_t r) const { return r; } return_t recurse (unsigned int sub_lookup_index) { - if (unlikely (nesting_level_left == 0 || !recurse_func || buffer->max_ops-- <= 0)) + assert (recurse_func); + if (unlikely (nesting_level_left == 0)) { - buffer->shaping_failed = true; + buffer->successful = false; + return default_return_value (); + } + + buffer->max_ops--; + if (unlikely (buffer->max_ops < 0)) + { + buffer->successful = false; return default_return_value (); } @@ -703,7 +711,7 @@ struct hb_ot_apply_context_t : return ret; } - skipping_iterator_t iter_input, iter_context; + skipping_iterator_t iter_input, iter_context; unsigned int table_index; /* GSUB/GPOS */ hb_font_t *font; @@ -715,8 +723,7 @@ struct hb_ot_apply_context_t : const GDEF::accelerator_t &gdef_accel; const hb_ot_layout_lookup_accelerator_t *lookup_accel = nullptr; const ItemVariationStore &var_store; - ItemVariationStore::cache_t *var_store_cache; - hb_set_digest_t digest; + hb_scalar_cache_t *var_store_cache; hb_direction_t direction; hb_mask_t lookup_mask = 1; @@ -734,11 +741,14 @@ struct hb_ot_apply_context_t : signed last_base = -1; // GPOS uses unsigned last_base_until = 0; // GPOS uses + hb_vector_t match_positions; + uint32_t stack_match_positions[8]; + hb_ot_apply_context_t (unsigned int table_index_, hb_font_t *font_, hb_buffer_t *buffer_, hb_blob_t *table_blob_, - ItemVariationStore::cache_t *var_store_cache_ = nullptr) : + hb_scalar_cache_t *var_store_cache_ = nullptr) : table_index (table_index_), font (font_), face (font->face), buffer (buffer_), sanitizer (table_blob_), @@ -762,7 +772,7 @@ struct hb_ot_apply_context_t : has_glyph_classes (gdef.has_glyph_classes ()) { init_iters (); - buffer->collect_codepoints (digest); + match_positions.set_storage (stack_match_positions); } void init_iters () @@ -778,7 +788,11 @@ struct hb_ot_apply_context_t : void set_random (bool random_) { random = random_; } void set_recurse_func (recurse_func_t func) { recurse_func = func; } void set_lookup_index (unsigned int lookup_index_) { lookup_index = lookup_index_; } - void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; init_iters (); } + void set_lookup_props (unsigned int lookup_props_) + { + lookup_props = gdef_accel.sanitize_lookup_props (lookup_props_); + init_iters (); + } uint32_t random_number () { @@ -787,7 +801,9 @@ struct hb_ot_apply_context_t : return buffer->random_state; } - bool match_properties_mark (hb_codepoint_t glyph, + HB_ALWAYS_INLINE + HB_HOT + bool match_properties_mark (const hb_glyph_info_t *info, unsigned int glyph_props, unsigned int match_props) const { @@ -795,7 +811,7 @@ struct hb_ot_apply_context_t : * match_props has the set index. */ if (match_props & LookupFlag::UseMarkFilteringSet) - return gdef_accel.mark_set_covers (match_props >> 16, glyph); + return gdef_accel.mark_set_covers (match_props >> 16, info->codepoint); /* The second byte of match_props has the meaning * "ignore marks of attachment type different than @@ -811,7 +827,7 @@ struct hb_ot_apply_context_t : HB_ALWAYS_INLINE #endif bool check_glyph_property (const hb_glyph_info_t *info, - unsigned int match_props) const + unsigned match_props) const { unsigned int glyph_props = _hb_glyph_info_get_glyph_props (info); @@ -821,8 +837,8 @@ struct hb_ot_apply_context_t : if (glyph_props & match_props & LookupFlag::IgnoreFlags) return false; - if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_PROPS_MARK)) - return match_properties_mark (info->codepoint, glyph_props, match_props); + if (glyph_props & HB_OT_LAYOUT_GLYPH_PROPS_MARK) + return match_properties_mark (info, glyph_props, match_props); return true; } @@ -832,7 +848,7 @@ struct hb_ot_apply_context_t : bool ligature = false, bool component = false) { - digest.add (glyph_index); + buffer->digest.add (glyph_index); if (new_syllables != (unsigned) -1) buffer->cur().syllable() = new_syllables; @@ -890,54 +906,58 @@ struct hb_ot_apply_context_t : } }; -enum class hb_ot_lookup_cache_op_t +enum class hb_ot_subtable_cache_op_t { - CREATE, ENTER, LEAVE, - DESTROY, }; struct hb_accelerate_subtables_context_t : hb_dispatch_context_t { - template - static inline bool apply_to (const void *obj, hb_ot_apply_context_t *c) + template + static inline auto apply_ (const T *obj, hb_ot_apply_context_t *c, void *external_cache, hb_priority<1>) HB_RETURN (bool, obj->apply (c, external_cache) ) + template + static inline auto apply_ (const T *obj, hb_ot_apply_context_t *c, void *external_cache, hb_priority<0>) HB_RETURN (bool, obj->apply (c) ) + template + static inline bool apply_to (const void *obj, hb_ot_apply_context_t *c, void *external_cache) { - const Type *typed_obj = (const Type *) obj; - return typed_obj->apply (c); + const T *typed_obj = (const T *) obj; + return apply_ (typed_obj, c, external_cache, hb_prioritize); } #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE template - static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, hb_priority<1>) HB_RETURN (bool, obj->apply_cached (c) ) + static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, void *external_cache, hb_priority<2>) HB_RETURN (bool, obj->apply_cached (c, external_cache) ) template - static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, hb_priority<0>) HB_RETURN (bool, obj->apply (c) ) - template - static inline bool apply_cached_to (const void *obj, hb_ot_apply_context_t *c) + static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, void *external_cache, hb_priority<1>) HB_RETURN (bool, obj->apply (c, external_cache) ) + template + static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, void *external_cache, hb_priority<0>) HB_RETURN (bool, obj->apply (c) ) + template + static inline bool apply_cached_to (const void *obj, hb_ot_apply_context_t *c, void *external_cache) { - const Type *typed_obj = (const Type *) obj; - return apply_cached_ (typed_obj, c, hb_prioritize); + const T *typed_obj = (const T *) obj; + return apply_cached_ (typed_obj, c, external_cache, hb_prioritize); } template - static inline auto cache_func_ (void *p, - hb_ot_lookup_cache_op_t op, - hb_priority<1>) HB_RETURN (void *, T::cache_func (p, op) ) + static inline auto cache_func_ (hb_ot_apply_context_t *c, + hb_ot_subtable_cache_op_t op, + hb_priority<1>) HB_RETURN (bool, T::cache_func (c, op) ) template - static inline void * cache_func_ (void *p, - hb_ot_lookup_cache_op_t op HB_UNUSED, - hb_priority<0>) { return (void *) false; } + static inline bool cache_func_ (hb_ot_apply_context_t *c, + hb_ot_subtable_cache_op_t op HB_UNUSED, + hb_priority<0>) { return false; } template - static inline void * cache_func_to (void *p, - hb_ot_lookup_cache_op_t op) + static inline bool cache_func_to (hb_ot_apply_context_t *c, + hb_ot_subtable_cache_op_t op) { - return cache_func_ (p, op, hb_prioritize); + return cache_func_ (c, op, hb_prioritize); } #endif - typedef bool (*hb_apply_func_t) (const void *obj, hb_ot_apply_context_t *c); - typedef void * (*hb_cache_func_t) (void *p, hb_ot_lookup_cache_op_t op); + typedef bool (*hb_apply_func_t) (const void *obj, hb_ot_apply_context_t *c, void *external_cache); + typedef bool (*hb_cache_func_t) (hb_ot_apply_context_t *c, hb_ot_subtable_cache_op_t op); struct hb_applicable_t { @@ -950,6 +970,7 @@ struct hb_accelerate_subtables_context_t : #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE , hb_apply_func_t apply_cached_func_ , hb_cache_func_t cache_func_ + , void *external_cache_ #endif ) { @@ -958,27 +979,34 @@ struct hb_accelerate_subtables_context_t : #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE apply_cached_func = apply_cached_func_; cache_func = cache_func_; + external_cache = external_cache_; #endif digest.init (); obj_.get_coverage ().collect_coverage (&digest); } +#ifdef HB_NO_OT_LAYOUT_LOOKUP_CACHE bool apply (hb_ot_apply_context_t *c) const { - return digest.may_have (c->buffer->cur().codepoint) && apply_func (obj, c); + return digest.may_have (c->buffer->cur().codepoint) && apply_func (obj, c, nullptr); + } +#else + bool apply (hb_ot_apply_context_t *c) const + { + return digest.may_have (c->buffer->cur().codepoint) && apply_func (obj, c, external_cache); } -#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE bool apply_cached (hb_ot_apply_context_t *c) const { - return digest.may_have (c->buffer->cur().codepoint) && apply_cached_func (obj, c); + return digest.may_have (c->buffer->cur().codepoint) && apply_cached_func (obj, c, external_cache); } + bool cache_enter (hb_ot_apply_context_t *c) const { - return (bool) cache_func (c, hb_ot_lookup_cache_op_t::ENTER); + return cache_func (c, hb_ot_subtable_cache_op_t::ENTER); } void cache_leave (hb_ot_apply_context_t *c) const { - cache_func (c, hb_ot_lookup_cache_op_t::LEAVE); + cache_func (c, hb_ot_subtable_cache_op_t::LEAVE); } #endif @@ -988,6 +1016,7 @@ struct hb_accelerate_subtables_context_t : #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE hb_apply_func_t apply_cached_func; hb_cache_func_t cache_func; + void *external_cache; #endif hb_set_digest_t digest; }; @@ -997,12 +1026,23 @@ struct hb_accelerate_subtables_context_t : auto cache_cost (const T &obj, hb_priority<1>) HB_AUTO_RETURN ( obj.cache_cost () ) template auto cache_cost (const T &obj, hb_priority<0>) HB_AUTO_RETURN ( 0u ) + + template + auto external_cache_create (const T &obj, hb_priority<1>) HB_AUTO_RETURN ( obj.external_cache_create () ) + template + auto external_cache_create (const T &obj, hb_priority<0>) HB_AUTO_RETURN ( nullptr ) #endif /* Dispatch interface. */ template return_t dispatch (const T &obj) { +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + void *external_cache = nullptr; + if (i < 8) + external_cache = external_cache_create (obj, hb_prioritize); +#endif + hb_applicable_t *entry = &array[i++]; entry->init (obj, @@ -1010,6 +1050,7 @@ struct hb_accelerate_subtables_context_t : #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE , apply_cached_to , cache_func_to + , external_cache #endif ); @@ -1023,10 +1064,10 @@ struct hb_accelerate_subtables_context_t : * and we allocate the cache opportunity to the costliest subtable. */ unsigned cost = cache_cost (obj, hb_prioritize); - if (cost > cache_user_cost) + if (cost > subtable_cache_user_cost) { - cache_user_idx = i - 1; - cache_user_cost = cost; + subtable_cache_user_idx = i - 1; + subtable_cache_user_cost = cost; } #endif @@ -1041,8 +1082,8 @@ struct hb_accelerate_subtables_context_t : unsigned i = 0; #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE - unsigned cache_user_idx = (unsigned) -1; - unsigned cache_user_cost = 0; + unsigned subtable_cache_user_idx = (unsigned) -1; + unsigned subtable_cache_user_cost = 0; #endif }; @@ -1191,38 +1232,50 @@ static inline bool match_class (hb_glyph_info_t &info, unsigned value, const voi const ClassDef &class_def = *reinterpret_cast(data); return class_def.get_class (info.codepoint) == value; } -static inline bool match_class_cached (hb_glyph_info_t &info, unsigned value, const void *data) +static inline unsigned get_class_cached (const ClassDef &class_def, hb_glyph_info_t &info) { unsigned klass = info.syllable(); if (klass < 255) - return klass == value; - const ClassDef &class_def = *reinterpret_cast(data); + return klass; klass = class_def.get_class (info.codepoint); if (likely (klass < 255)) info.syllable() = klass; - return klass == value; + return klass; } -static inline bool match_class_cached1 (hb_glyph_info_t &info, unsigned value, const void *data) +static inline bool match_class_cached (hb_glyph_info_t &info, unsigned value, const void *data) +{ + const ClassDef &class_def = *reinterpret_cast(data); + return get_class_cached (class_def, info) == value; +} +static inline unsigned get_class_cached1 (const ClassDef &class_def, hb_glyph_info_t &info) { unsigned klass = info.syllable() & 0x0F; if (klass < 15) - return klass == value; - const ClassDef &class_def = *reinterpret_cast(data); + return klass; klass = class_def.get_class (info.codepoint); if (likely (klass < 15)) info.syllable() = (info.syllable() & 0xF0) | klass; - return klass == value; + return klass; } -static inline bool match_class_cached2 (hb_glyph_info_t &info, unsigned value, const void *data) +static inline bool match_class_cached1 (hb_glyph_info_t &info, unsigned value, const void *data) +{ + const ClassDef &class_def = *reinterpret_cast(data); + return get_class_cached1 (class_def, info) == value; +} +static inline unsigned get_class_cached2 (const ClassDef &class_def, hb_glyph_info_t &info) { unsigned klass = (info.syllable() & 0xF0) >> 4; if (klass < 15) - return klass == value; - const ClassDef &class_def = *reinterpret_cast(data); + return klass; klass = class_def.get_class (info.codepoint); if (likely (klass < 15)) info.syllable() = (info.syllable() & 0x0F) | (klass << 4); - return klass == value; + return klass; +} +static inline bool match_class_cached2 (hb_glyph_info_t &info, unsigned value, const void *data) +{ + const ClassDef &class_def = *reinterpret_cast(data); + return get_class_cached2 (class_def, info) == value; } static inline bool match_coverage (hb_glyph_info_t &info, unsigned value, const void *data) { @@ -1261,16 +1314,24 @@ static bool match_input (hb_ot_apply_context_t *c, match_func_t match_func, const void *match_data, unsigned int *end_position, - unsigned int *match_positions, unsigned int *p_total_component_count = nullptr) { TRACE_APPLY (nullptr); - if (unlikely (count > HB_MAX_CONTEXT_LENGTH)) return_trace (false); - hb_buffer_t *buffer = c->buffer; - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + if (count == 1) + { + *end_position = buffer->idx + 1; + c->match_positions[0] = buffer->idx; + if (p_total_component_count) + *p_total_component_count = _hb_glyph_info_get_lig_num_comps (&buffer->cur()); + return_trace (true); + } + + if (unlikely (count > HB_MAX_CONTEXT_LENGTH)) return_trace (false); + + auto &skippy_iter = c->iter_input; skippy_iter.reset (buffer->idx); skippy_iter.set_match_func (match_func, match_data); skippy_iter.set_glyph_data (input); @@ -1319,7 +1380,10 @@ static bool match_input (hb_ot_apply_context_t *c, return_trace (false); } - match_positions[i] = skippy_iter.idx; + if (unlikely (i + 1 > c->match_positions.length && + !c->match_positions.resize_dirty (i + 1))) + return_trace (false); + c->match_positions.arrayZ[i] = skippy_iter.idx; unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx]); unsigned int this_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]); @@ -1349,7 +1413,7 @@ static bool match_input (hb_ot_apply_context_t *c, j--; } - if (found && skippy_iter.may_skip (out[j]) == hb_ot_apply_context_t::matcher_t::SKIP_YES) + if (found && skippy_iter.may_skip (out[j]) == matcher_t::SKIP_YES) ligbase = LIGBASE_MAY_SKIP; else ligbase = LIGBASE_MAY_NOT_SKIP; @@ -1379,13 +1443,12 @@ static bool match_input (hb_ot_apply_context_t *c, *p_total_component_count = total_component_count; } - match_positions[0] = buffer->idx; + c->match_positions.arrayZ[0] = buffer->idx; return_trace (true); } static inline bool ligate_input (hb_ot_apply_context_t *c, unsigned int count, /* Including the first glyph */ - const unsigned int *match_positions, /* Including the first glyph */ unsigned int match_end, hb_codepoint_t lig_glyph, unsigned int total_component_count) @@ -1428,10 +1491,10 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, * https://bugzilla.gnome.org/show_bug.cgi?id=437633 */ - bool is_base_ligature = _hb_glyph_info_is_base_glyph (&buffer->info[match_positions[0]]); - bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->info[match_positions[0]]); + bool is_base_ligature = _hb_glyph_info_is_base_glyph (&buffer->info[c->match_positions.arrayZ[0]]); + bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->info[c->match_positions.arrayZ[0]]); for (unsigned int i = 1; i < count; i++) - if (!_hb_glyph_info_is_mark (&buffer->info[match_positions[i]])) + if (!_hb_glyph_info_is_mark (&buffer->info[c->match_positions.arrayZ[i]])) { is_base_ligature = false; is_mark_ligature = false; @@ -1457,7 +1520,7 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, for (unsigned int i = 1; i < count; i++) { - while (buffer->idx < match_positions[i] && buffer->successful) + while (buffer->idx < c->match_positions.arrayZ[i] && buffer->successful) { if (is_ligature) { @@ -1512,8 +1575,14 @@ static bool match_backtrack (hb_ot_apply_context_t *c, { TRACE_APPLY (nullptr); - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; - skippy_iter.reset (c->buffer->backtrack_len ()); + if (!count) + { + *match_start = c->buffer->backtrack_len (); + return_trace (true); + } + + auto &skippy_iter = c->iter_context; + skippy_iter.reset_back (c->buffer->backtrack_len ()); skippy_iter.set_match_func (match_func, match_data); skippy_iter.set_glyph_data (backtrack); @@ -1545,7 +1614,13 @@ static bool match_lookahead (hb_ot_apply_context_t *c, { TRACE_APPLY (nullptr); - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; + if (!count) + { + *end_index = start_index; + return_trace (true); + } + + auto &skippy_iter = c->iter_context; assert (start_index >= 1); skippy_iter.reset (start_index - 1); skippy_iter.set_match_func (match_func, match_data); @@ -1696,7 +1771,6 @@ static inline void recurse_lookups (context_t *c, static inline void apply_lookup (hb_ot_apply_context_t *c, unsigned int count, /* Including the first glyph */ - unsigned int *match_positions, /* Including the first glyph */ unsigned int lookupCount, const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */ unsigned int match_end) @@ -1704,9 +1778,6 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, hb_buffer_t *buffer = c->buffer; int end; - unsigned int *match_positions_input = match_positions; - unsigned int match_positions_count = count; - /* All positions are distance from beginning of *output* buffer. * Adjust. */ { @@ -1716,7 +1787,7 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, int delta = bl - buffer->idx; /* Convert positions to new indexing. */ for (unsigned int j = 0; j < count; j++) - match_positions[j] += delta; + c->match_positions.arrayZ[j] += delta; } for (unsigned int i = 0; i < lookupCount && buffer->successful; i++) @@ -1728,10 +1799,10 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, unsigned int orig_len = buffer->backtrack_len () + buffer->lookahead_len (); /* This can happen if earlier recursed lookups deleted many entries. */ - if (unlikely (match_positions[idx] >= orig_len)) + if (unlikely (c->match_positions.arrayZ[idx] >= orig_len)) continue; - if (unlikely (!buffer->move_to (match_positions[idx]))) + if (unlikely (!buffer->move_to (c->match_positions.arrayZ[idx]))) break; if (unlikely (buffer->max_ops <= 0)) @@ -1790,9 +1861,9 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, */ end += delta; - if (end < int (match_positions[idx])) + if (end < int (c->match_positions.arrayZ[idx])) { - /* End might end up being smaller than match_positions[idx] if the recursed + /* End might end up being smaller than match_positions.arrayZ[idx] if the recursed * lookup ended up removing many items. * Just never rewind end beyond start of current position, since that is * not possible in the recursed lookup. Also adjust delta as such. @@ -1800,8 +1871,8 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, * https://bugs.chromium.org/p/chromium/issues/detail?id=659496 * https://github.com/harfbuzz/harfbuzz/issues/1611 */ - delta += match_positions[idx] - end; - end = match_positions[idx]; + delta += c->match_positions.arrayZ[idx] - end; + end = c->match_positions.arrayZ[idx]; } unsigned int next = idx + 1; /* next now is the position after the recursed lookup. */ @@ -1810,27 +1881,9 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, { if (unlikely (delta + count > HB_MAX_CONTEXT_LENGTH)) break; - if (unlikely (delta + count > match_positions_count)) - { - unsigned new_match_positions_count = hb_max (delta + count, hb_max(match_positions_count, 4u) * 1.5); - if (match_positions == match_positions_input) - { - match_positions = (unsigned int *) hb_malloc (new_match_positions_count * sizeof (match_positions[0])); - if (unlikely (!match_positions)) - break; - memcpy (match_positions, match_positions_input, count * sizeof (match_positions[0])); - match_positions_count = new_match_positions_count; - } - else - { - unsigned int *new_match_positions = (unsigned int *) hb_realloc (match_positions, new_match_positions_count * sizeof (match_positions[0])); - if (unlikely (!new_match_positions)) - break; - match_positions = new_match_positions; - match_positions_count = new_match_positions_count; - } - } - + if (unlikely (count + delta > c->match_positions.length && + !c->match_positions.resize_dirty (count + delta))) + return; } else { @@ -1840,23 +1893,20 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, } /* Shift! */ - memmove (match_positions + next + delta, match_positions + next, - (count - next) * sizeof (match_positions[0])); + memmove (c->match_positions + next + delta, c->match_positions + next, + (count - next) * sizeof (c->match_positions.arrayZ[0])); next += delta; count += delta; /* Fill in new entries. */ for (unsigned int j = idx + 1; j < next; j++) - match_positions[j] = match_positions[j - 1] + 1; + c->match_positions.arrayZ[j] = c->match_positions.arrayZ[j - 1] + 1; /* And fixup the rest. */ for (; next < count; next++) - match_positions[next] += delta; + c->match_positions.arrayZ[next] += delta; } - if (match_positions != match_positions_input) - hb_free (match_positions); - assert (end >= 0); (void) buffer->move_to (end); } @@ -1950,34 +2000,25 @@ static inline bool context_would_apply_lookup (hb_would_apply_context_t *c, } template -HB_ALWAYS_INLINE -static bool context_apply_lookup (hb_ot_apply_context_t *c, - unsigned int inputCount, /* Including the first glyph (not matched) */ - const HBUINT input[], /* Array of input values--start with second glyph */ - unsigned int lookupCount, - const LookupRecord lookupRecord[], - const ContextApplyLookupContext &lookup_context) +static inline bool context_apply_lookup (hb_ot_apply_context_t *c, + unsigned int inputCount, /* Including the first glyph (not matched) */ + const HBUINT input[], /* Array of input values--start with second glyph */ + unsigned int lookupCount, + const LookupRecord lookupRecord[], + const ContextApplyLookupContext &lookup_context) { if (unlikely (inputCount > HB_MAX_CONTEXT_LENGTH)) return false; - unsigned match_positions_stack[4]; - unsigned *match_positions = match_positions_stack; - if (unlikely (inputCount > ARRAY_LENGTH (match_positions_stack))) - { - match_positions = (unsigned *) hb_malloc (hb_max (inputCount, 1u) * sizeof (match_positions[0])); - if (unlikely (!match_positions)) - return false; - } unsigned match_end = 0; bool ret = false; if (match_input (c, inputCount, input, lookup_context.funcs.match, lookup_context.match_data, - &match_end, match_positions)) + &match_end)) { c->buffer->unsafe_to_break (c->buffer->idx, match_end); apply_lookup (c, - inputCount, match_positions, + inputCount, lookupCount, lookupRecord, match_end); ret = true; @@ -1988,12 +2029,34 @@ static bool context_apply_lookup (hb_ot_apply_context_t *c, ret = false; } - if (unlikely (match_positions != match_positions_stack)) - hb_free (match_positions); - return ret; } +static inline bool context_cache_func (hb_ot_apply_context_t *c, hb_ot_subtable_cache_op_t op) +{ + switch (op) + { + case hb_ot_subtable_cache_op_t::ENTER: + { + if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable)) + return false; + auto &info = c->buffer->info; + unsigned count = c->buffer->len; + for (unsigned i = 0; i < count; i++) + info[i].syllable() = 255; + c->new_syllables = 255; + return true; + } + case hb_ot_subtable_cache_op_t::LEAVE: + { + c->new_syllables = (unsigned) -1; + HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable); + break; + } + } + return false; +} + template struct Rule { @@ -2209,24 +2272,29 @@ struct RuleSet * * Replicated from LigatureSet::apply(). */ - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + /* We use the iter_context instead of iter_input, to avoid skipping + * default-ignorables and such. + * + * Related: https://github.com/harfbuzz/harfbuzz/issues/4813 + */ + auto &skippy_iter = c->iter_context; skippy_iter.reset (c->buffer->idx); skippy_iter.set_match_func (match_always, nullptr); skippy_iter.set_glyph_data ((HBUINT16 *) nullptr); - unsigned unsafe_to = (unsigned) -1, unsafe_to1 = 0, unsafe_to2 = 0; + unsigned unsafe_to = (unsigned) -1, unsafe_to1, unsafe_to2 = 0; hb_glyph_info_t *first = nullptr, *second = nullptr; bool matched = skippy_iter.next (); if (likely (matched)) { - first = &c->buffer->info[skippy_iter.idx]; - unsafe_to = skippy_iter.idx + 1; - if (skippy_iter.may_skip (c->buffer->info[skippy_iter.idx])) { /* Can't use the fast path if eg. the next char is a default-ignorable * or other skippable. */ goto slow; } + + first = &c->buffer->info[skippy_iter.idx]; + unsafe_to1 = skippy_iter.idx + 1; } else { @@ -2242,8 +2310,15 @@ struct RuleSet ; } matched = skippy_iter.next (); - if (likely (matched && !skippy_iter.may_skip (c->buffer->info[skippy_iter.idx]))) + if (likely (matched)) { + if (skippy_iter.may_skip (c->buffer->info[skippy_iter.idx])) + { + /* Can't use the fast path if eg. the next char is a default-ignorable + * or other skippable. */ + goto slow; + } + second = &c->buffer->info[skippy_iter.idx]; unsafe_to2 = skippy_iter.idx + 1; } @@ -2280,6 +2355,15 @@ struct RuleSet { if (unsafe_to == (unsigned) -1) unsafe_to = unsafe_to1; + + // Skip ahead to next possible first glyph match. + for (; i + 1 < num_rules; i++) + { + const auto &r2 = this+rule.arrayZ[i + 1]; + const auto &input2 = r2.inputZ; + if (r2.inputCount <= 1 || input2.arrayZ[0] != input.arrayZ[0]) + break; + } } } if (likely (unsafe_to != (unsigned) -1)) @@ -2622,46 +2706,37 @@ struct ContextFormat2_5 unsigned cache_cost () const { - unsigned c = (this+classDef).cost () * ruleSet.len; - return c >= 4 ? c : 0; + return (this+classDef).cost (); } - static void * cache_func (void *p, hb_ot_lookup_cache_op_t op) + static bool cache_func (hb_ot_apply_context_t *c, hb_ot_subtable_cache_op_t op) { - switch (op) - { - case hb_ot_lookup_cache_op_t::CREATE: - return (void *) true; - case hb_ot_lookup_cache_op_t::ENTER: - { - hb_ot_apply_context_t *c = (hb_ot_apply_context_t *) p; - if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable)) - return (void *) false; - auto &info = c->buffer->info; - unsigned count = c->buffer->len; - for (unsigned i = 0; i < count; i++) - info[i].syllable() = 255; - c->new_syllables = 255; - return (void *) true; - } - case hb_ot_lookup_cache_op_t::LEAVE: - { - hb_ot_apply_context_t *c = (hb_ot_apply_context_t *) p; - c->new_syllables = (unsigned) -1; - HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable); - return nullptr; - } - case hb_ot_lookup_cache_op_t::DESTROY: - return nullptr; - } - return nullptr; + return context_cache_func (c, op); } - bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } - bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); } - bool _apply (hb_ot_apply_context_t *c, bool cached) const + struct external_cache_t + { + hb_ot_layout_binary_cache_t coverage; + }; + void *external_cache_create () const + { + external_cache_t *cache = (external_cache_t *) hb_malloc (sizeof (external_cache_t)); + if (likely (cache)) + { + cache->coverage.clear (); + } + return cache; + } + bool apply_cached (hb_ot_apply_context_t *c, void *external_cache) const { return _apply (c, true, external_cache); } + bool apply (hb_ot_apply_context_t *c, void *external_cache) const { return _apply (c, false, external_cache); } + bool _apply (hb_ot_apply_context_t *c, bool cached, void *external_cache) const { TRACE_APPLY (this); +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + external_cache_t *cache = (external_cache_t *) external_cache; + unsigned int index = (this+coverage).get_coverage_binary (c->buffer->cur().codepoint, cache ? &cache->coverage : nullptr); +#else unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); +#endif if (index == NOT_COVERED) return_trace (false); const ClassDef &class_def = this+classDef; @@ -2671,10 +2746,7 @@ struct ContextFormat2_5 &class_def }; - if (cached && c->buffer->cur().syllable() < 255) - index = c->buffer->cur().syllable (); - else - index = class_def.get_class (c->buffer->cur().codepoint); + index = cached ? get_class_cached (class_def, c->buffer->cur()) : class_def.get_class (c->buffer->cur().codepoint); const RuleSet &rule_set = this+ruleSet[index]; return_trace (rule_set.apply (c, lookup_context)); } @@ -2919,9 +2991,9 @@ struct Context template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward (ds)...)); case 2: hb_barrier (); return_trace (c->dispatch (u.format2, std::forward (ds)...)); case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward (ds)...)); @@ -2935,7 +3007,7 @@ struct Context protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ ContextFormat1_4 format1; ContextFormat2_5 format2; ContextFormat3 format3; @@ -3069,27 +3141,18 @@ static inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c } template -HB_ALWAYS_INLINE -static bool chain_context_apply_lookup (hb_ot_apply_context_t *c, - unsigned int backtrackCount, - const HBUINT backtrack[], - unsigned int inputCount, /* Including the first glyph (not matched) */ - const HBUINT input[], /* Array of input values--start with second glyph */ - unsigned int lookaheadCount, - const HBUINT lookahead[], - unsigned int lookupCount, - const LookupRecord lookupRecord[], - const ChainContextApplyLookupContext &lookup_context) +static inline bool chain_context_apply_lookup (hb_ot_apply_context_t *c, + unsigned int backtrackCount, + const HBUINT backtrack[], + unsigned int inputCount, /* Including the first glyph (not matched) */ + const HBUINT input[], /* Array of input values--start with second glyph */ + unsigned int lookaheadCount, + const HBUINT lookahead[], + unsigned int lookupCount, + const LookupRecord lookupRecord[], + const ChainContextApplyLookupContext &lookup_context) { if (unlikely (inputCount > HB_MAX_CONTEXT_LENGTH)) return false; - unsigned match_positions_stack[4]; - unsigned *match_positions = match_positions_stack; - if (unlikely (inputCount > ARRAY_LENGTH (match_positions_stack))) - { - match_positions = (unsigned *) hb_malloc (hb_max (inputCount, 1u) * sizeof (match_positions[0])); - if (unlikely (!match_positions)) - return false; - } unsigned start_index = c->buffer->out_len; unsigned end_index = c->buffer->idx; @@ -3098,15 +3161,14 @@ static bool chain_context_apply_lookup (hb_ot_apply_context_t *c, if (!(match_input (c, inputCount, input, lookup_context.funcs.match[1], lookup_context.match_data[1], - &match_end, match_positions) && (end_index = match_end) + &match_end) && (end_index = match_end) && match_lookahead (c, lookaheadCount, lookahead, lookup_context.funcs.match[2], lookup_context.match_data[2], match_end, &end_index))) { c->buffer->unsafe_to_concat (c->buffer->idx, end_index); - ret = false; - goto done; + return false; } if (!match_backtrack (c, @@ -3115,19 +3177,14 @@ static bool chain_context_apply_lookup (hb_ot_apply_context_t *c, &start_index)) { c->buffer->unsafe_to_concat_from_outbuffer (start_index, end_index); - ret = false; - goto done; + return false; } c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index); apply_lookup (c, - inputCount, match_positions, + inputCount, lookupCount, lookupRecord, match_end); - done: - - if (unlikely (match_positions != match_positions_stack)) - hb_free (match_positions); return ret; } @@ -3411,33 +3468,29 @@ struct ChainRuleSet * * Replicated from LigatureSet::apply(). */ - /* If the input skippy has non-auto joiners behavior (as in Indic shapers), - * skip this fast path, as we don't distinguish between input & lookahead - * matching in the fast path. + /* We use the iter_context instead of iter_input, to avoid skipping + * default-ignorables and such. * - * https://github.com/harfbuzz/harfbuzz/issues/4813 + * Related: https://github.com/harfbuzz/harfbuzz/issues/4813 */ - if (!c->auto_zwnj || !c->auto_zwj) - goto slow; - - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + auto &skippy_iter = c->iter_context; skippy_iter.reset (c->buffer->idx); skippy_iter.set_match_func (match_always, nullptr); skippy_iter.set_glyph_data ((HBUINT16 *) nullptr); - unsigned unsafe_to = (unsigned) -1, unsafe_to1 = 0, unsafe_to2 = 0; + unsigned unsafe_to = (unsigned) -1, unsafe_to1, unsafe_to2 = 0; hb_glyph_info_t *first = nullptr, *second = nullptr; bool matched = skippy_iter.next (); if (likely (matched)) { - first = &c->buffer->info[skippy_iter.idx]; - unsafe_to1 = skippy_iter.idx + 1; - if (skippy_iter.may_skip (c->buffer->info[skippy_iter.idx])) { /* Can't use the fast path if eg. the next char is a default-ignorable * or other skippable. */ goto slow; } + + first = &c->buffer->info[skippy_iter.idx]; + unsafe_to1 = skippy_iter.idx + 1; } else { @@ -3458,8 +3511,15 @@ struct ChainRuleSet ; } matched = skippy_iter.next (); - if (likely (matched && !skippy_iter.may_skip (c->buffer->info[skippy_iter.idx]))) + if (likely (matched)) { + if (skippy_iter.may_skip (c->buffer->info[skippy_iter.idx])) + { + /* Can't use the fast path if eg. the next char is a default-ignorable + * or other skippable. */ + goto slow; + } + second = &c->buffer->info[skippy_iter.idx]; unsafe_to2 = skippy_iter.idx + 1; } @@ -3475,7 +3535,7 @@ struct ChainRuleSet const auto &input = StructAfter (r.backtrack); const auto &lookahead = StructAfter (input); - unsigned lenP1 = hb_max ((unsigned) input.lenP1, 1u); + unsigned lenP1 = input.lenP1; if (lenP1 > 1 ? (!match_input || match_input (*first, input.arrayZ[0], input_data)) @@ -3483,6 +3543,7 @@ struct ChainRuleSet (!lookahead.len || !match_lookahead || match_lookahead (*first, lookahead.arrayZ[0], lookahead_data))) { + lenP1 = hb_max (lenP1, 1u); if (!second || (lenP1 > 2 ? (!match_input || @@ -3505,6 +3566,18 @@ struct ChainRuleSet { if (unsafe_to == (unsigned) -1) unsafe_to = unsafe_to1; + + if (lenP1 > 1) + { + // Skip ahead to next possible first glyph match. + for (; i + 1 < num_rules; i++) + { + const auto &r2 = this+rule.arrayZ[i + 1]; + const auto &input2 = StructAfter (r2.backtrack); + if (input2.lenP1 <= 1 || input2.arrayZ[0] != input.arrayZ[0]) + break; + } + } } } if (likely (unsafe_to != (unsigned) -1)) @@ -3873,45 +3946,37 @@ struct ChainContextFormat2_5 unsigned cache_cost () const { - return (this+lookaheadClassDef).cost () * ruleSet.len; + return (this+inputClassDef).cost () + (this+lookaheadClassDef).cost (); } - static void * cache_func (void *p, hb_ot_lookup_cache_op_t op) + static bool cache_func (hb_ot_apply_context_t *c, hb_ot_subtable_cache_op_t op) { - switch (op) - { - case hb_ot_lookup_cache_op_t::CREATE: - return (void *) true; - case hb_ot_lookup_cache_op_t::ENTER: - { - hb_ot_apply_context_t *c = (hb_ot_apply_context_t *) p; - if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable)) - return (void *) false; - auto &info = c->buffer->info; - unsigned count = c->buffer->len; - for (unsigned i = 0; i < count; i++) - info[i].syllable() = 255; - c->new_syllables = 255; - return (void *) true; - } - case hb_ot_lookup_cache_op_t::LEAVE: - { - hb_ot_apply_context_t *c = (hb_ot_apply_context_t *) p; - c->new_syllables = (unsigned) -1; - HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable); - return nullptr; - } - case hb_ot_lookup_cache_op_t::DESTROY: - return nullptr; - } - return nullptr; + return context_cache_func (c, op); } - bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } - bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); } - bool _apply (hb_ot_apply_context_t *c, bool cached) const + struct external_cache_t + { + hb_ot_layout_binary_cache_t coverage; + }; + void *external_cache_create () const + { + external_cache_t *cache = (external_cache_t *) hb_malloc (sizeof (external_cache_t)); + if (likely (cache)) + { + cache->coverage.clear (); + } + return cache; + } + bool apply_cached (hb_ot_apply_context_t *c, void *external_cache) const { return _apply (c, true, external_cache); } + bool apply (hb_ot_apply_context_t *c, void *external_cache) const { return _apply (c, false, external_cache); } + bool _apply (hb_ot_apply_context_t *c, bool cached, void *external_cache) const { TRACE_APPLY (this); +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + external_cache_t *cache = (external_cache_t *) external_cache; + unsigned int index = (this+coverage).get_coverage_binary (c->buffer->cur().codepoint, cache ? &cache->coverage : nullptr); +#else unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); +#endif if (index == NOT_COVERED) return_trace (false); const ClassDef &backtrack_class_def = this+backtrackClassDef; @@ -3929,11 +3994,9 @@ struct ChainContextFormat2_5 &lookahead_class_def} }; - // Note: Corresponds to match_class_cached2 - if (cached && ((c->buffer->cur().syllable() & 0xF0) >> 4) < 15) - index = (c->buffer->cur().syllable () & 0xF0) >> 4; - else - index = input_class_def.get_class (c->buffer->cur().codepoint); + index = cached + ? get_class_cached2 (input_class_def, c->buffer->cur()) + : input_class_def.get_class (c->buffer->cur().codepoint); const ChainRuleSet &rule_set = this+ruleSet[index]; return_trace (rule_set.apply (c, lookup_context)); } @@ -4261,9 +4324,9 @@ struct ChainContext template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward (ds)...)); case 2: hb_barrier (); return_trace (c->dispatch (u.format2, std::forward (ds)...)); case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward (ds)...)); @@ -4277,7 +4340,7 @@ struct ChainContext protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ ChainContextFormat1_4 format1; ChainContextFormat2_5 format2; ChainContextFormat3 format3; @@ -4352,7 +4415,7 @@ struct Extension { unsigned int get_type () const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.get_type (); default:return 0; } @@ -4360,7 +4423,7 @@ struct Extension template const X& get_subtable () const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.template get_subtable (); default:return Null (typename T::SubTable); } @@ -4372,7 +4435,7 @@ struct Extension template typename hb_subset_context_t::return_t dispatch (hb_subset_context_t *c, Ts&&... ds) const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.subset (c); default: return c->default_return_value (); } @@ -4381,9 +4444,9 @@ struct Extension template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: hb_barrier (); return_trace (u.format1.dispatch (c, std::forward (ds)...)); default:return_trace (c->default_return_value ()); } @@ -4391,7 +4454,7 @@ struct Extension protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ ExtensionFormat1 format1; } u; }; @@ -4428,22 +4491,14 @@ struct hb_ot_layout_lookup_accelerator_t for (auto& subtable : hb_iter (thiz->subtables, count)) thiz->digest.union_ (subtable.digest); + thiz->count = count; + #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE - if (c_accelerate_subtables.cache_user_cost < 4) - c_accelerate_subtables.cache_user_idx = (unsigned) -1; - - thiz->cache_user_idx = c_accelerate_subtables.cache_user_idx; - - if (thiz->cache_user_idx != (unsigned) -1) - { - thiz->cache = thiz->subtables[thiz->cache_user_idx].cache_func (nullptr, hb_ot_lookup_cache_op_t::CREATE); - if (!thiz->cache) - thiz->cache_user_idx = (unsigned) -1; - } + thiz->subtable_cache_user_idx = c_accelerate_subtables.subtable_cache_user_idx; for (unsigned i = 0; i < count; i++) - if (i != thiz->cache_user_idx) - thiz->subtables[i].apply_cached_func = thiz->subtables[i].apply_func; + if (i != thiz->subtable_cache_user_idx) + thiz->subtables[i].apply_cached_func = thiz->subtables[i].apply_func; #endif return thiz; @@ -4452,11 +4507,8 @@ struct hb_ot_layout_lookup_accelerator_t void fini () { #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE - if (cache) - { - assert (cache_user_idx != (unsigned) -1); - subtables[cache_user_idx].cache_func (cache, hb_ot_lookup_cache_op_t::DESTROY); - } + for (unsigned i = 0; i < count; i++) + hb_free (subtables[i].external_cache); #endif } @@ -4466,14 +4518,14 @@ struct hb_ot_layout_lookup_accelerator_t #ifndef HB_OPTIMIZE_SIZE HB_ALWAYS_INLINE #endif - bool apply (hb_ot_apply_context_t *c, unsigned subtables_count, bool use_cache) const + bool apply (hb_ot_apply_context_t *c, bool use_cache) const { c->lookup_accel = this; #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE if (use_cache) { return - + hb_iter (hb_iter (subtables, subtables_count)) + + hb_iter (hb_iter (subtables, count)) | hb_map ([&c] (const hb_accelerate_subtables_context_t::hb_applicable_t &_) { return _.apply_cached (c); }) | hb_any ; @@ -4482,7 +4534,7 @@ struct hb_ot_layout_lookup_accelerator_t #endif { return - + hb_iter (hb_iter (subtables, subtables_count)) + + hb_iter (hb_iter (subtables, count)) | hb_map ([&c] (const hb_accelerate_subtables_context_t::hb_applicable_t &_) { return _.apply (c); }) | hb_any ; @@ -4493,8 +4545,8 @@ struct hb_ot_layout_lookup_accelerator_t bool cache_enter (hb_ot_apply_context_t *c) const { #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE - return cache_user_idx != (unsigned) -1 && - subtables[cache_user_idx].cache_enter (c); + return subtable_cache_user_idx != (unsigned) -1 && + subtables[subtable_cache_user_idx].cache_enter (c); #else return false; #endif @@ -4502,19 +4554,17 @@ struct hb_ot_layout_lookup_accelerator_t void cache_leave (hb_ot_apply_context_t *c) const { #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE - subtables[cache_user_idx].cache_leave (c); + subtables[subtable_cache_user_idx].cache_leave (c); #endif } hb_set_digest_t digest; + private: + unsigned count = 0; /* Number of subtables in the array. */ #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE - public: - void *cache = nullptr; - private: - unsigned cache_user_idx = (unsigned) -1; + unsigned subtable_cache_user_idx = (unsigned) -1; #endif - private: hb_accelerate_subtables_context_t::hb_applicable_t subtables[HB_VAR_ARRAY]; }; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc index afe52963201..c73e4dc4b6d 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc @@ -343,7 +343,7 @@ hb_ot_layout_get_glyphs_in_class (hb_face_t *face, * @face: The #hb_face_t to work on * @glyph: The #hb_codepoint_t code point to query * @start_offset: offset of the first attachment point to retrieve - * @point_count: (inout) (optional): Input = the maximum number of attachment points to return; + * @point_count: (inout) (nullable): Input = the maximum number of attachment points to return; * Output = the actual number of attachment points returned (may be zero) * @point_array: (out) (array length=point_count): The array of attachment points found for the query * @@ -373,7 +373,7 @@ hb_ot_layout_get_attach_points (hb_face_t *face, * @direction: The #hb_direction_t text direction to use * @glyph: The #hb_codepoint_t code point to query * @start_offset: offset of the first caret position to retrieve - * @caret_count: (inout) (optional): Input = the maximum number of caret positions to return; + * @caret_count: (inout) (nullable): Input = the maximum number of caret positions to return; * Output = the actual number of caret positions returned (may be zero) * @caret_array: (out) (array length=caret_count): The array of caret positions found for the query * @@ -444,7 +444,7 @@ get_gsubgpos_table (hb_face_t *face, * @face: #hb_face_t to work upon * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @start_offset: offset of the first script tag to retrieve - * @script_count: (inout) (optional): Input = the maximum number of script tags to return; + * @script_count: (inout) (nullable): Input = the maximum number of script tags to return; * Output = the actual number of script tags returned (may be zero) * @script_tags: (out) (array length=script_count): The array of #hb_tag_t script tags found for the query * @@ -541,8 +541,8 @@ hb_ot_layout_table_choose_script (hb_face_t *face, * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @script_count: Number of script tags in the array * @script_tags: Array of #hb_tag_t script tags - * @script_index: (out) (optional): The index of the requested script - * @chosen_script: (out) (optional): #hb_tag_t of the requested script + * @script_index: (out) (nullable): The index of the requested script + * @chosen_script: (out) (nullable): #hb_tag_t of the requested script * * Selects an OpenType script for @table_tag from the @script_tags array. * @@ -613,7 +613,7 @@ hb_ot_layout_table_select_script (hb_face_t *face, * @face: #hb_face_t to work upon * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @start_offset: offset of the first feature tag to retrieve - * @feature_count: (inout) (optional): Input = the maximum number of feature tags to return; + * @feature_count: (inout) (nullable): Input = the maximum number of feature tags to return; * Output = the actual number of feature tags returned (may be zero) * @feature_tags: (out) (array length=feature_count): Array of feature tags found in the table * @@ -683,7 +683,7 @@ hb_ot_layout_table_find_feature (hb_face_t *face, * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @script_index: The index of the requested script tag * @start_offset: offset of the first language tag to retrieve - * @language_count: (inout) (optional): Input = the maximum number of language tags to return; + * @language_count: (inout) (nullable): Input = the maximum number of language tags to return; * Output = the actual number of language tags returned (may be zero) * @language_tags: (out) (array length=language_count): Array of language tags found in the table * @@ -911,7 +911,7 @@ hb_ot_layout_language_get_required_feature (hb_face_t *face, * @script_index: The index of the requested script tag * @language_index: The index of the requested language tag * @start_offset: offset of the first feature tag to retrieve - * @feature_count: (inout) (optional): Input = the maximum number of feature tags to return; + * @feature_count: (inout) (nullable): Input = the maximum number of feature tags to return; * Output: the actual number of feature tags returned (may be zero) * @feature_indexes: (out) (array length=feature_count): The array of feature indexes found for the query * @@ -947,7 +947,7 @@ hb_ot_layout_language_get_feature_indexes (hb_face_t *face, * @script_index: The index of the requested script tag * @language_index: The index of the requested language tag * @start_offset: offset of the first feature tag to retrieve - * @feature_count: (inout) (optional): Input = the maximum number of feature tags to return; + * @feature_count: (inout) (nullable): Input = the maximum number of feature tags to return; * Output = the actual number of feature tags returned (may be zero) * @feature_tags: (out) (array length=feature_count): The array of #hb_tag_t feature tags found for the query * @@ -1035,7 +1035,7 @@ hb_ot_layout_language_find_feature (hb_face_t *face, * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @feature_index: The index of the requested feature * @start_offset: offset of the first lookup to retrieve - * @lookup_count: (inout) (optional): Input = the maximum number of lookups to return; + * @lookup_count: (inout) (nullable): Input = the maximum number of lookups to return; * Output = the actual number of lookups returned (may be zero) * @lookup_indexes: (out) (array length=lookup_count): The array of lookup indexes found for the query * @@ -1386,10 +1386,10 @@ hb_ot_layout_collect_lookups (hb_face_t *face, * @face: #hb_face_t to work upon * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @lookup_index: The index of the feature lookup to query - * @glyphs_before: (out): Array of glyphs preceding the substitution range - * @glyphs_input: (out): Array of input glyphs that would be substituted by the lookup - * @glyphs_after: (out): Array of glyphs following the substitution range - * @glyphs_output: (out): Array of glyphs that would be the substituted output of the lookup + * @glyphs_before: (out) (nullable): Array of glyphs preceding the substitution range + * @glyphs_input: (out) (nullable): Array of input glyphs that would be substituted by the lookup + * @glyphs_after: (out) (nullable): Array of glyphs following the substitution range + * @glyphs_output: (out) (nullable): Array of glyphs that would be the substituted output of the lookup * * Fetches a list of all glyphs affected by the specified lookup in the * specified face's GSUB table or GPOS table. @@ -1473,7 +1473,7 @@ hb_ot_layout_table_find_feature_variations (hb_face_t *face, * @feature_index: The index of the feature to query * @variations_index: The index of the feature variation to query * @start_offset: offset of the first lookup to retrieve - * @lookup_count: (inout) (optional): Input = the maximum number of lookups to return; + * @lookup_count: (inout) (nullable): Input = the maximum number of lookups to return; * Output = the actual number of lookups returned (may be zero) * @lookup_indexes: (out) (array length=lookup_count): The array of lookups found for the query * @@ -1777,15 +1777,15 @@ hb_ot_layout_get_size_params (hb_face_t *face, * @face: #hb_face_t to work upon * @table_tag: table tag to query, "GSUB" or "GPOS". * @feature_index: index of feature to query. - * @label_id: (out) (optional): The ‘name’ table name ID that specifies a string - * for a user-interface label for this feature. (May be NULL.) - * @tooltip_id: (out) (optional): The ‘name’ table name ID that specifies a string + * @label_id: (out) (nullable): The ‘name’ table name ID that specifies a string + * for a user-interface label for this feature. + * @tooltip_id: (out) (nullable): The ‘name’ table name ID that specifies a string * that an application can use for tooltip text for this - * feature. (May be NULL.) - * @sample_id: (out) (optional): The ‘name’ table name ID that specifies sample text - * that illustrates the effect of this feature. (May be NULL.) - * @num_named_parameters: (out) (optional): Number of named parameters. (May be zero.) - * @first_param_id: (out) (optional): The first ‘name’ table name ID used to specify + * feature. + * @sample_id: (out) (nullable): The ‘name’ table name ID that specifies sample text + * that illustrates the effect of this feature. + * @num_named_parameters: (out) (nullable): Number of named parameters. + * @first_param_id: (out) (nullable): The first ‘name’ table name ID used to specify * strings for user-interface labels for the feature * parameters. (Must be zero if numParameters is zero.) * @@ -1852,7 +1852,7 @@ hb_ot_layout_feature_get_name_ids (hb_face_t *face, * @table_tag: table tag to query, "GSUB" or "GPOS". * @feature_index: index of feature to query. * @start_offset: offset of the first character to retrieve - * @char_count: (inout) (optional): Input = the maximum number of characters to return; + * @char_count: (inout) (nullable): Input = the maximum number of characters to return; * Output = the actual number of characters returned (may be zero) * @characters: (out caller-allocates) (array length=char_count): A buffer pointer. * The Unicode codepoints of the characters for which this feature provides @@ -1915,31 +1915,33 @@ struct GPOSProxy static inline bool apply_forward (OT::hb_ot_apply_context_t *c, - const OT::hb_ot_layout_lookup_accelerator_t &accel, - unsigned subtable_count) + const OT::hb_ot_layout_lookup_accelerator_t &accel) { - bool use_cache = accel.cache_enter (c); + bool use_hot_subtable_cache = accel.cache_enter (c); bool ret = false; hb_buffer_t *buffer = c->buffer; - while (buffer->idx < buffer->len && buffer->successful) + while (buffer->successful) { - bool applied = false; - auto &cur = buffer->cur(); - if (accel.digest.may_have (cur.codepoint) && - (cur.mask & c->lookup_mask) && - c->check_glyph_property (&cur, c->lookup_props)) - { - applied = accel.apply (c, subtable_count, use_cache); - } + hb_glyph_info_t *info = buffer->info; + unsigned j = buffer->idx; + while (j < buffer->len && + !(accel.digest.may_have (info[j].codepoint) && + (info[j].mask & c->lookup_mask) && + c->check_glyph_property (&info[j], c->lookup_props))) + j++; + if (unlikely (j > buffer->idx && !buffer->next_glyphs (j - buffer->idx))) + break; + if (buffer->idx >= buffer->len) + break; - if (applied) + if (accel.apply (c, use_hot_subtable_cache)) ret = true; else (void) buffer->next_glyph (); } - if (use_cache) + if (use_hot_subtable_cache) accel.cache_leave (c); return ret; @@ -1947,8 +1949,7 @@ apply_forward (OT::hb_ot_apply_context_t *c, static inline bool apply_backward (OT::hb_ot_apply_context_t *c, - const OT::hb_ot_layout_lookup_accelerator_t &accel, - unsigned subtable_count) + const OT::hb_ot_layout_lookup_accelerator_t &accel) { bool ret = false; hb_buffer_t *buffer = c->buffer; @@ -1958,11 +1959,10 @@ apply_backward (OT::hb_ot_apply_context_t *c, if (accel.digest.may_have (cur.codepoint) && (cur.mask & c->lookup_mask) && c->check_glyph_property (&cur, c->lookup_props)) - ret |= accel.apply (c, subtable_count, false); + ret |= accel.apply (c, false); /* The reverse lookup doesn't "advance" cursor (for good reason). */ buffer->idx--; - } while ((int) buffer->idx >= 0); return ret; @@ -1975,7 +1975,6 @@ apply_string (OT::hb_ot_apply_context_t *c, const OT::hb_ot_layout_lookup_accelerator_t &accel) { hb_buffer_t *buffer = c->buffer; - unsigned subtable_count = lookup.get_subtable_count (); if (unlikely (!buffer->len || !c->lookup_mask)) return false; @@ -1991,7 +1990,7 @@ apply_string (OT::hb_ot_apply_context_t *c, buffer->clear_output (); buffer->idx = 0; - ret = apply_forward (c, accel, subtable_count); + ret = apply_forward (c, accel); if (!Proxy::always_inplace) buffer->sync (); @@ -2001,7 +2000,7 @@ apply_string (OT::hb_ot_apply_context_t *c, /* in-place backward substitution/positioning */ assert (!buffer->have_output); buffer->idx = buffer->len - 1; - ret = apply_backward (c, accel, subtable_count); + ret = apply_backward (c, accel); } return ret; @@ -2017,7 +2016,7 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, unsigned int i = 0; auto *font_data = font->data.ot.get (); - auto *var_store_cache = font_data == HB_SHAPER_DATA_SUCCEEDED ? nullptr : (OT::ItemVariationStore::cache_t *) font_data; + auto *var_store_cache = (OT::hb_scalar_cache_t *) font_data; OT::hb_ot_apply_context_t c (table_index, font, buffer, proxy.accel.get_blob (), var_store_cache); c.set_recurse_func (Proxy::Lookup::template dispatch_recurse_func); @@ -2037,11 +2036,8 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, if (buffer->messaging () && !buffer->message (font, "start lookup %u feature '%c%c%c%c'", lookup_index, HB_UNTAG (lookup.feature_tag))) continue; - /* c.digest is a digest of all the current glyphs in the buffer - * (plus some past glyphs). - * - * Only try applying the lookup if there is any overlap. */ - if (accel->digest.may_intersect (c.digest)) + /* Only try applying the lookup if there is any overlap. */ + if (accel->digest.may_intersect (buffer->digest)) { c.set_lookup_index (lookup_index); c.set_lookup_mask (lookup.mask, false); @@ -2067,7 +2063,7 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, if (stage->pause_func (plan, font, buffer)) { /* Refresh working buffer digest since buffer changed. */ - buffer->collect_codepoints (c.digest); + buffer->update_digest (); } } } @@ -2601,6 +2597,7 @@ hb_ot_layout_get_baseline_with_fallback2 (hb_font_t *font, #endif +#ifndef HB_NO_LAYOUT_RARELY_USED struct hb_get_glyph_alternates_dispatch_t : hb_dispatch_context_t { @@ -2620,14 +2617,13 @@ struct hb_get_glyph_alternates_dispatch_t : ( _dispatch (obj, hb_prioritize, std::forward (ds)...) ) }; -#ifndef HB_NO_LAYOUT_RARELY_USED /** * hb_ot_layout_lookup_get_glyph_alternates: * @face: a face. * @lookup_index: index of the feature lookup to query. * @glyph: a glyph id. * @start_offset: starting offset. - * @alternate_count: (inout) (optional): Input = the maximum number of alternate glyphs to return; + * @alternate_count: (inout) (nullable): Input = the maximum number of alternate glyphs to return; * Output = the actual number of alternate glyphs returned (may be zero). * @alternate_glyphs: (out caller-allocates) (array length=alternate_count): A glyphs buffer. * Alternate glyphs associated with the glyph id. @@ -2654,6 +2650,64 @@ hb_ot_layout_lookup_get_glyph_alternates (hb_face_t *face, return ret; } +struct hb_collect_glyph_alternates_dispatch_t : + hb_dispatch_context_t +{ + static return_t default_return_value () { return false; } + bool stop_sublookup_iteration (return_t r) const { return false; } + + private: + template auto + _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN + ( (obj.collect_glyph_alternates (std::forward (ds)...), true) ) + template auto + _dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN + ( default_return_value () ) + public: + template auto + dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN + ( _dispatch (obj, hb_prioritize, std::forward (ds)...) ) +}; + +/** + * hb_ot_layout_lookup_collect_glyph_alternates: + * @face: a face. + * @lookup_index: index of the feature lookup to query. + * @alternate_count: (inout): mapping from glyph index to number of alternates for that glyph. + * @alternate_glyphs: (inout): mapping from encoded glyph index and alternate index, to alternate glyph ids. + * + * Collects alternates of glyphs from a given GSUB lookup index. + * + * For one-to-one GSUB glyph substitutions, this function collects the + * substituted glyph. + * + * For lookups that assign multiple alternates to a glyph, all alternate glyphs are collected. + * + * For other lookup types, nothing is performed and `false` is returned. + * + * The `alternate_count` mapping will contain the number of alternates for each glyph id. + * Upon entry, this mapping should contain the glyph ids as keys, and the number of alternates + * currently known for each glyph id as values. + * + * The `alternate_glyphs` mapping will contain the alternate glyph ids for each glyph id. + * The mapping is encoded in the following way, upon entry and after processing: + * If G is the glyph id, and A0, A1, ..., A(n-1) are the alternate glyph ids, + * the mapping will contain the following entries: (G + (i << 24)) -> A(i) + * for i = 0, 1, ..., n-1 where n is the number of alternates for G as per `alternate_count`. + * + * Return value: `true` if alternates were collected, `false` otherwise. + * Since: 12.1.0 + */ +HB_EXTERN hb_bool_t +hb_ot_layout_lookup_collect_glyph_alternates (hb_face_t *face, + unsigned lookup_index, + hb_map_t *alternate_count /* IN/OUT */, + hb_map_t *alternate_glyphs /* IN/OUT */) +{ + hb_collect_glyph_alternates_dispatch_t c; + const OT::SubstLookup &lookup = face->table.GSUB->table->get_lookup (lookup_index); + return lookup.dispatch (&c, alternate_count, alternate_glyphs); +} struct hb_position_single_dispatch_t : hb_dispatch_context_t diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.h b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.h index 1d9db1105bd..b814c2acda3 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.h @@ -383,6 +383,12 @@ hb_ot_layout_lookup_get_glyph_alternates (hb_face_t *face, unsigned *alternate_count /* IN/OUT */, hb_codepoint_t *alternate_glyphs /* OUT */); +HB_EXTERN hb_bool_t +hb_ot_layout_lookup_collect_glyph_alternates (hb_face_t *face, + unsigned lookup_index, + hb_map_t *alternate_count /* IN/OUT */, + hb_map_t *alternate_glyphs /* IN/OUT */); + HB_EXTERN hb_bool_t hb_ot_layout_lookup_would_substitute (hb_face_t *face, unsigned int lookup_index, diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.hh index a68c8421e4c..f669ac7c46d 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.hh @@ -217,8 +217,6 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer) if (u >= 0x80u) { - buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII; - if (unlikely (unicode->is_default_ignorable (u))) { buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES; @@ -247,6 +245,7 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer) if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (gen_cat))) { + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_CONTINUATIONS; props |= UPROPS_MASK_CONTINUATION; props |= unicode->modified_combining_class (u)<<8; } @@ -361,8 +360,9 @@ _hb_glyph_info_unhide (hb_glyph_info_t *info) } static inline void -_hb_glyph_info_set_continuation (hb_glyph_info_t *info) +_hb_glyph_info_set_continuation (hb_glyph_info_t *info, hb_buffer_t *buffer) { + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_CONTINUATIONS; info->unicode_props() |= UPROPS_MASK_CONTINUATION; } static inline void @@ -410,18 +410,6 @@ _hb_glyph_info_is_zwj (const hb_glyph_info_t *info) return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & UPROPS_MASK_Cf_ZWJ); } static inline bool -_hb_glyph_info_is_joiner (const hb_glyph_info_t *info) -{ - return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & (UPROPS_MASK_Cf_ZWNJ|UPROPS_MASK_Cf_ZWJ)); -} -static inline void -_hb_glyph_info_flip_joiners (hb_glyph_info_t *info) -{ - if (!_hb_glyph_info_is_unicode_format (info)) - return; - info->unicode_props() ^= UPROPS_MASK_Cf_ZWNJ | UPROPS_MASK_Cf_ZWJ; -} -static inline bool _hb_glyph_info_is_aat_deleted (const hb_glyph_info_t *info) { return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & UPROPS_MASK_Cf_AAT_DELETED); @@ -657,4 +645,18 @@ _hb_buffer_assert_gsubgpos_vars (hb_buffer_t *buffer) #undef lig_props #undef glyph_props +static inline void +_hb_collect_glyph_alternates_add (hb_codepoint_t from, + hb_codepoint_t to, + hb_map_t *alternate_count, + hb_map_t *alternate_glyphs) +{ + hb_codepoint_t zero = 0; + hb_codepoint_t *i = &zero; + alternate_count->has (from, &i); + alternate_glyphs->set (from | (*i << 24), to); + alternate_count->set (from, *i + 1); +} + + #endif /* HB_OT_LAYOUT_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-math-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-math-table.hh index b33e01fd6c9..ad9d7cb03e8 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-math-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-math-table.hh @@ -69,6 +69,8 @@ struct MathValueRecord struct MathConstants { + friend struct MATH; + MathConstants* copy (hb_serialize_context_t *c) const { TRACE_SERIALIZE (this); @@ -1109,8 +1111,8 @@ struct MATH { #ifndef HB_NO_MATH switch HB_CODEPOINT_ENCODE3 (font->face->table.MATH.get_blob ()->length, - get_constant (HB_OT_MATH_CONSTANT_DISPLAY_OPERATOR_MIN_HEIGHT, font), - get_constant (HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT, font)) + (this+mathConstants).minHeight[1], // displayOperatorMinHeight + (this+mathConstants).minHeight[0]) // delimitedSubFormulaMinHeight { /* sha1sum:ab4a4fe054d23061f3c039493d6f665cfda2ecf5 cambria.ttc * sha1sum:086855301bff644f9d8827b88491fcf73a6d4cb9 cambria.ttc diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-post-macroman.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-post-macroman.hh index b4df8aaeeab..269b4d3fe45 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-post-macroman.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-post-macroman.hh @@ -31,264 +31,264 @@ #endif -_S(".notdef") -_S(".null") -_S("nonmarkingreturn") -_S("space") -_S("exclam") -_S("quotedbl") -_S("numbersign") -_S("dollar") -_S("percent") -_S("ampersand") -_S("quotesingle") -_S("parenleft") -_S("parenright") -_S("asterisk") -_S("plus") -_S("comma") -_S("hyphen") -_S("period") -_S("slash") -_S("zero") -_S("one") -_S("two") -_S("three") -_S("four") -_S("five") -_S("six") -_S("seven") -_S("eight") -_S("nine") -_S("colon") -_S("semicolon") -_S("less") -_S("equal") -_S("greater") -_S("question") -_S("at") -_S("A") -_S("B") -_S("C") -_S("D") -_S("E") -_S("F") -_S("G") -_S("H") -_S("I") -_S("J") -_S("K") -_S("L") -_S("M") -_S("N") -_S("O") -_S("P") -_S("Q") -_S("R") -_S("S") -_S("T") -_S("U") -_S("V") -_S("W") -_S("X") -_S("Y") -_S("Z") -_S("bracketleft") -_S("backslash") -_S("bracketright") -_S("asciicircum") -_S("underscore") -_S("grave") -_S("a") -_S("b") -_S("c") -_S("d") -_S("e") -_S("f") -_S("g") -_S("h") -_S("i") -_S("j") -_S("k") -_S("l") -_S("m") -_S("n") -_S("o") -_S("p") -_S("q") -_S("r") -_S("s") -_S("t") -_S("u") -_S("v") -_S("w") -_S("x") -_S("y") -_S("z") -_S("braceleft") -_S("bar") -_S("braceright") -_S("asciitilde") -_S("Adieresis") -_S("Aring") -_S("Ccedilla") -_S("Eacute") -_S("Ntilde") -_S("Odieresis") -_S("Udieresis") -_S("aacute") -_S("agrave") -_S("acircumflex") -_S("adieresis") -_S("atilde") -_S("aring") -_S("ccedilla") -_S("eacute") -_S("egrave") -_S("ecircumflex") -_S("edieresis") -_S("iacute") -_S("igrave") -_S("icircumflex") -_S("idieresis") -_S("ntilde") -_S("oacute") -_S("ograve") -_S("ocircumflex") -_S("odieresis") -_S("otilde") -_S("uacute") -_S("ugrave") -_S("ucircumflex") -_S("udieresis") -_S("dagger") -_S("degree") -_S("cent") -_S("sterling") -_S("section") -_S("bullet") -_S("paragraph") -_S("germandbls") -_S("registered") -_S("copyright") -_S("trademark") -_S("acute") -_S("dieresis") -_S("notequal") -_S("AE") -_S("Oslash") -_S("infinity") -_S("plusminus") -_S("lessequal") -_S("greaterequal") -_S("yen") -_S("mu") -_S("partialdiff") -_S("summation") -_S("product") -_S("pi") -_S("integral") -_S("ordfeminine") -_S("ordmasculine") -_S("Omega") -_S("ae") -_S("oslash") -_S("questiondown") -_S("exclamdown") -_S("logicalnot") -_S("radical") -_S("florin") -_S("approxequal") -_S("Delta") -_S("guillemotleft") -_S("guillemotright") -_S("ellipsis") -_S("nonbreakingspace") -_S("Agrave") -_S("Atilde") -_S("Otilde") -_S("OE") -_S("oe") -_S("endash") -_S("emdash") -_S("quotedblleft") -_S("quotedblright") -_S("quoteleft") -_S("quoteright") -_S("divide") -_S("lozenge") -_S("ydieresis") -_S("Ydieresis") -_S("fraction") -_S("currency") -_S("guilsinglleft") -_S("guilsinglright") -_S("fi") -_S("fl") -_S("daggerdbl") -_S("periodcentered") -_S("quotesinglbase") -_S("quotedblbase") -_S("perthousand") -_S("Acircumflex") -_S("Ecircumflex") -_S("Aacute") -_S("Edieresis") -_S("Egrave") -_S("Iacute") -_S("Icircumflex") -_S("Idieresis") -_S("Igrave") -_S("Oacute") -_S("Ocircumflex") -_S("apple") -_S("Ograve") -_S("Uacute") -_S("Ucircumflex") -_S("Ugrave") -_S("dotlessi") -_S("circumflex") -_S("tilde") -_S("macron") -_S("breve") -_S("dotaccent") -_S("ring") -_S("cedilla") -_S("hungarumlaut") -_S("ogonek") -_S("caron") -_S("Lslash") -_S("lslash") -_S("Scaron") -_S("scaron") -_S("Zcaron") -_S("zcaron") -_S("brokenbar") -_S("Eth") -_S("eth") -_S("Yacute") -_S("yacute") -_S("Thorn") -_S("thorn") -_S("minus") -_S("multiply") -_S("onesuperior") -_S("twosuperior") -_S("threesuperior") -_S("onehalf") -_S("onequarter") -_S("threequarters") -_S("franc") -_S("Gbreve") -_S("gbreve") -_S("Idotaccent") -_S("Scedilla") -_S("scedilla") -_S("Cacute") -_S("cacute") -_S("Ccaron") -_S("ccaron") -_S("dcroat") +HB_STR(".notdef") +HB_STR(".null") +HB_STR("nonmarkingreturn") +HB_STR("space") +HB_STR("exclam") +HB_STR("quotedbl") +HB_STR("numbersign") +HB_STR("dollar") +HB_STR("percent") +HB_STR("ampersand") +HB_STR("quotesingle") +HB_STR("parenleft") +HB_STR("parenright") +HB_STR("asterisk") +HB_STR("plus") +HB_STR("comma") +HB_STR("hyphen") +HB_STR("period") +HB_STR("slash") +HB_STR("zero") +HB_STR("one") +HB_STR("two") +HB_STR("three") +HB_STR("four") +HB_STR("five") +HB_STR("six") +HB_STR("seven") +HB_STR("eight") +HB_STR("nine") +HB_STR("colon") +HB_STR("semicolon") +HB_STR("less") +HB_STR("equal") +HB_STR("greater") +HB_STR("question") +HB_STR("at") +HB_STR("A") +HB_STR("B") +HB_STR("C") +HB_STR("D") +HB_STR("E") +HB_STR("F") +HB_STR("G") +HB_STR("H") +HB_STR("I") +HB_STR("J") +HB_STR("K") +HB_STR("L") +HB_STR("M") +HB_STR("N") +HB_STR("O") +HB_STR("P") +HB_STR("Q") +HB_STR("R") +HB_STR("S") +HB_STR("T") +HB_STR("U") +HB_STR("V") +HB_STR("W") +HB_STR("X") +HB_STR("Y") +HB_STR("Z") +HB_STR("bracketleft") +HB_STR("backslash") +HB_STR("bracketright") +HB_STR("asciicircum") +HB_STR("underscore") +HB_STR("grave") +HB_STR("a") +HB_STR("b") +HB_STR("c") +HB_STR("d") +HB_STR("e") +HB_STR("f") +HB_STR("g") +HB_STR("h") +HB_STR("i") +HB_STR("j") +HB_STR("k") +HB_STR("l") +HB_STR("m") +HB_STR("n") +HB_STR("o") +HB_STR("p") +HB_STR("q") +HB_STR("r") +HB_STR("s") +HB_STR("t") +HB_STR("u") +HB_STR("v") +HB_STR("w") +HB_STR("x") +HB_STR("y") +HB_STR("z") +HB_STR("braceleft") +HB_STR("bar") +HB_STR("braceright") +HB_STR("asciitilde") +HB_STR("Adieresis") +HB_STR("Aring") +HB_STR("Ccedilla") +HB_STR("Eacute") +HB_STR("Ntilde") +HB_STR("Odieresis") +HB_STR("Udieresis") +HB_STR("aacute") +HB_STR("agrave") +HB_STR("acircumflex") +HB_STR("adieresis") +HB_STR("atilde") +HB_STR("aring") +HB_STR("ccedilla") +HB_STR("eacute") +HB_STR("egrave") +HB_STR("ecircumflex") +HB_STR("edieresis") +HB_STR("iacute") +HB_STR("igrave") +HB_STR("icircumflex") +HB_STR("idieresis") +HB_STR("ntilde") +HB_STR("oacute") +HB_STR("ograve") +HB_STR("ocircumflex") +HB_STR("odieresis") +HB_STR("otilde") +HB_STR("uacute") +HB_STR("ugrave") +HB_STR("ucircumflex") +HB_STR("udieresis") +HB_STR("dagger") +HB_STR("degree") +HB_STR("cent") +HB_STR("sterling") +HB_STR("section") +HB_STR("bullet") +HB_STR("paragraph") +HB_STR("germandbls") +HB_STR("registered") +HB_STR("copyright") +HB_STR("trademark") +HB_STR("acute") +HB_STR("dieresis") +HB_STR("notequal") +HB_STR("AE") +HB_STR("Oslash") +HB_STR("infinity") +HB_STR("plusminus") +HB_STR("lessequal") +HB_STR("greaterequal") +HB_STR("yen") +HB_STR("mu") +HB_STR("partialdiff") +HB_STR("summation") +HB_STR("product") +HB_STR("pi") +HB_STR("integral") +HB_STR("ordfeminine") +HB_STR("ordmasculine") +HB_STR("Omega") +HB_STR("ae") +HB_STR("oslash") +HB_STR("questiondown") +HB_STR("exclamdown") +HB_STR("logicalnot") +HB_STR("radical") +HB_STR("florin") +HB_STR("approxequal") +HB_STR("Delta") +HB_STR("guillemotleft") +HB_STR("guillemotright") +HB_STR("ellipsis") +HB_STR("nonbreakingspace") +HB_STR("Agrave") +HB_STR("Atilde") +HB_STR("Otilde") +HB_STR("OE") +HB_STR("oe") +HB_STR("endash") +HB_STR("emdash") +HB_STR("quotedblleft") +HB_STR("quotedblright") +HB_STR("quoteleft") +HB_STR("quoteright") +HB_STR("divide") +HB_STR("lozenge") +HB_STR("ydieresis") +HB_STR("Ydieresis") +HB_STR("fraction") +HB_STR("currency") +HB_STR("guilsinglleft") +HB_STR("guilsinglright") +HB_STR("fi") +HB_STR("fl") +HB_STR("daggerdbl") +HB_STR("periodcentered") +HB_STR("quotesinglbase") +HB_STR("quotedblbase") +HB_STR("perthousand") +HB_STR("Acircumflex") +HB_STR("Ecircumflex") +HB_STR("Aacute") +HB_STR("Edieresis") +HB_STR("Egrave") +HB_STR("Iacute") +HB_STR("Icircumflex") +HB_STR("Idieresis") +HB_STR("Igrave") +HB_STR("Oacute") +HB_STR("Ocircumflex") +HB_STR("apple") +HB_STR("Ograve") +HB_STR("Uacute") +HB_STR("Ucircumflex") +HB_STR("Ugrave") +HB_STR("dotlessi") +HB_STR("circumflex") +HB_STR("tilde") +HB_STR("macron") +HB_STR("breve") +HB_STR("dotaccent") +HB_STR("ring") +HB_STR("cedilla") +HB_STR("hungarumlaut") +HB_STR("ogonek") +HB_STR("caron") +HB_STR("Lslash") +HB_STR("lslash") +HB_STR("Scaron") +HB_STR("scaron") +HB_STR("Zcaron") +HB_STR("zcaron") +HB_STR("brokenbar") +HB_STR("Eth") +HB_STR("eth") +HB_STR("Yacute") +HB_STR("yacute") +HB_STR("Thorn") +HB_STR("thorn") +HB_STR("minus") +HB_STR("multiply") +HB_STR("onesuperior") +HB_STR("twosuperior") +HB_STR("threesuperior") +HB_STR("onehalf") +HB_STR("onequarter") +HB_STR("threequarters") +HB_STR("franc") +HB_STR("Gbreve") +HB_STR("gbreve") +HB_STR("Idotaccent") +HB_STR("Scedilla") +HB_STR("scedilla") +HB_STR("Cacute") +HB_STR("cacute") +HB_STR("Ccaron") +HB_STR("ccaron") +HB_STR("dcroat") #endif /* HB_OT_POST_MACROMAN_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-fallback.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-fallback.cc index 2401e18f0e6..c17e7628975 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-fallback.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-fallback.cc @@ -409,16 +409,13 @@ position_around_base (const hb_ot_shape_plan_t *plan, } static inline void -position_cluster (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer, - unsigned int start, - unsigned int end, - bool adjust_offsets_when_zeroing) +position_cluster_impl (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer, + unsigned int start, + unsigned int end, + bool adjust_offsets_when_zeroing) { - if (end - start < 2) - return; - /* Find the base glyph */ hb_glyph_info_t *info = buffer->info; for (unsigned int i = start; i < end; i++) @@ -441,6 +438,20 @@ position_cluster (const hb_ot_shape_plan_t *plan, } } +static HB_ALWAYS_INLINE void +position_cluster (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer, + unsigned int start, + unsigned int end, + bool adjust_offsets_when_zeroing) +{ + if (end - start < 2) + return; + + position_cluster_impl (plan, font, buffer, start, end, adjust_offsets_when_zeroing); +} + void _hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan, hb_font_t *font, diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.cc index cb941bc7fbd..508ed6a5076 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.cc @@ -78,14 +78,14 @@ static inline void set_glyph (hb_glyph_info_t &info, hb_font_t *font) { - (void) font->get_nominal_glyph (info.codepoint, &info.glyph_index()); + (void) font->get_nominal_glyph (info.codepoint, &info.normalizer_glyph_index()); } static inline void output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph) { /* This is very confusing indeed. */ - buffer->cur().glyph_index() = glyph; + buffer->cur().normalizer_glyph_index() = glyph; (void) buffer->output_glyph (unichar); _hb_glyph_info_set_unicode_props (&buffer->prev(), buffer); } @@ -93,7 +93,7 @@ output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph) static inline void next_char (hb_buffer_t *buffer, hb_codepoint_t glyph) { - buffer->cur().glyph_index() = glyph; + buffer->cur().normalizer_glyph_index() = glyph; (void) buffer->next_glyph (); } @@ -210,7 +210,7 @@ handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, hb_font_t * const font = c->font; for (; buffer->idx < end - 1 && buffer->successful;) { if (unlikely (buffer->unicode->is_variation_selector (buffer->cur(+1).codepoint))) { - if (font->get_variation_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index())) + if (font->get_variation_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().normalizer_glyph_index())) { hb_codepoint_t unicode = buffer->cur().codepoint; (void) buffer->replace_glyphs (2, 1, &unicode); @@ -342,7 +342,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, unsigned int done = font->get_nominal_glyphs (end - buffer->idx, &buffer->cur().codepoint, sizeof (buffer->info[0]), - &buffer->cur().glyph_index(), + &buffer->cur().normalizer_glyph_index(), sizeof (buffer->info[0])); if (unlikely (!buffer->next_glyphs (done))) break; } @@ -456,7 +456,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, buffer->out_len--; /* Remove the second composable. */ /* Modify starter and carry on. */ buffer->out_info[starter].codepoint = composed; - buffer->out_info[starter].glyph_index() = glyph; + buffer->out_info[starter].normalizer_glyph_index() = glyph; _hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer); continue; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.hh index 9f17bdbb243..138e895e8e1 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.hh @@ -32,7 +32,7 @@ /* buffer var allocations, used during the normalization process */ -#define glyph_index() var1.u32 +#define normalizer_glyph_index() var1.u32 struct hb_ot_shape_plan_t; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.cc index 477a7c7fc72..69b188f7aa3 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.cc @@ -44,6 +44,7 @@ #include "hb-ot-face.hh" #include "hb-set.hh" +#include "hb-unicode.hh" #include "hb-aat-layout.hh" #include "hb-ot-layout-gdef-table.hh" @@ -92,7 +93,7 @@ hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t *fac shaper = hb_ot_shaper_categorize (props.script, props.direction, map.chosen_script[0]); script_zero_marks = shaper->zero_width_marks != HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE; - script_fallback_mark_positioning = shaper->fallback_position; + script_fallback_position = shaper->fallback_position; #ifndef HB_NO_AAT_SHAPE /* https://github.com/harfbuzz/harfbuzz/issues/1528 */ @@ -178,12 +179,12 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, #endif #ifndef HB_NO_OT_KERN else if (hb_ot_layout_has_kerning (face)) - plan.apply_kern = true; + plan.apply_kern = script_fallback_position; // Not all shapers apply legacy `kern` #endif else {} } - plan.apply_fallback_kern = !(plan.apply_gpos || plan.apply_kerx || plan.apply_kern); + plan.apply_fallback_kern = script_fallback_position && !(plan.apply_gpos || plan.apply_kerx || plan.apply_kern); plan.zero_marks = script_zero_marks && !plan.apply_kerx && @@ -203,7 +204,7 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, ); plan.fallback_mark_positioning = plan.adjust_mark_positioning_when_zeroing && - script_fallback_mark_positioning; + script_fallback_position; #ifndef HB_NO_AAT_SHAPE /* If we're using morx shaping, we cancel mark position adjustment because @@ -425,25 +426,20 @@ _hb_ot_shaper_face_data_destroy (hb_ot_face_data_t *data) */ struct hb_ot_font_data_t { - OT::ItemVariationStore::cache_t unused; // Just for alignment + OT::hb_scalar_cache_t unused; // Just for alignment }; hb_ot_font_data_t * _hb_ot_shaper_font_data_create (hb_font_t *font) { - if (!font->num_coords) - return (hb_ot_font_data_t *) HB_SHAPER_DATA_SUCCEEDED; - const OT::ItemVariationStore &var_store = font->face->table.GDEF->table->get_var_store (); - auto *cache = (hb_ot_font_data_t *) var_store.create_cache (); - return cache ? cache : (hb_ot_font_data_t *) HB_SHAPER_DATA_SUCCEEDED; + return (hb_ot_font_data_t *) var_store.create_cache (); } void _hb_ot_shaper_font_data_destroy (hb_ot_font_data_t *data) { - if (data == HB_SHAPER_DATA_SUCCEEDED) return; - OT::ItemVariationStore::destroy_cache ((OT::ItemVariationStore::cache_t *) data); + OT::ItemVariationStore::destroy_cache ((OT::hb_scalar_cache_t *) data); } @@ -488,6 +484,9 @@ hb_set_unicode_props (hb_buffer_t *buffer) { _hb_glyph_info_set_unicode_props (&info[i], buffer); + if (info[i].codepoint < 0x80) + continue; + unsigned gen_cat = _hb_glyph_info_get_general_category (&info[i]); if (FLAG_UNSAFE (gen_cat) & (FLAG (HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER) | @@ -502,7 +501,7 @@ hb_set_unicode_props (hb_buffer_t *buffer) if (unlikely (gen_cat == HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL && hb_in_range (info[i].codepoint, 0x1F3FBu, 0x1F3FFu))) { - _hb_glyph_info_set_continuation (&info[i]); + _hb_glyph_info_set_continuation (&info[i], buffer); } /* Regional_Indicators are hairy as hell... * https://github.com/harfbuzz/harfbuzz/issues/2265 */ @@ -510,18 +509,18 @@ hb_set_unicode_props (hb_buffer_t *buffer) { if (_hb_codepoint_is_regional_indicator (info[i - 1].codepoint) && !_hb_glyph_info_is_continuation (&info[i - 1])) - _hb_glyph_info_set_continuation (&info[i]); + _hb_glyph_info_set_continuation (&info[i], buffer); } #ifndef HB_NO_EMOJI_SEQUENCES else if (unlikely (_hb_glyph_info_is_zwj (&info[i]))) { - _hb_glyph_info_set_continuation (&info[i]); + _hb_glyph_info_set_continuation (&info[i], buffer); if (i + 1 < count && _hb_unicode_is_emoji_Extended_Pictographic (info[i + 1].codepoint)) { i++; _hb_glyph_info_set_unicode_props (&info[i], buffer); - _hb_glyph_info_set_continuation (&info[i]); + _hb_glyph_info_set_continuation (&info[i], buffer); } } #endif @@ -540,7 +539,9 @@ hb_set_unicode_props (hb_buffer_t *buffer) * https://github.com/harfbuzz/harfbuzz/issues/3844 */ else if (unlikely (hb_in_ranges (info[i].codepoint, 0xFF9Eu, 0xFF9Fu, 0xE0020u, 0xE007Fu))) - _hb_glyph_info_set_continuation (&info[i]); + _hb_glyph_info_set_continuation (&info[i], buffer); + else if (unlikely (info[i].codepoint == 0x2044u /* FRACTION SLASH */)) + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_FRACTION_SLASH; } } @@ -576,7 +577,7 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font) static void hb_form_clusters (hb_buffer_t *buffer) { - if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII)) + if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_CONTINUATIONS)) return; if (HB_BUFFER_CLUSTER_LEVEL_IS_GRAPHEMES (buffer->cluster_level)) @@ -618,14 +619,14 @@ hb_ensure_native_direction (hb_buffer_t *buffer) for (unsigned i = 0; i < count; i++) { auto gc = _hb_glyph_info_get_general_category (&info[i]); - if (gc == HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) - found_number = true; - else if (HB_UNICODE_GENERAL_CATEGORY_IS_LETTER (gc)) + if (HB_UNICODE_GENERAL_CATEGORY_IS_LETTER (gc)) { found_letter = true; break; } - else if (_hb_codepoint_is_regional_indicator (info[i].codepoint)) + else if (gc == HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) + found_number = true; + else if (unlikely (_hb_codepoint_is_regional_indicator (info[i].codepoint))) found_ri = true; } if ((found_number || found_ri) && !found_letter) @@ -651,59 +652,6 @@ hb_ensure_native_direction (hb_buffer_t *buffer) * Substitute */ -#ifndef HB_NO_VERTICAL -static hb_codepoint_t -hb_vert_char_for (hb_codepoint_t u) -{ - switch (u >> 8) - { - case 0x20: switch (u) { - case 0x2013u: return 0xfe32u; // EN DASH - case 0x2014u: return 0xfe31u; // EM DASH - case 0x2025u: return 0xfe30u; // TWO DOT LEADER - case 0x2026u: return 0xfe19u; // HORIZONTAL ELLIPSIS - } break; - case 0x30: switch (u) { - case 0x3001u: return 0xfe11u; // IDEOGRAPHIC COMMA - case 0x3002u: return 0xfe12u; // IDEOGRAPHIC FULL STOP - case 0x3008u: return 0xfe3fu; // LEFT ANGLE BRACKET - case 0x3009u: return 0xfe40u; // RIGHT ANGLE BRACKET - case 0x300au: return 0xfe3du; // LEFT DOUBLE ANGLE BRACKET - case 0x300bu: return 0xfe3eu; // RIGHT DOUBLE ANGLE BRACKET - case 0x300cu: return 0xfe41u; // LEFT CORNER BRACKET - case 0x300du: return 0xfe42u; // RIGHT CORNER BRACKET - case 0x300eu: return 0xfe43u; // LEFT WHITE CORNER BRACKET - case 0x300fu: return 0xfe44u; // RIGHT WHITE CORNER BRACKET - case 0x3010u: return 0xfe3bu; // LEFT BLACK LENTICULAR BRACKET - case 0x3011u: return 0xfe3cu; // RIGHT BLACK LENTICULAR BRACKET - case 0x3014u: return 0xfe39u; // LEFT TORTOISE SHELL BRACKET - case 0x3015u: return 0xfe3au; // RIGHT TORTOISE SHELL BRACKET - case 0x3016u: return 0xfe17u; // LEFT WHITE LENTICULAR BRACKET - case 0x3017u: return 0xfe18u; // RIGHT WHITE LENTICULAR BRACKET - } break; - case 0xfe: switch (u) { - case 0xfe4fu: return 0xfe34u; // WAVY LOW LINE - } break; - case 0xff: switch (u) { - case 0xff01u: return 0xfe15u; // FULLWIDTH EXCLAMATION MARK - case 0xff08u: return 0xfe35u; // FULLWIDTH LEFT PARENTHESIS - case 0xff09u: return 0xfe36u; // FULLWIDTH RIGHT PARENTHESIS - case 0xff0cu: return 0xfe10u; // FULLWIDTH COMMA - case 0xff1au: return 0xfe13u; // FULLWIDTH COLON - case 0xff1bu: return 0xfe14u; // FULLWIDTH SEMICOLON - case 0xff1fu: return 0xfe16u; // FULLWIDTH QUESTION MARK - case 0xff3bu: return 0xfe47u; // FULLWIDTH LEFT SQUARE BRACKET - case 0xff3du: return 0xfe48u; // FULLWIDTH RIGHT SQUARE BRACKET - case 0xff3fu: return 0xfe33u; // FULLWIDTH LOW LINE - case 0xff5bu: return 0xfe37u; // FULLWIDTH LEFT CURLY BRACKET - case 0xff5du: return 0xfe38u; // FULLWIDTH RIGHT CURLY BRACKET - } break; - } - - return u; -} -#endif - static inline void hb_ot_rotate_chars (const hb_ot_shape_context_t *c) { @@ -729,7 +677,7 @@ hb_ot_rotate_chars (const hb_ot_shape_context_t *c) if (HB_DIRECTION_IS_VERTICAL (c->target_direction) && !c->plan->has_vert) { for (unsigned int i = 0; i < count; i++) { - hb_codepoint_t codepoint = hb_vert_char_for (info[i].codepoint); + hb_codepoint_t codepoint = hb_unicode_funcs_t::vertical_char_for (info[i].codepoint); if (unlikely (codepoint != info[i].codepoint && c->font->has_glyph (codepoint))) info[i].codepoint = codepoint; } @@ -744,7 +692,7 @@ hb_ot_shape_setup_masks_fraction (const hb_ot_shape_context_t *c) return; #endif - if (!(c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII) || + if (!(c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_FRACTION_SLASH) || !c->plan->has_frac) return; @@ -845,7 +793,13 @@ hb_ot_zero_width_default_ignorables (const hb_buffer_t *buffer) unsigned int i = 0; for (i = 0; i < count; i++) if (unlikely (_hb_glyph_info_is_default_ignorable (&info[i]))) - pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset = 0; + { + pos[i].x_advance = pos[i].y_advance = 0; + if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) + pos[i].x_offset = 0; + else + pos[i].y_offset = 0; + } } static void @@ -900,11 +854,11 @@ hb_ot_hide_default_ignorables (hb_buffer_t *buffer, static inline void hb_ot_map_glyphs_fast (hb_buffer_t *buffer) { - /* Normalization process sets up glyph_index(), we just copy it. */ + /* Normalization process sets up normalizer_glyph_index(), we just copy it. */ unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; for (unsigned int i = 0; i < count; i++) - info[i].codepoint = info[i].glyph_index(); + info[i].codepoint = info[i].normalizer_glyph_index(); buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS; } @@ -942,7 +896,7 @@ hb_ot_substitute_default (const hb_ot_shape_context_t *c) hb_ot_rotate_chars (c); - HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index); + HB_BUFFER_ALLOCATE_VAR (buffer, normalizer_glyph_index); _hb_ot_shape_normalize (c->plan, buffer, c->font); @@ -954,7 +908,7 @@ hb_ot_substitute_default (const hb_ot_shape_context_t *c) hb_ot_map_glyphs_fast (buffer); - HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_index); + HB_BUFFER_DEALLOCATE_VAR (buffer, normalizer_glyph_index); } static inline void @@ -969,11 +923,17 @@ hb_ot_substitute_plan (const hb_ot_shape_context_t *c) #ifndef HB_NO_AAT_SHAPE if (unlikely (c->plan->apply_morx)) + { hb_aat_layout_substitute (c->plan, c->font, c->buffer, c->user_features, c->num_user_features); + c->buffer->update_digest (); + } else #endif + { + c->buffer->update_digest (); c->plan->substitute (c->font, buffer); + } } static inline void @@ -1054,23 +1014,16 @@ hb_ot_position_default (const hb_ot_shape_context_t *c) { c->font->get_glyph_h_advances (count, &info[0].codepoint, sizeof(info[0]), &pos[0].x_advance, sizeof(pos[0])); - /* The nil glyph_h_origin() func returns 0, so no need to apply it. */ - if (c->font->has_glyph_h_origin_func ()) - for (unsigned int i = 0; i < count; i++) - c->font->subtract_glyph_h_origin (info[i].codepoint, - &pos[i].x_offset, - &pos[i].y_offset); + // h_origin defaults to zero; only apply it if the font has it. + if (c->font->has_glyph_h_origin_func () || c->font->has_glyph_h_origins_func ()) + c->font->subtract_glyph_h_origins (c->buffer); } else { c->font->get_glyph_v_advances (count, &info[0].codepoint, sizeof(info[0]), &pos[0].y_advance, sizeof(pos[0])); - for (unsigned int i = 0; i < count; i++) - { - c->font->subtract_glyph_v_origin (info[i].codepoint, - &pos[i].x_offset, - &pos[i].y_offset); - } + // v_origin defaults to non-zero; apply even if only fallback is there. + c->font->subtract_glyph_v_origins (c->buffer); } if (c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK) _hb_ot_shape_fallback_spaces (c->plan, c->font, c->buffer); @@ -1079,10 +1032,6 @@ hb_ot_position_default (const hb_ot_shape_context_t *c) static inline void hb_ot_position_plan (const hb_ot_shape_context_t *c) { - unsigned int count = c->buffer->len; - hb_glyph_info_t *info = c->buffer->info; - hb_glyph_position_t *pos = c->buffer->pos; - /* If the font has no GPOS and direction is forward, then when * zeroing mark widths, we shift the mark with it, such that the * mark is positioned hanging over the previous glyph. When @@ -1097,12 +1046,9 @@ hb_ot_position_plan (const hb_ot_shape_context_t *c) /* We change glyph origin to what GPOS expects (horizontal), apply GPOS, change it back. */ - /* The nil glyph_h_origin() func returns 0, so no need to apply it. */ - if (c->font->has_glyph_h_origin_func ()) - for (unsigned int i = 0; i < count; i++) - c->font->add_glyph_h_origin (info[i].codepoint, - &pos[i].x_offset, - &pos[i].y_offset); + // h_origin defaults to zero; only apply it if the font has it. + if (c->font->has_glyph_h_origin_func () || c->font->has_glyph_h_origins_func ()) + c->font->add_glyph_h_origins (c->buffer); hb_ot_layout_position_start (c->font, c->buffer); @@ -1139,12 +1085,9 @@ hb_ot_position_plan (const hb_ot_shape_context_t *c) hb_ot_zero_width_default_ignorables (c->buffer); hb_ot_layout_position_finish_offsets (c->font, c->buffer); - /* The nil glyph_h_origin() func returns 0, so no need to apply it. */ - if (c->font->has_glyph_h_origin_func ()) - for (unsigned int i = 0; i < count; i++) - c->font->subtract_glyph_h_origin (info[i].codepoint, - &pos[i].x_offset, - &pos[i].y_offset); + // h_origin defaults to zero; only apply it if the font has it. + if (c->font->has_glyph_h_origin_func () || c->font->has_glyph_h_origins_func ()) + c->font->subtract_glyph_h_origins (c->buffer); if (c->plan->fallback_mark_positioning) _hb_ot_shape_fallback_mark_position (c->plan, c->font, c->buffer, @@ -1172,8 +1115,33 @@ hb_propagate_flags (hb_buffer_t *buffer) /* Propagate cluster-level glyph flags to be the same on all cluster glyphs. * Simplifies using them. */ - if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS)) + hb_mask_t and_mask = HB_GLYPH_FLAG_DEFINED; + if ((buffer->flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) == 0) + and_mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_CONCAT; + + hb_glyph_info_t *info = buffer->info; + + if ((buffer->flags & HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_TATWEEL) == 0) + { + foreach_cluster (buffer, start, end) + { + if (end - start == 1) + { + info[start].mask &= and_mask; + continue; + } + + unsigned int mask = 0; + for (unsigned int i = start; i < end; i++) + mask |= info[i].mask; + + mask &= and_mask; + + for (unsigned int i = start; i < end; i++) + info[i].mask = mask; + } return; + } /* If we are producing SAFE_TO_INSERT_TATWEEL, then do two things: * @@ -1181,30 +1149,20 @@ hb_propagate_flags (hb_buffer_t *buffer) * are UNSAFE_TO_BREAK, then clear the SAFE_TO_INSERT_TATWEEL, * - Any place that is SAFE_TO_INSERT_TATWEEL, is also now UNSAFE_TO_BREAK. * - * We couldn't make this interaction earlier. It has to be done here. + * We couldn't make this interaction earlier. It has to be done this way. */ - bool flip_tatweel = buffer->flags & HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_TATWEEL; - - bool clear_concat = (buffer->flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) == 0; - - hb_glyph_info_t *info = buffer->info; - foreach_cluster (buffer, start, end) { unsigned int mask = 0; for (unsigned int i = start; i < end; i++) - mask |= info[i].mask & HB_GLYPH_FLAG_DEFINED; + mask |= info[i].mask; - if (flip_tatweel) - { - if (mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK) - mask &= ~HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL; - if (mask & HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL) - mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK | HB_GLYPH_FLAG_UNSAFE_TO_CONCAT; - } + if (mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK) + mask &= ~HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL; + if (mask & HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL) + mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK | HB_GLYPH_FLAG_UNSAFE_TO_CONCAT; - if (clear_concat) - mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_CONCAT; + mask &= and_mask; for (unsigned int i = start; i < end; i++) info[i].mask = mask; @@ -1245,8 +1203,6 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c) _hb_buffer_deallocate_unicode_vars (c->buffer); c->buffer->props.direction = c->target_direction; - - c->buffer->leave (); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.hh index 068d7192d0d..649acddb414 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.hh @@ -150,7 +150,7 @@ struct hb_ot_shape_planner_t static constexpr bool apply_morx = false; #endif bool script_zero_marks : 1; - bool script_fallback_mark_positioning : 1; + bool script_fallback_position : 1; const struct hb_ot_shaper_t *shaper; HB_INTERNAL hb_ot_shape_planner_t (hb_face_t *face, diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-joining-list.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-joining-list.hh index e38686e3ebb..79d3014d3e1 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-joining-list.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-joining-list.hh @@ -6,10 +6,10 @@ * * on files with these headers: * - * # ArabicShaping-16.0.0.txt - * # Date: 2024-07-30 - * # Scripts-16.0.0.txt - * # Date: 2024-04-30, 21:48:40 GMT + * # ArabicShaping-17.0.0.txt + * # Date: 2025-08-14 + * # Scripts-17.0.0.txt + * # Date: 2025-07-24, 13:28:55 GMT */ #ifndef HB_OT_SHAPER_ARABIC_JOINING_LIST_HH diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-table.hh index 19bd72d4218..5f87995ea9c 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-table.hh @@ -6,10 +6,10 @@ * * on files with these headers: * - * # ArabicShaping-16.0.0.txt - * # Date: 2024-07-30 - * # Blocks-16.0.0.txt - * # Date: 2024-02-02 + * # ArabicShaping-17.0.0.txt + * # Date: 2025-08-14 + * # Blocks-17.0.0.txt + * # Date: 2025-08-01 * UnicodeData.txt does not have a header. */ @@ -80,7 +80,7 @@ static const uint8_t joining_table[] = /* Arabic Extended-B */ /* 0860 */ R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,R, - /* 0880 */ R,R,R,C,C,C,D,U,U,D,D,D,D,D,R,X,U,U,X,X,X,X,X,X,X,X,X,X,X,X,X,X, + /* 0880 */ R,R,R,C,C,C,D,U,U,D,D,D,D,D,R,D,U,U,X,X,X,X,X,X,X,X,X,X,X,X,X,X, /* Arabic Extended-A */ @@ -140,9 +140,9 @@ static const uint8_t joining_table[] = /* Arabic Extended-C */ - /* 10EC0 */ R,D,D, + /* 10EC0 */ R,D,D,X,D,D, -#define joining_offset_0x10f30u 1185 +#define joining_offset_0x10f30u 1188 /* Sogdian */ @@ -161,14 +161,14 @@ static const uint8_t joining_table[] = /* 10FA0 */ D,U,D,D,R,R,R,U,D,R,R,D,D,R,D,D, /* 10FC0 */ U,D,R,R,D,U,U,U,U,R,D,L, -#define joining_offset_0x110bdu 1341 +#define joining_offset_0x110bdu 1344 /* Kaithi */ /* 110A0 */ U,X,X, /* 110C0 */ X,X,X,X,X,X,X,X,X,X,X,X,X,U, -#define joining_offset_0x1e900u 1358 +#define joining_offset_0x1e900u 1361 /* Adlam */ @@ -176,7 +176,7 @@ static const uint8_t joining_table[] = /* 1E920 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, /* 1E940 */ D,D,D,D,X,X,X,X,X,X,X,T, -}; /* Table items: 1434; occupancy: 57% */ +}; /* Table items: 1437; occupancy: 58% */ static unsigned int @@ -204,7 +204,7 @@ joining_type (hb_codepoint_t u) if (hb_in_range (u, 0x10AC0u, 0x10AEFu)) return joining_table[u - 0x10AC0u + joining_offset_0x10ac0u]; if (hb_in_range (u, 0x10B80u, 0x10BAFu)) return joining_table[u - 0x10B80u + joining_offset_0x10b80u]; if (hb_in_range (u, 0x10D00u, 0x10D23u)) return joining_table[u - 0x10D00u + joining_offset_0x10d00u]; - if (hb_in_range (u, 0x10EC2u, 0x10EC4u)) return joining_table[u - 0x10EC2u + joining_offset_0x10ec2u]; + if (hb_in_range (u, 0x10EC2u, 0x10EC7u)) return joining_table[u - 0x10EC2u + joining_offset_0x10ec2u]; if (hb_in_range (u, 0x10F30u, 0x10FCBu)) return joining_table[u - 0x10F30u + joining_offset_0x10f30u]; break; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic.cc index 7379bb7f15b..981c0f9224b 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic.cc @@ -654,7 +654,7 @@ postprocess_glyphs_arabic (const hb_ot_shape_plan_t *plan, /* https://www.unicode.org/reports/tr53/ */ -static hb_codepoint_t +static const hb_codepoint_t modifier_combining_marks[] = { 0x0654u, /* ARABIC HAMZA ABOVE */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-hangul.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-hangul.cc index 5c46ebbc281..5f15aff8b7c 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-hangul.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-hangul.cc @@ -427,7 +427,7 @@ const hb_ot_shaper_t _hb_ot_shaper_hangul = HB_TAG_NONE, /* gpos_tag */ HB_OT_SHAPE_NORMALIZATION_MODE_NONE, HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, - false, /* fallback_position */ + true, /* fallback_position */ }; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-machine.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-machine.hh index 25e6d85ef80..76c5e83e30f 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-machine.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-machine.hh @@ -53,7 +53,7 @@ enum indic_syllable_type_t { }; -#line 57 "hb-ot-shaper-indic-machine.hh" +#line 54 "hb-ot-shaper-indic-machine.hh" #define indic_syllable_machine_ex_A 9u #define indic_syllable_machine_ex_C 1u #define indic_syllable_machine_ex_CM 16u @@ -77,7 +77,7 @@ enum indic_syllable_type_t { #define indic_syllable_machine_ex_ZWNJ 5u -#line 81 "hb-ot-shaper-indic-machine.hh" +#line 76 "hb-ot-shaper-indic-machine.hh" static const unsigned char _indic_syllable_machine_trans_keys[] = { 8u, 57u, 4u, 57u, 5u, 57u, 5u, 57u, 13u, 13u, 4u, 57u, 4u, 57u, 4u, 57u, 8u, 57u, 5u, 57u, 5u, 57u, 13u, 13u, 4u, 57u, 4u, 57u, 4u, 57u, 4u, 57u, @@ -1126,7 +1126,7 @@ find_syllables_indic (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 1130 "hb-ot-shaper-indic-machine.hh" +#line 1119 "hb-ot-shaper-indic-machine.hh" { cs = indic_syllable_machine_start; ts = 0; @@ -1142,7 +1142,7 @@ find_syllables_indic (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 1146 "hb-ot-shaper-indic-machine.hh" +#line 1131 "hb-ot-shaper-indic-machine.hh" { int _slen; int _trans; @@ -1156,7 +1156,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 1160 "hb-ot-shaper-indic-machine.hh" +#line 1143 "hb-ot-shaper-indic-machine.hh" } _keys = _indic_syllable_machine_trans_keys + (cs<<1); @@ -1268,7 +1268,7 @@ _eof_trans: #line 117 "hb-ot-shaper-indic-machine.rl" {act = 7;} break; -#line 1272 "hb-ot-shaper-indic-machine.hh" +#line 1232 "hb-ot-shaper-indic-machine.hh" } _again: @@ -1277,7 +1277,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 1281 "hb-ot-shaper-indic-machine.hh" +#line 1239 "hb-ot-shaper-indic-machine.hh" } if ( ++p != pe ) diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-table.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-table.cc index b87c530853b..bf27efee21b 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-table.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-table.cc @@ -6,12 +6,12 @@ * * on files with these headers: * - * # IndicSyllabicCategory-16.0.0.txt - * # Date: 2024-04-30, 21:48:21 GMT - * # IndicPositionalCategory-16.0.0.txt - * # Date: 2024-04-30, 21:48:21 GMT - * # Blocks-16.0.0.txt - * # Date: 2024-02-02 + * # IndicSyllabicCategory-17.0.0.txt + * # Date: 2025-08-01, 04:02:23 GMT + * # IndicPositionalCategory-17.0.0.txt + * # Date: 2025-07-29, 13:35:52 GMT + * # Blocks-17.0.0.txt + * # Date: 2025-08-01 */ #include "hb.hh" diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic.cc index d78b5670f61..bec802429ab 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic.cc @@ -296,11 +296,6 @@ struct indic_shape_plan_t const indic_config_t *config; bool is_old_spec; -#ifndef HB_NO_UNISCRIBE_BUG_COMPATIBLE - bool uniscribe_bug_compatible; -#else - static constexpr bool uniscribe_bug_compatible = false; -#endif mutable hb_atomic_t virama_glyph; hb_indic_would_substitute_feature_t rphf; @@ -327,9 +322,6 @@ data_create_indic (const hb_ot_shape_plan_t *plan) } indic_plan->is_old_spec = indic_plan->config->has_old_spec && ((plan->map.chosen_script[0] & 0x000000FFu) != '2'); -#ifndef HB_NO_UNISCRIBE_BUG_COMPATIBLE - indic_plan->uniscribe_bug_compatible = hb_options ().uniscribe_bug_compatible; -#endif indic_plan->virama_glyph = -1; /* Use zero-context would_substitute() matching for new-spec of the main @@ -943,17 +935,7 @@ initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan, unsigned int start, unsigned int end) { /* We treat placeholder/dotted-circle as if they are consonants, so we - * should just chain. Only if not in compatibility mode that is... */ - - const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data; - if (indic_plan->uniscribe_bug_compatible) - { - /* For dotted-circle, this is what Uniscribe does: - * If dotted-circle is the last glyph, it just does nothing. - * Ie. It doesn't form Reph. */ - if (buffer->info[end - 1].indic_category() == I_Cat(DOTTEDCIRCLE)) - return; - } + * should just chain... */ initial_reordering_consonant_syllable (plan, face, buffer, start, end); } @@ -1347,8 +1329,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan, * Uniscribe doesn't do this. * TEST: U+0930,U+094D,U+0915,U+094B,U+094D */ - if (!indic_plan->uniscribe_bug_compatible && - unlikely (is_halant (info[new_reph_pos]))) + if (unlikely (is_halant (info[new_reph_pos]))) { for (unsigned int i = base + 1; i < new_reph_pos; i++) if (FLAG_UNSAFE (info[i].indic_category()) & (FLAG (I_Cat(M)) | FLAG (I_Cat(MPst)))) @@ -1451,27 +1432,6 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan, else buffer->unsafe_to_break (start - 1, start + 1); } - - - /* - * Finish off the clusters and go home! - */ - if (indic_plan->uniscribe_bug_compatible) - { - switch ((hb_tag_t) plan->props.script) - { - case HB_SCRIPT_TAMIL: - break; - - default: - /* Uniscribe merges the entire syllable into a single cluster... Except for Tamil. - * This means, half forms are submerged into the main consonant's cluster. - * This is unnecessary, and makes cursor positioning harder, but that's what - * Uniscribe does. */ - buffer->merge_clusters (start, end); - break; - } - } } @@ -1501,9 +1461,7 @@ preprocess_text_indic (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, hb_font_t *font) { - const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data; - if (!indic_plan->uniscribe_bug_compatible) - _hb_preprocess_text_vowel_constraints (plan, buffer, font); + _hb_preprocess_text_vowel_constraints (plan, buffer, font); } static bool diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-khmer-machine.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-khmer-machine.hh index e1f657c758a..2442f0341ef 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-khmer-machine.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-khmer-machine.hh @@ -48,7 +48,7 @@ enum khmer_syllable_type_t { }; -#line 52 "hb-ot-shaper-khmer-machine.hh" +#line 49 "hb-ot-shaper-khmer-machine.hh" #define khmer_syllable_machine_ex_C 1u #define khmer_syllable_machine_ex_DOTTEDCIRCLE 11u #define khmer_syllable_machine_ex_H 4u @@ -66,7 +66,7 @@ enum khmer_syllable_type_t { #define khmer_syllable_machine_ex_ZWNJ 5u -#line 70 "hb-ot-shaper-khmer-machine.hh" +#line 65 "hb-ot-shaper-khmer-machine.hh" static const unsigned char _khmer_syllable_machine_trans_keys[] = { 5u, 26u, 5u, 26u, 1u, 15u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 1u, 15u, 5u, 26u, 5u, 26u, @@ -294,7 +294,7 @@ find_syllables_khmer (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 298 "hb-ot-shaper-khmer-machine.hh" +#line 287 "hb-ot-shaper-khmer-machine.hh" { cs = khmer_syllable_machine_start; ts = 0; @@ -310,7 +310,7 @@ find_syllables_khmer (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 314 "hb-ot-shaper-khmer-machine.hh" +#line 299 "hb-ot-shaper-khmer-machine.hh" { int _slen; int _trans; @@ -324,7 +324,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 328 "hb-ot-shaper-khmer-machine.hh" +#line 311 "hb-ot-shaper-khmer-machine.hh" } _keys = _khmer_syllable_machine_trans_keys + (cs<<1); @@ -394,7 +394,7 @@ _eof_trans: #line 98 "hb-ot-shaper-khmer-machine.rl" {act = 3;} break; -#line 398 "hb-ot-shaper-khmer-machine.hh" +#line 368 "hb-ot-shaper-khmer-machine.hh" } _again: @@ -403,7 +403,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 407 "hb-ot-shaper-khmer-machine.hh" +#line 375 "hb-ot-shaper-khmer-machine.hh" } if ( ++p != pe ) diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-khmer.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-khmer.cc index 2a4aed2ab1b..1f5028aa3ee 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-khmer.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-khmer.cc @@ -141,12 +141,6 @@ override_features_khmer (hb_ot_shape_planner_t *plan) * typographical correctness.", hence in overrides... */ map->enable_feature (HB_TAG('c','l','i','g')); - /* Uniscribe does not apply 'kern' in Khmer. */ - if (hb_options ().uniscribe_bug_compatible) - { - map->disable_feature (HB_TAG('k','e','r','n')); - } - map->disable_feature (HB_TAG('l','i','g','a')); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-myanmar-machine.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-myanmar-machine.hh index 64eb761b4ea..6e5fce609bc 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-myanmar-machine.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-myanmar-machine.hh @@ -50,7 +50,7 @@ enum myanmar_syllable_type_t { }; -#line 54 "hb-ot-shaper-myanmar-machine.hh" +#line 51 "hb-ot-shaper-myanmar-machine.hh" #define myanmar_syllable_machine_ex_A 9u #define myanmar_syllable_machine_ex_As 32u #define myanmar_syllable_machine_ex_C 1u @@ -78,7 +78,7 @@ enum myanmar_syllable_type_t { #define myanmar_syllable_machine_ex_ZWNJ 5u -#line 82 "hb-ot-shaper-myanmar-machine.hh" +#line 77 "hb-ot-shaper-myanmar-machine.hh" static const unsigned char _myanmar_syllable_machine_trans_keys[] = { 1u, 57u, 3u, 57u, 5u, 57u, 5u, 57u, 3u, 57u, 5u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 5u, 57u, 1u, 15u, 3u, 57u, 3u, 57u, 3u, 57u, @@ -549,7 +549,7 @@ find_syllables_myanmar (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 553 "hb-ot-shaper-myanmar-machine.hh" +#line 542 "hb-ot-shaper-myanmar-machine.hh" { cs = myanmar_syllable_machine_start; ts = 0; @@ -565,7 +565,7 @@ find_syllables_myanmar (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 569 "hb-ot-shaper-myanmar-machine.hh" +#line 554 "hb-ot-shaper-myanmar-machine.hh" { int _slen; int _trans; @@ -579,7 +579,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 583 "hb-ot-shaper-myanmar-machine.hh" +#line 566 "hb-ot-shaper-myanmar-machine.hh" } _keys = _myanmar_syllable_machine_trans_keys + (cs<<1); @@ -649,7 +649,7 @@ _eof_trans: #line 113 "hb-ot-shaper-myanmar-machine.rl" {act = 3;} break; -#line 653 "hb-ot-shaper-myanmar-machine.hh" +#line 623 "hb-ot-shaper-myanmar-machine.hh" } _again: @@ -658,7 +658,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 662 "hb-ot-shaper-myanmar-machine.hh" +#line 630 "hb-ot-shaper-myanmar-machine.hh" } if ( ++p != pe ) diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-thai.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-thai.cc index a0ea464e775..42fc4bbcc44 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-thai.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-thai.cc @@ -163,7 +163,7 @@ thai_pua_shape (hb_codepoint_t u, thai_action_t action, hb_font_t *font) } -static enum thai_above_state_t +static const enum thai_above_state_t { /* Cluster above looks like: */ T0, /* ⣤ */ T1, /* ⣼ */ @@ -191,7 +191,7 @@ static const struct thai_above_state_machine_edge_t { }; -static enum thai_below_state_t +static const enum thai_below_state_t { B0, /* No descender */ B1, /* Removable descender */ @@ -334,7 +334,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan, /* Is SARA AM. Decompose and reorder. */ (void) buffer->output_glyph (NIKHAHIT_FROM_SARA_AM (u)); - _hb_glyph_info_set_continuation (&buffer->prev()); + _hb_glyph_info_set_continuation (&buffer->prev(), buffer); if (unlikely (!buffer->replace_glyph (SARA_AA_FROM_SARA_AM (u)))) break; /* Make Nikhahit be recognized as a ccc=0 mark when zeroing widths. */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-machine.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-machine.hh index 46f66f7d285..22a5356a877 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-machine.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-machine.hh @@ -53,7 +53,7 @@ enum use_syllable_type_t { }; -#line 57 "hb-ot-shaper-use-machine.hh" +#line 54 "hb-ot-shaper-use-machine.hh" #define use_syllable_machine_ex_B 1u #define use_syllable_machine_ex_CGJ 6u #define use_syllable_machine_ex_CMAbv 31u @@ -100,7 +100,7 @@ enum use_syllable_type_t { #define use_syllable_machine_ex_ZWNJ 14u -#line 104 "hb-ot-shaper-use-machine.hh" +#line 99 "hb-ot-shaper-use-machine.hh" static const unsigned char _use_syllable_machine_trans_keys[] = { 49u, 51u, 0u, 56u, 11u, 56u, 11u, 56u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, @@ -929,7 +929,7 @@ find_syllables_use (hb_buffer_t *buffer) unsigned int act HB_UNUSED; int cs; -#line 933 "hb-ot-shaper-use-machine.hh" +#line 922 "hb-ot-shaper-use-machine.hh" { cs = use_syllable_machine_start; ts = 0; @@ -942,7 +942,7 @@ find_syllables_use (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 946 "hb-ot-shaper-use-machine.hh" +#line 931 "hb-ot-shaper-use-machine.hh" { int _slen; int _trans; @@ -956,7 +956,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 960 "hb-ot-shaper-use-machine.hh" +#line 943 "hb-ot-shaper-use-machine.hh" } _keys = _use_syllable_machine_trans_keys + (cs<<1); @@ -1078,7 +1078,7 @@ _eof_trans: #line 181 "hb-ot-shaper-use-machine.rl" {act = 9;} break; -#line 1082 "hb-ot-shaper-use-machine.hh" +#line 1039 "hb-ot-shaper-use-machine.hh" } _again: @@ -1087,7 +1087,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 1091 "hb-ot-shaper-use-machine.hh" +#line 1046 "hb-ot-shaper-use-machine.hh" } if ( ++p != pe ) diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-table.hh index d3c49949aa8..a69abefdd01 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-table.hh @@ -6,18 +6,18 @@ * * on files with these headers: * - * # IndicSyllabicCategory-16.0.0.txt - * # Date: 2024-04-30, 21:48:21 GMT - * # IndicPositionalCategory-16.0.0.txt - * # Date: 2024-04-30, 21:48:21 GMT - * # ArabicShaping-16.0.0.txt - * # Date: 2024-07-30 - * # DerivedCoreProperties-16.0.0.txt - * # Date: 2024-05-31, 18:09:32 GMT - * # Blocks-16.0.0.txt - * # Date: 2024-02-02 - * # Scripts-16.0.0.txt - * # Date: 2024-04-30, 21:48:40 GMT + * # IndicSyllabicCategory-17.0.0.txt + * # Date: 2025-08-01, 04:02:23 GMT + * # IndicPositionalCategory-17.0.0.txt + * # Date: 2025-07-29, 13:35:52 GMT + * # ArabicShaping-17.0.0.txt + * # Date: 2025-08-14 + * # DerivedCoreProperties-17.0.0.txt + * # Date: 2025-07-30, 23:55:08 GMT + * # Blocks-17.0.0.txt + * # Date: 2025-08-01 + * # Scripts-17.0.0.txt + * # Date: 2025-07-24, 13:28:55 GMT * # Override values For Indic_Syllabic_Category * # Not derivable * # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17 @@ -101,8 +101,9 @@ #ifndef HB_OPTIMIZE_SIZE -static const uint8_t -hb_use_u8[3345] = +#include + +static const uint8_t hb_use_u8[3343]= { 16, 50, 51, 51, 51, 52, 51, 83, 118, 131, 57, 58, 59, 195, 211, 62, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, @@ -126,24 +127,24 @@ hb_use_u8[3345] = 49, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 50, 51, 2, 2, 2, 2, 2, 2, 2, 2, 52, 53, 2, 54, 2, 2, 55, 56, 2, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 2, 70, 71, 72, 73, - 2, 74, 2, 75, 76, 77, 78, 2, 2, 79, 80, 81, 82, 2, 83, 84, - 2, 85, 85, 85, 85, 85, 85, 85, 85, 86, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 87, 2, 2, 2, 2, 2, 2, 2, + 2, 74, 2, 75, 76, 77, 78, 79, 2, 80, 81, 82, 83, 2, 84, 85, + 2, 86, 86, 86, 86, 86, 86, 86, 86, 87, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 88, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 88, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 89, 90, 2, 2, 2, 91, 2, 2, 2, 92, - 93, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 94, 94, 94, 95, 2, 2, 2, 2, 2, + 2, 2, 2, 89, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 90, 91, 2, 2, 2, 92, 2, 2, 2, 93, + 94, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 95, 95, 95, 96, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 96, 97, 2, 2, 2, 2, 2, - 2, 2, 2, 98, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 97, 98, 2, 2, 2, 2, 2, + 2, 2, 2, 99, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 99, 2, 2, 100, 2, 2, 2, 101, 2, 102, 2, 2, 2, - 2, 2, 2, 103, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 104, 104, 105, 106, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 2, 2, 2, 100, 2, 2, 101, 2, 2, 2, 102, 2, 103, 2, 2, 2, + 2, 2, 2, 104, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 105, 105, 106, 107, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 5, 0, 0, 0, 0, 0, 6, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -192,99 +193,99 @@ hb_use_u8[3345] = 48, 48, 48, 48, 15, 82, 83, 84, 85, 86, 87, 0, 0, 0, 0, 88, 0, 9, 0, 0, 30, 0, 89, 81, 90, 2, 2, 2, 2, 9, 0, 0, 0, 42, 42, 91, 92, 2, 2, 2, 2, 2, 2, 2, 2, 13, 9, 0, - 0, 93, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 9, 22, 80, 45, 22, 94, 61, 0, 0, 95, 96, 95, 95, 97, 98, 0, - 0, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 9, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 29, 0, 0, - 0, 2, 2, 2, 2, 2, 9, 0, 0, 2, 2, 2, 52, 99, 45, 0, - 0, 2, 2, 100, 101, 102, 103, 61, 63, 104, 16, 45, 22, 59, 21, 80, - 48, 48, 76, 11, 11, 11, 105, 46, 40, 11, 106, 74, 2, 2, 2, 2, - 2, 2, 2, 107, 22, 20, 20, 22, 48, 48, 22, 108, 2, 2, 2, 9, - 0, 0, 0, 0, 0, 0, 109, 110, 110, 110, 110, 0, 0, 0, 0, 0, - 0, 106, 74, 2, 2, 2, 2, 2, 2, 60, 61, 59, 25, 22, 111, 61, - 2, 2, 2, 2, 107, 22, 23, 45, 45, 102, 112, 0, 0, 0, 0, 0, - 0, 2, 2, 61, 18, 48, 23, 113, 102, 102, 102, 114, 115, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 0, 30, 2, 11, 46, 116, 116, 116, 11, 116, - 116, 15, 116, 116, 116, 26, 0, 40, 0, 0, 0, 117, 51, 11, 5, 0, - 0, 0, 0, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 6, 119, - 120, 42, 42, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 120, - 121, 120, 120, 120, 120, 120, 120, 120, 120, 0, 0, 122, 0, 0, 0, 0, - 0, 0, 7, 122, 0, 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 123, 123, 0, 0, - 0, 2, 2, 2, 2, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, - 124, 0, 123, 123, 0, 0, 0, 0, 0, 2, 53, 2, 108, 2, 10, 2, - 2, 2, 65, 19, 16, 0, 0, 31, 0, 2, 2, 0, 0, 0, 0, 0, - 0, 29, 2, 2, 2, 2, 2, 2, 2, 2, 2, 125, 23, 23, 23, 23, - 23, 23, 23, 126, 0, 0, 0, 0, 0, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 2, 0, 0, 0, 0, 0, 52, 2, 2, 2, 22, 22, 127, 116, - 0, 2, 2, 2, 128, 20, 59, 20, 113, 102, 129, 0, 0, 0, 0, 0, - 0, 11, 130, 2, 2, 2, 2, 2, 2, 2, 131, 23, 22, 20, 48, 132, - 133, 134, 0, 0, 0, 0, 0, 0, 0, 2, 2, 52, 30, 2, 2, 2, - 2, 2, 2, 2, 2, 10, 22, 59, 99, 76, 135, 136, 137, 0, 0, 0, - 0, 2, 138, 2, 2, 2, 2, 139, 0, 30, 2, 42, 5, 0, 79, 15, - 2, 53, 22, 140, 52, 53, 2, 2, 105, 10, 9, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 141, 21, 25, 0, 0, 142, 143, 0, 0, 0, - 0, 2, 65, 45, 23, 80, 47, 144, 0, 81, 81, 81, 81, 81, 81, 81, - 81, 0, 0, 0, 0, 0, 0, 0, 6, 120, 120, 120, 120, 121, 0, 0, - 0, 2, 2, 2, 2, 2, 9, 2, 2, 2, 9, 2, 30, 2, 2, 2, - 2, 2, 30, 2, 2, 2, 30, 9, 0, 128, 20, 27, 31, 0, 0, 145, - 146, 2, 2, 30, 2, 30, 2, 2, 2, 2, 2, 2, 0, 14, 37, 0, - 147, 2, 2, 13, 37, 0, 30, 2, 2, 2, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 30, 2, 2, 9, 2, 2, 11, 41, 0, 0, 0, - 0, 2, 2, 2, 0, 27, 22, 22, 30, 2, 2, 2, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 27, 38, 0, 2, 2, 2, 116, 116, 116, 116, - 116, 148, 2, 9, 0, 0, 0, 0, 0, 2, 14, 14, 0, 0, 0, 0, - 0, 9, 2, 2, 9, 2, 2, 2, 2, 30, 2, 9, 0, 30, 2, 0, - 0, 149, 150, 151, 2, 2, 2, 2, 2, 2, 2, 2, 2, 22, 22, 20, - 20, 20, 22, 22, 134, 0, 0, 0, 0, 0, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 2, 2, 2, 2, 2, 53, 52, 53, 0, 0, 0, 0, - 153, 11, 74, 2, 2, 2, 2, 2, 2, 18, 19, 21, 16, 24, 37, 0, - 0, 0, 31, 0, 0, 0, 0, 0, 0, 11, 49, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 128, 20, 22, 154, 22, 21, 155, 156, 2, 2, 2, 2, - 2, 0, 0, 65, 157, 0, 0, 0, 0, 2, 13, 0, 0, 0, 0, 0, - 0, 2, 65, 25, 20, 20, 20, 22, 22, 108, 158, 0, 0, 56, 159, 31, - 160, 30, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 23, - 19, 22, 22, 161, 44, 0, 0, 0, 49, 128, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 9, 9, 2, 2, 30, 2, 2, 2, 2, 2, 2, 2, - 30, 2, 2, 2, 2, 2, 2, 2, 10, 18, 19, 21, 22, 162, 31, 0, - 0, 11, 11, 30, 2, 2, 2, 9, 30, 9, 2, 30, 2, 2, 58, 17, - 23, 16, 23, 47, 32, 33, 32, 34, 0, 0, 0, 0, 35, 0, 0, 0, - 2, 2, 23, 0, 11, 11, 11, 46, 0, 11, 11, 46, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 30, 0, 9, 2, 2, 2, 30, 45, 59, 20, - 20, 31, 33, 32, 32, 25, 163, 29, 164, 165, 37, 0, 0, 0, 0, 0, - 0, 12, 26, 0, 0, 0, 0, 0, 0, 2, 2, 65, 25, 20, 20, 20, - 22, 23, 126, 15, 17, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, - 166, 167, 0, 0, 0, 0, 0, 0, 0, 18, 19, 20, 20, 66, 99, 25, - 160, 11, 168, 9, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, - 65, 25, 20, 20, 0, 48, 48, 11, 169, 37, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2, 2, 20, 0, 23, 19, 20, 20, 21, 16, 82, - 169, 38, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 10, 170, - 25, 20, 22, 22, 168, 9, 0, 0, 0, 2, 2, 2, 2, 2, 9, 43, - 136, 23, 22, 20, 76, 21, 22, 0, 0, 2, 2, 2, 9, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 2, 18, 19, 20, 21, 22, 105, 169, 37, 0, - 0, 2, 2, 2, 9, 30, 0, 2, 2, 2, 2, 30, 9, 2, 2, 2, - 2, 23, 23, 18, 32, 33, 12, 171, 165, 172, 173, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 0, 2, 2, 2, 65, 25, 20, 20, 0, 22, 23, - 29, 108, 0, 33, 0, 0, 0, 0, 0, 52, 20, 22, 22, 22, 140, 2, - 2, 2, 174, 175, 11, 15, 176, 61, 177, 0, 0, 1, 147, 0, 0, 0, - 0, 52, 20, 22, 16, 19, 20, 2, 2, 2, 2, 158, 158, 158, 178, 178, - 178, 178, 178, 178, 15, 179, 0, 30, 0, 22, 20, 20, 31, 22, 22, 11, + 0, 2, 2, 2, 2, 2, 2, 2, 9, 22, 80, 45, 22, 93, 61, 0, + 0, 94, 95, 94, 94, 96, 97, 0, 0, 2, 2, 2, 2, 2, 2, 2, + 0, 2, 2, 9, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, + 0, 2, 2, 2, 2, 29, 0, 0, 0, 2, 2, 2, 2, 2, 9, 0, + 0, 2, 2, 2, 52, 98, 45, 0, 0, 2, 2, 99, 100, 101, 102, 61, + 63, 103, 16, 45, 22, 59, 21, 80, 48, 48, 76, 11, 11, 11, 104, 46, + 40, 11, 105, 74, 2, 2, 2, 2, 2, 2, 2, 106, 22, 20, 20, 22, + 48, 48, 22, 107, 2, 2, 2, 9, 0, 0, 0, 0, 0, 0, 108, 109, + 109, 109, 109, 0, 0, 0, 0, 0, 0, 105, 74, 2, 2, 2, 2, 2, + 2, 60, 61, 59, 25, 22, 110, 61, 2, 2, 2, 2, 106, 22, 23, 45, + 45, 101, 111, 0, 0, 0, 0, 0, 0, 2, 2, 61, 18, 48, 23, 112, + 101, 101, 101, 113, 114, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 30, + 2, 11, 46, 115, 115, 115, 11, 115, 115, 15, 115, 115, 115, 26, 0, 40, + 0, 0, 0, 116, 51, 11, 5, 0, 0, 0, 0, 0, 0, 0, 117, 0, + 0, 0, 0, 0, 0, 0, 6, 118, 119, 42, 42, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 119, 119, 120, 119, 119, 119, 119, 119, 119, 119, + 119, 0, 0, 121, 0, 0, 0, 0, 0, 0, 7, 121, 0, 0, 0, 0, + 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 0, 0, 0, 0, 122, 122, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, + 30, 0, 0, 0, 0, 0, 0, 0, 123, 0, 122, 122, 0, 0, 0, 0, + 0, 2, 53, 2, 107, 2, 10, 2, 2, 2, 65, 19, 16, 0, 0, 31, + 0, 2, 2, 0, 0, 0, 0, 0, 0, 29, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 124, 23, 23, 23, 23, 23, 23, 23, 125, 0, 0, 0, 0, + 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, 0, 0, 0, 0, 0, + 52, 2, 2, 2, 22, 22, 126, 115, 0, 2, 2, 2, 127, 20, 59, 20, + 112, 101, 128, 0, 0, 0, 0, 0, 0, 11, 129, 2, 2, 2, 2, 2, + 2, 2, 130, 23, 22, 20, 48, 131, 132, 133, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 52, 30, 2, 2, 2, 2, 2, 2, 2, 2, 10, 22, 59, + 98, 76, 134, 135, 136, 0, 0, 0, 0, 2, 137, 2, 2, 2, 2, 138, + 0, 30, 2, 42, 5, 0, 79, 15, 2, 139, 20, 53, 127, 139, 2, 2, + 140, 10, 9, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 141, 21, + 25, 0, 0, 142, 143, 0, 0, 0, 0, 2, 65, 45, 23, 80, 47, 144, + 0, 81, 81, 81, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 0, 0, + 6, 119, 119, 119, 119, 120, 0, 0, 0, 2, 2, 2, 2, 2, 9, 2, + 2, 2, 9, 2, 30, 2, 2, 2, 2, 2, 30, 2, 2, 2, 30, 9, + 0, 127, 20, 27, 31, 0, 0, 145, 146, 2, 2, 30, 2, 30, 2, 2, + 2, 2, 2, 2, 0, 14, 37, 0, 147, 2, 2, 13, 37, 0, 30, 2, + 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 2, 2, + 9, 2, 2, 11, 41, 0, 0, 0, 0, 2, 2, 2, 0, 27, 22, 22, + 30, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 27, 38, + 0, 2, 2, 2, 115, 115, 115, 115, 115, 148, 2, 9, 0, 0, 0, 0, + 0, 2, 14, 14, 0, 0, 0, 0, 0, 9, 2, 2, 9, 2, 2, 2, + 2, 30, 2, 9, 0, 30, 2, 0, 0, 149, 150, 151, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 22, 22, 20, 20, 20, 22, 22, 133, 0, 0, 0, + 0, 0, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 2, 2, 2, 2, + 2, 53, 52, 53, 0, 0, 0, 0, 153, 11, 74, 2, 2, 2, 2, 2, + 2, 18, 19, 21, 16, 24, 37, 0, 0, 0, 31, 0, 0, 0, 0, 0, + 0, 11, 49, 2, 2, 2, 2, 2, 2, 2, 2, 2, 127, 20, 22, 154, + 22, 21, 155, 156, 2, 2, 2, 2, 2, 0, 0, 65, 157, 0, 0, 0, + 0, 2, 13, 0, 0, 0, 0, 0, 0, 2, 65, 25, 20, 20, 20, 22, + 22, 107, 158, 0, 0, 56, 159, 31, 160, 30, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 23, 19, 22, 22, 161, 44, 0, 0, 0, + 49, 127, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 9, 9, 2, 2, + 30, 2, 2, 2, 2, 2, 2, 2, 30, 2, 2, 2, 2, 2, 2, 2, + 10, 18, 19, 21, 22, 162, 31, 0, 0, 11, 11, 30, 2, 2, 2, 9, + 30, 9, 2, 30, 2, 2, 58, 17, 23, 16, 23, 47, 32, 33, 32, 34, + 0, 0, 0, 0, 35, 0, 0, 0, 2, 2, 23, 0, 11, 11, 11, 46, + 0, 11, 11, 46, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 30, 0, + 9, 2, 2, 2, 30, 45, 59, 20, 20, 31, 33, 32, 32, 25, 163, 29, + 164, 165, 37, 0, 0, 0, 0, 0, 0, 12, 26, 0, 0, 0, 0, 0, + 0, 2, 2, 65, 25, 20, 20, 20, 22, 23, 125, 15, 17, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 0, 0, 166, 167, 0, 0, 0, 0, 0, 0, + 0, 18, 19, 20, 20, 66, 98, 25, 160, 11, 168, 9, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 2, 2, 65, 25, 20, 20, 0, 48, 48, 11, + 169, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 20, + 0, 23, 19, 20, 20, 21, 16, 82, 169, 38, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 10, 170, 25, 20, 22, 22, 168, 9, 0, 0, + 0, 2, 2, 2, 2, 2, 9, 43, 135, 23, 22, 20, 76, 21, 22, 0, + 0, 2, 2, 2, 9, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 18, + 19, 20, 21, 22, 104, 169, 37, 0, 0, 2, 2, 2, 9, 30, 0, 2, + 2, 2, 2, 30, 9, 2, 2, 2, 2, 23, 23, 18, 32, 33, 12, 171, + 165, 172, 173, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 2, 2, + 2, 65, 25, 20, 20, 0, 22, 23, 29, 107, 0, 33, 0, 0, 0, 0, + 0, 52, 20, 22, 22, 22, 139, 2, 2, 2, 174, 140, 11, 15, 175, 61, + 176, 0, 0, 1, 147, 0, 0, 0, 0, 52, 20, 22, 16, 19, 20, 2, + 2, 2, 2, 158, 158, 158, 177, 177, 177, 177, 177, 177, 15, 178, 0, 30, + 0, 16, 20, 16, 16, 0, 0, 0, 0, 22, 20, 20, 31, 22, 22, 11, 169, 0, 61, 61, 61, 61, 61, 61, 61, 66, 21, 82, 46, 0, 0, 0, 0, 2, 2, 2, 9, 2, 30, 2, 2, 52, 22, 22, 31, 0, 38, 22, - 27, 11, 159, 180, 181, 0, 0, 0, 0, 2, 2, 2, 30, 9, 2, 2, + 27, 11, 159, 179, 180, 0, 0, 0, 0, 2, 2, 2, 30, 9, 2, 2, 2, 2, 2, 2, 2, 2, 23, 23, 47, 22, 35, 82, 68, 0, 0, 0, - 0, 2, 182, 66, 47, 0, 0, 0, 0, 11, 183, 2, 2, 2, 2, 2, + 0, 2, 181, 66, 47, 0, 0, 0, 0, 11, 182, 2, 2, 2, 2, 2, 2, 2, 2, 23, 22, 20, 31, 0, 48, 16, 143, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 156, 0, 0, 184, 184, 184, 184, 184, 184, 184, - 184, 185, 185, 185, 186, 187, 185, 184, 184, 188, 184, 184, 189, 190, 190, 190, - 190, 190, 190, 190, 0, 0, 0, 0, 0, 184, 184, 184, 184, 184, 191, 0, - 0, 2, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, 22, 22, 192, 193, - 194, 11, 11, 11, 46, 0, 0, 0, 0, 29, 74, 2, 2, 2, 2, 2, + 0, 2, 2, 2, 2, 2, 156, 0, 0, 183, 183, 183, 183, 183, 183, 183, + 183, 184, 184, 184, 185, 186, 184, 183, 183, 187, 183, 183, 188, 189, 189, 189, + 189, 189, 189, 189, 0, 0, 0, 0, 0, 183, 183, 183, 183, 183, 190, 0, + 0, 2, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, 22, 22, 191, 192, + 193, 11, 11, 11, 46, 0, 0, 0, 0, 29, 74, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 65, 47, 0, 2, 2, 2, 2, 2, 9, 0, - 58, 195, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 0, 0, 0, 40, 116, 26, 0, 0, 0, 0, 0, + 58, 194, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 0, 0, 0, 40, 115, 26, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 30, 2, 2, 2, 2, 2, 0, 58, 37, 0, 6, 120, 120, 120, 121, 0, + 30, 2, 2, 2, 2, 2, 0, 58, 37, 0, 6, 119, 119, 119, 120, 0, 0, 11, 11, 11, 49, 2, 2, 2, 0, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 46, 2, 2, 2, 2, 2, 2, 11, 11, 2, 2, 2, 2, 2, 2, 22, 22, 2, 2, 2, 2, 2, 2, 2, @@ -300,23 +301,21 @@ hb_use_u8[3345] = VMBlw,VMPst, IS, VAbv, MPst, MPre, MBlw, MBlw, B, MBlw, MBlw, VPst,VMPst,VMPst, B, MBlw, VPst, VPre, VAbv, VAbv,VMPst,VMPst,VMBlw, B,VMPst, VBlw, VPst, CGJ, CGJ, VPst,VMAbv,VMAbv, FMAbv, FAbv,CMAbv,FMAbv,VMAbv,FMAbv, VAbv, IS,FMAbv, B,FMAbv, B, CGJ, WJ, CGJ, GB, - CMAbv,CMAbv, B, GB, B, VAbv, SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, - VPre, B, MPre, MBlw, SUB, FAbv, FAbv, MAbv, SUB, Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, - VPst, H, B, O,SMAbv,SMAbv,SMAbv, VPst, IS, RK, RK, VBlw, FAbv,VMPre,VMPre,FMAbv, - CMBlw,VMBlw,VMBlw,VMAbv, CS, O,FMAbv, ZWNJ, CGJ, WJ, WJ, WJ, O,FMPst, O, SB, - SE, O, H, MPst, VPst, H,VMAbv, VAbv,VMBlw, B, VBlw, FPst, VPst, FAbv,VMPst, B, - CMAbv, VAbv, MBlw, MPst, MBlw, H, O, VBlw, MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, - FPst, VBlw, B, B, VPre, O,VMPst, IS, O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv, O, + CMAbv,CMAbv, B, VAbv, SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre, B, + MPre, MBlw, SUB, FAbv, FAbv, MAbv, SUB, Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst, H, + B, O,SMAbv,SMAbv,SMAbv, VPst, IS, RK, RK, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw, + VMBlw,VMAbv, CS, O,FMAbv, ZWNJ, CGJ, WJ, WJ, WJ, O,FMPst, O, SB, SE, O, + H, MPst, VPst, H,VMAbv, VAbv,VMBlw, B, VBlw, FPst, VPst, FAbv,VMPst, B,CMAbv, VAbv, + MBlw, MPst, MBlw, H, O, VBlw, MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, FPst, VBlw, + B, VBlw,VMAbv, B, VPre, O,VMPst, IS, O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv, O, IS,VMBlw, B,VMPst,VMAbv,VMPst, CS, CS, B, N, N, O, HN, VPre, VBlw, VAbv, IS,CMAbv, O, VPst, B, R, R,CMBlw, VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,VMPst, O,VMAbv,CMBlw, IS, R,FMAbv, B, CS, CS, H,CMBlw,VMPst, H,VMPst, VAbv,VMAbv, - VPst, MPst, R, MPst,CMBlw, B,FMBlw, VBlw,VMAbv, CS, SUB, SUB, GB, FBlw, FBlw,CMAbv, - IS, VBlw, IS, R, MBlw, GB, VAbv, R,VMPst, G, G, J, J, J, SB, SE, - J, HR, G, G, HM, HM, HM, G, O, MPre, MPre, MPst,VMAbv, MBlw, VBlw, O, - VBlw, + VPst, MPst, R, MPst,CMBlw, B,FMBlw, CS, SUB, SUB, GB, FBlw, FBlw,CMAbv, IS, VBlw, + IS, R, MBlw, GB, VAbv, R,VMPst, G, G, J, J, J, SB, SE, J, HR, + G, G, HM, HM, HM, G, O, MPre, MPre, MPst,VMAbv, MBlw, VBlw, O, VBlw, }; -static const uint16_t -hb_use_u16[856] = +static const uint16_t hb_use_u16[864]= { 0, 0, 1, 2, 0, 3, 0, 3, 0, 0, 4, 5, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, @@ -330,66 +329,65 @@ hb_use_u16[856] = 73, 74, 75, 76, 77, 0, 0, 0, 10, 10, 78, 79, 80, 81, 82, 83, 84, 85, 0, 0, 0, 0, 0, 0, 10, 86, 10, 87, 10, 88, 89, 90, 10, 10, 10, 91, 92, 93, 2, 0, 94, 0, 10, 10, 10, 10, 10, 95, - 96, 10, 97, 0, 0, 0, 0, 0, 98, 99,100,101, 31, 10,102,103, - 10, 10,104, 10,105,106, 0, 0, 10,107, 10, 10, 10,108,109,110, - 2, 2, 0, 0, 0, 0, 0, 0,111, 10, 10,112,113, 2,114,115, - 116, 10,117, 10, 10, 10,118,119, 10, 10,120,121,122, 0, 0, 0, - 0, 0, 0, 0, 0,123,124,125, 0, 0, 0, 0, 0, 0, 0,126, - 127,128,129, 0, 0, 0,130,131,132, 0, 0, 0, 0, 0, 0,133, - 0, 0, 0, 0,134, 0, 0, 0, 0, 0, 0, 0, 0, 0,135, 0, - 0, 0, 0, 10, 10, 10,136,137, 0, 0,138, 0, 0, 0, 0, 0, - 139, 10,140, 0, 10, 10, 10,141,142, 10, 10,143,144, 2,145,146, - 10, 10,147, 10,148,149, 0, 0,150, 10, 10,151,152, 2,153, 99, - 10, 10,154,155,156, 2, 10,157, 10, 10, 10,158,159, 0,160,161, - 0, 0, 0, 0, 10, 10,162, 2,163, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,164, 0, 0, 0, 0, 0, 0, 0,165, - 0, 0, 0, 0, 0, 0, 0,166,166,167, 34,168, 0, 0, 0, 0, - 169,170, 10,171, 95, 0, 0, 0, 0, 0, 0, 0, 70, 10,172, 0, - 10,173,174, 0, 0, 0, 0, 0, 10, 10,175, 2, 9, 10,176, 10, - 177, 0, 0, 0, 0, 0, 0, 0, 10, 10,178,173, 0, 0, 0, 0, - 0, 0, 0, 10,179,180, 0, 10,181, 0, 0,182,183, 0, 0, 0, - 184, 10, 10,185,186,187,188,189,190, 10, 10,191,192, 0, 0, 0, - 193, 10,194,195,196, 10, 10,197,190, 10, 10,198,199,106,200,103, - 10, 34,201,202,203, 0, 0, 0,204,205, 95, 10, 10,206,207, 2, - 208, 21, 22,209,210,211,212,213,214, 10, 10,215,216,217,218, 0, - 10, 10, 10,219,220,221,222, 0,200, 10, 10,223,224, 2, 0, 0, - 10, 10,225,226,227,228, 0, 0, 10, 10, 10,229,230, 2, 0, 0, - 10, 10,231,232, 2, 10,141, 0, 10,233,234,104,235, 0, 0, 0, - 10, 10,236,237, 0, 0, 0, 0,238,239, 10,240,241, 2, 0, 0, - 0, 0,242, 10, 10,243,244, 0,245, 10, 10,246,247,248, 10, 10, - 249,250, 0, 0, 0, 0, 0, 0, 22, 10,225,251, 8, 10, 71, 19, - 10,252, 74,253, 0, 0, 0, 0,254, 10, 10,255,256, 2,257, 10, - 258,259, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,260, - 261, 49, 10,262,263,264, 0, 0,265,265,265,265,265,265,265,265, - 265,265,265,266,267,268,265,265,265,265,265,265,265,265,265,269, - 10,270,271, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, - 10, 10, 10,272, 0, 0, 0, 0, 0, 0, 0, 0,273, 10,274, 2, - 10, 10, 10, 10,275,276,277,277,278,279, 0, 0, 0, 0,280, 0, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,177, 0,281, - 10, 10, 10, 10, 10, 10,106, 71, 95,282, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,283, 10, 10, 71,284,285, 0, 0, 0, - 0, 10,286, 0, 10, 10,287, 2, 0, 0, 0, 0, 0, 10,288, 2, - 0, 0, 0, 0, 0, 10,289,106, 10, 10, 10, 10,290, 2, 0, 0, - 130,130,130,130,130,130,130,130,163,163,163,163,163,163,163,163, - 163,163,163,163,163,163,163,130, + 96, 10, 97, 0, 0, 0, 0, 0, 10, 98, 99,100, 31, 10,101,102, + 10, 10,103, 10,104,105, 0, 0, 10,106, 10, 10, 10,107,108,109, + 2, 2, 0, 0, 0, 0, 0, 0,110, 10, 10,111,112, 2,113,114, + 115, 10,116, 10, 10, 10,117,118, 10, 10,119,120,121, 0, 0, 0, + 0, 0, 0, 0, 0,122,123,124, 0, 0, 0, 0, 0, 0, 0,125, + 126,127,128, 0, 0, 0,129,130,131, 0, 0, 0, 0, 0, 0,132, + 0, 0, 0, 0,133, 0, 0, 0, 0, 0, 0, 0, 0, 0,134, 0, + 0, 0, 0, 10, 10, 10,135,136, 0, 0,137, 0, 0, 0, 0, 0, + 138, 10,139, 0, 10, 10, 10,140,141, 10, 10,142,143, 2,144,145, + 10, 10,146, 10,147,148, 0, 0,149, 10, 10,150,151, 2,152, 98, + 10, 10,153,154,155, 2, 10,156, 10, 10, 10,157,158, 0,159,160, + 0, 0, 0, 0, 10, 10,161, 2,162, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,163, 0, 0, 0, 0, 0, 0, 0,164, + 0, 0, 0, 0, 0, 0, 0,165,165,166, 34,167, 0, 0, 0, 0, + 168,169, 10,170, 95, 0, 0, 0, 0, 0, 0, 0, 70, 10,171, 0, + 10,172,173, 0, 0, 0, 0, 0, 10, 10,174, 2, 9, 10,175, 10, + 176, 0, 0, 0, 0, 0, 0, 0, 10, 10,177,172, 0, 0, 0, 0, + 0, 0, 0, 10,178,179, 0, 10,180, 0, 0,181,182, 0, 0, 0, + 183, 10, 10,184,185,186,187,188,189, 10, 10,190,191, 0, 0, 0, + 192, 10,193,194,195, 10, 10,196,189, 10, 10,197,198,105,199,102, + 10, 34,200,201,202, 0, 0, 0,203,204, 95, 10, 10,205,206, 2, + 207, 21, 22,208,209,210,211,212,213, 10, 10,214,215,216,217, 0, + 10, 10, 10,218,219,220,221, 0,199, 10, 10,222,223, 2, 0, 0, + 10, 10,224,225,226,227, 0, 0, 10, 10, 10,228,229, 2, 0, 0, + 10, 10,230,231, 2, 10,140, 0, 10,232,233,103,234, 0, 0, 0, + 10, 10,235,236, 0, 0, 0, 0,237,238, 10,239,240, 2, 0, 0, + 0, 0,241, 10, 10,242,243, 0,244, 10, 10,245,246,247, 10, 10, + 248,249, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,250, 0, + 22, 10,224,251, 8, 10, 71, 19, 10,252, 74,253, 0, 0, 0, 0, + 254, 10, 10,255,256, 2,257, 10,258,259, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 10,260,261, 49, 10,262,263,264, 0, 0, + 265,265,265,265,265,265,265,265,265,265,265,266,267,268,265,265, + 265,265,265,265,265,265,265,269, 10,270,271, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 10, 10, 10,272, 0, 0, 0, 0, + 0, 0, 0, 0,273, 10,274, 2, 10, 10, 10, 10,275,276,277,277, + 278,279, 0, 0, 0, 0,280, 0, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10,176, 0,281, 10, 10, 10, 10, 10, 10,105, 71, + 95,282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,283, + 10, 10, 71,284,285, 0, 0, 0, 0, 10,286, 0, 10, 10,287, 2, + 0, 0, 0, 0, 0, 10,288, 2, 0, 0, 0, 0, 0, 10,289,105, + 10, 10, 10, 10,290, 2, 0, 0,129,129,129,129,129,129,129,129, + 162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,129, }; -static inline unsigned -hb_use_b4 (const uint8_t* a, unsigned i) +static inline uint8_t hb_use_b4 (const uint8_t* a, unsigned i) { - return (a[i>>1]>>((i&1u)<<2))&15u; + return (a[i>>1]>>((i&1)<<2))&15; } -static inline uint_fast8_t -hb_use_get_category (unsigned u) +static inline uint8_t hb_use_get_category (unsigned u) { - return u<921600u?hb_use_u8[2953+(((hb_use_u8[625+(((hb_use_u16[((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>3>>5))<<5)+((u>>1>>3>>3)&31u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O; + return u<921600 ? hb_use_u8[2953u+((hb_use_u8[625u+((hb_use_u16[((hb_use_u8[113u+((hb_use_b4(hb_use_u8,((((((((u)>>1))>>3))>>3))>>5)))<<5)+((((((((u)>>1))>>3))>>3))&31)])<<3)+((((((u)>>1))>>3))&7)])<<3)+((((u)>>1))&7)])<<1)+((u)&1)] : O; } #else -static const uint8_t -hb_use_u8[3657] = +#include + +static const uint8_t hb_use_u8[3663]= { 16, 50, 51, 51, 51, 52, 51, 83, 118, 131, 57, 58, 59, 195, 211, 62, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, @@ -405,16 +403,16 @@ hb_use_u8[3657] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 25, 26, 27, 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 29, 30, 1, 1, 1, 1, 1, 31, 1, 1, 1, 1, 32, 33, 1, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 1, 48, 49, 50, - 51, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 54, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 55, 1, 1, 1, 1, 1, 1, 1, 1, 56, 57, 1, 58, 1, - 59, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 60, 61, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 1, - 1, 1, 63, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 64, 65, 1, 66, 67, 1, 1, 1, 68, 1, 1, 1, 1, 1, - 1, 69, 70, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 0, 1, 2, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 53, 53, 53, 54, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 55, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 56, 1, 1, 1, 1, 1, 1, 1, 1, 57, 58, 1, 59, 1, + 60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 61, 62, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 63, 1, 1, + 1, 1, 64, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 65, 66, 1, 67, 68, 1, 1, 1, 69, 1, 1, 1, 1, 1, + 1, 70, 71, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 0, 1, 2, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 0, 0, 9, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, @@ -438,120 +436,120 @@ hb_use_u8[3657] = 0, 0, 0, 0, 0, 56, 179, 180, 0, 56, 181, 182, 0, 56, 183, 184, 185, 186, 187, 188, 0, 0, 0, 0, 0, 56, 189, 0, 0, 0, 0, 0, 0, 190, 191, 192, 0, 0, 193, 194, 195, 196, 197, 198, 56, 199, 0, 0, - 0, 200, 201, 202, 203, 204, 205, 0, 0, 206, 207, 208, 209, 210, 67, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 211, 212, 213, 214, 0, 0, 0, 0, - 0, 215, 215, 215, 215, 215, 215, 215, 215, 215, 216, 217, 215, 215, 215, 215, - 215, 215, 215, 215, 215, 215, 215, 215, 218, 219, 220, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 67, 0, 56, 221, 0, 0, 0, 0, 0, - 0, 0, 0, 222, 223, 0, 0, 0, 0, 56, 56, 224, 225, 226, 0, 0, - 227, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 228, - 229, 56, 56, 56, 230, 231, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0, - 0, 56, 233, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101, 235, 56, - 236, 0, 0, 0, 0, 0, 0, 101, 237, 0, 0, 0, 0, 0, 0, 101, - 238, 56, 56, 239, 0, 0, 0, 0, 0, 240, 240, 240, 240, 240, 240, 240, - 240, 241, 241, 241, 241, 241, 241, 241, 242, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 2, 2, 2, 2, 0, 0, - 0, 0, 0, 0, 0, 0, 3, 4, 0, 5, 0, 0, 0, 0, 0, 6, - 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 10, 11, 11, 11, 11, 0, 0, 0, 9, 12, - 0, 2, 2, 2, 2, 13, 14, 0, 0, 11, 15, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 16, 17, 18, 19, 20, 21, 22, 16, 23, 24, - 25, 12, 26, 27, 20, 2, 2, 2, 2, 2, 20, 0, 2, 2, 2, 2, - 2, 0, 2, 2, 2, 2, 2, 2, 2, 28, 29, 30, 2, 2, 2, 9, - 30, 9, 30, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9, 2, 2, - 2, 9, 9, 0, 2, 2, 0, 17, 18, 19, 20, 31, 32, 33, 32, 34, - 0, 0, 0, 0, 35, 0, 0, 2, 30, 2, 0, 0, 0, 0, 0, 9, - 36, 12, 15, 30, 2, 2, 9, 0, 30, 9, 2, 30, 9, 2, 0, 37, - 18, 19, 31, 0, 27, 38, 27, 39, 0, 40, 0, 0, 0, 30, 2, 9, - 9, 0, 0, 0, 2, 2, 2, 2, 2, 41, 42, 43, 0, 0, 0, 0, - 0, 12, 15, 30, 2, 2, 2, 2, 30, 2, 30, 2, 2, 2, 2, 2, - 2, 9, 2, 30, 2, 2, 0, 17, 18, 19, 20, 21, 27, 22, 35, 24, - 0, 0, 0, 0, 0, 30, 41, 41, 44, 12, 29, 30, 2, 2, 2, 9, - 30, 9, 2, 30, 2, 2, 0, 17, 45, 0, 0, 27, 22, 0, 0, 2, - 30, 30, 0, 0, 0, 0, 0, 0, 0, 0, 46, 30, 2, 2, 9, 0, - 2, 9, 2, 2, 0, 30, 9, 9, 2, 0, 30, 9, 0, 2, 9, 0, - 2, 2, 2, 2, 2, 2, 0, 0, 23, 16, 47, 0, 48, 33, 48, 34, - 0, 0, 0, 0, 35, 0, 0, 0, 0, 15, 29, 49, 2, 2, 2, 9, - 2, 9, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 17, - 22, 16, 23, 47, 22, 38, 22, 39, 0, 0, 0, 27, 31, 2, 9, 0, - 0, 10, 29, 30, 2, 2, 2, 9, 2, 2, 2, 30, 2, 2, 0, 17, - 45, 0, 0, 35, 47, 0, 0, 0, 9, 50, 51, 0, 0, 0, 0, 0, - 0, 11, 29, 2, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 52, 53, - 23, 19, 20, 31, 48, 33, 48, 34, 54, 0, 0, 0, 35, 0, 0, 0, - 30, 12, 29, 30, 2, 2, 2, 2, 2, 2, 2, 2, 9, 0, 2, 2, - 2, 2, 30, 2, 2, 2, 2, 30, 0, 2, 2, 2, 9, 0, 55, 0, - 35, 23, 22, 31, 31, 18, 48, 48, 25, 0, 23, 0, 0, 0, 0, 0, - 0, 2, 0, 2, 9, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, - 0, 2, 2, 56, 56, 57, 0, 0, 18, 2, 2, 2, 2, 30, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 9, 0, 58, 21, 59, 22, 22, 20, 20, - 46, 21, 11, 31, 11, 2, 2, 60, 61, 61, 61, 61, 61, 62, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 63, - 0, 0, 0, 0, 64, 0, 0, 0, 0, 2, 2, 2, 2, 2, 65, 45, - 59, 66, 22, 22, 67, 68, 69, 70, 71, 2, 2, 2, 2, 2, 1, 0, - 5, 2, 2, 2, 23, 20, 2, 2, 72, 71, 73, 74, 65, 73, 29, 29, - 2, 52, 22, 53, 2, 2, 2, 2, 2, 2, 75, 76, 77, 29, 29, 78, - 79, 2, 2, 2, 2, 2, 29, 45, 0, 2, 59, 80, 0, 0, 0, 0, - 30, 2, 59, 47, 0, 0, 0, 0, 0, 2, 59, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 2, 9, 2, 9, 59, 0, 0, 0, 0, 0, - 0, 2, 2, 81, 45, 22, 59, 20, 48, 48, 48, 48, 15, 82, 83, 84, - 85, 86, 87, 0, 0, 0, 0, 88, 0, 9, 0, 0, 30, 0, 89, 81, - 90, 2, 2, 2, 2, 9, 0, 0, 0, 42, 42, 91, 92, 2, 2, 2, - 2, 2, 2, 2, 2, 13, 9, 0, 0, 93, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 9, 22, 80, 45, 22, 94, 61, 0, - 0, 95, 96, 95, 95, 97, 98, 0, 0, 2, 2, 2, 2, 2, 2, 2, + 0, 0, 0, 0, 200, 0, 0, 0, 0, 201, 202, 203, 204, 205, 206, 0, + 0, 207, 208, 209, 210, 211, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 212, 213, 214, 215, 0, 0, 0, 0, 0, 216, 216, 216, 216, 216, 216, 216, + 216, 216, 217, 218, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, + 219, 220, 221, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, + 0, 56, 222, 0, 0, 0, 0, 0, 0, 0, 0, 223, 224, 0, 0, 0, + 0, 56, 56, 225, 226, 227, 0, 0, 228, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 229, 230, 56, 56, 56, 231, 232, 0, 0, + 0, 0, 0, 0, 233, 0, 0, 0, 0, 56, 234, 235, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 101, 236, 56, 237, 0, 0, 0, 0, 0, 0, 101, + 238, 0, 0, 0, 0, 0, 0, 101, 239, 56, 56, 240, 0, 0, 0, 0, + 0, 241, 241, 241, 241, 241, 241, 241, 241, 242, 242, 242, 242, 242, 242, 242, + 243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, + 0, 5, 0, 0, 0, 0, 0, 6, 0, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 11, + 11, 11, 11, 0, 0, 0, 9, 12, 0, 2, 2, 2, 2, 13, 14, 0, + 0, 11, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 16, 17, + 18, 19, 20, 21, 22, 16, 23, 24, 25, 12, 26, 27, 20, 2, 2, 2, + 2, 2, 20, 0, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, + 2, 28, 29, 30, 2, 2, 2, 9, 30, 9, 30, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 9, 2, 2, 2, 9, 9, 0, 2, 2, 0, 17, + 18, 19, 20, 31, 32, 33, 32, 34, 0, 0, 0, 0, 35, 0, 0, 2, + 30, 2, 0, 0, 0, 0, 0, 9, 36, 12, 15, 30, 2, 2, 9, 0, + 30, 9, 2, 30, 9, 2, 0, 37, 18, 19, 31, 0, 27, 38, 27, 39, + 0, 40, 0, 0, 0, 30, 2, 9, 9, 0, 0, 0, 2, 2, 2, 2, + 2, 41, 42, 43, 0, 0, 0, 0, 0, 12, 15, 30, 2, 2, 2, 2, + 30, 2, 30, 2, 2, 2, 2, 2, 2, 9, 2, 30, 2, 2, 0, 17, + 18, 19, 20, 21, 27, 22, 35, 24, 0, 0, 0, 0, 0, 30, 41, 41, + 44, 12, 29, 30, 2, 2, 2, 9, 30, 9, 2, 30, 2, 2, 0, 17, + 45, 0, 0, 27, 22, 0, 0, 2, 30, 30, 0, 0, 0, 0, 0, 0, + 0, 0, 46, 30, 2, 2, 9, 0, 2, 9, 2, 2, 0, 30, 9, 9, + 2, 0, 30, 9, 0, 2, 9, 0, 2, 2, 2, 2, 2, 2, 0, 0, + 23, 16, 47, 0, 48, 33, 48, 34, 0, 0, 0, 0, 35, 0, 0, 0, + 0, 15, 29, 49, 2, 2, 2, 9, 2, 9, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 0, 17, 22, 16, 23, 47, 22, 38, 22, 39, + 0, 0, 0, 27, 31, 2, 9, 0, 0, 10, 29, 30, 2, 2, 2, 9, + 2, 2, 2, 30, 2, 2, 0, 17, 45, 0, 0, 35, 47, 0, 0, 0, + 9, 50, 51, 0, 0, 0, 0, 0, 0, 11, 29, 2, 2, 2, 2, 9, + 2, 2, 2, 2, 2, 2, 52, 53, 23, 19, 20, 31, 48, 33, 48, 34, + 54, 0, 0, 0, 35, 0, 0, 0, 30, 12, 29, 30, 2, 2, 2, 2, + 2, 2, 2, 2, 9, 0, 2, 2, 2, 2, 30, 2, 2, 2, 2, 30, + 0, 2, 2, 2, 9, 0, 55, 0, 35, 23, 22, 31, 31, 18, 48, 48, + 25, 0, 23, 0, 0, 0, 0, 0, 0, 2, 0, 2, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 20, 0, 0, 0, 2, 2, 56, 56, 57, 0, 0, + 18, 2, 2, 2, 2, 30, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9, + 0, 58, 21, 59, 22, 22, 20, 20, 46, 21, 11, 31, 11, 2, 2, 60, + 61, 61, 61, 61, 61, 62, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 63, 0, 0, 0, 0, 64, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 65, 45, 59, 66, 22, 22, 67, 68, 69, 70, + 71, 2, 2, 2, 2, 2, 1, 0, 5, 2, 2, 2, 23, 20, 2, 2, + 72, 71, 73, 74, 65, 73, 29, 29, 2, 52, 22, 53, 2, 2, 2, 2, + 2, 2, 75, 76, 77, 29, 29, 78, 79, 2, 2, 2, 2, 2, 29, 45, + 0, 2, 59, 80, 0, 0, 0, 0, 30, 2, 59, 47, 0, 0, 0, 0, + 0, 2, 59, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 9, + 2, 9, 59, 0, 0, 0, 0, 0, 0, 2, 2, 81, 45, 22, 59, 20, + 48, 48, 48, 48, 15, 82, 83, 84, 85, 86, 87, 0, 0, 0, 0, 88, + 0, 9, 0, 0, 30, 0, 89, 81, 90, 2, 2, 2, 2, 9, 0, 0, + 0, 42, 42, 91, 92, 2, 2, 2, 2, 2, 2, 2, 2, 13, 9, 0, + 0, 2, 2, 2, 2, 2, 2, 2, 9, 22, 80, 45, 22, 93, 61, 0, + 0, 94, 95, 94, 94, 96, 97, 0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 9, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 29, 0, 0, 0, 2, 2, 2, 2, 2, 9, 0, - 0, 2, 2, 2, 52, 99, 45, 0, 0, 2, 2, 100, 101, 102, 103, 61, - 63, 104, 16, 45, 22, 59, 21, 80, 48, 48, 76, 11, 11, 11, 105, 46, - 40, 11, 106, 74, 2, 2, 2, 2, 2, 2, 2, 107, 22, 20, 20, 22, - 48, 48, 22, 108, 2, 2, 2, 9, 0, 0, 0, 0, 0, 0, 109, 110, - 110, 110, 110, 0, 0, 0, 0, 0, 0, 106, 74, 2, 2, 2, 2, 2, - 2, 60, 61, 59, 25, 22, 111, 61, 2, 2, 2, 2, 107, 22, 23, 45, - 45, 102, 112, 0, 0, 0, 0, 0, 0, 2, 2, 61, 18, 48, 23, 113, - 102, 102, 102, 114, 115, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 30, - 2, 11, 46, 116, 116, 116, 11, 116, 116, 15, 116, 116, 116, 26, 0, 40, - 0, 0, 0, 117, 51, 11, 5, 0, 0, 0, 0, 0, 0, 0, 118, 0, - 0, 0, 0, 0, 0, 0, 6, 119, 120, 42, 42, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 120, 120, 121, 120, 120, 120, 120, 120, 120, 120, - 120, 0, 0, 122, 0, 0, 0, 0, 0, 0, 7, 122, 0, 0, 0, 0, + 0, 2, 2, 2, 52, 98, 45, 0, 0, 2, 2, 99, 100, 101, 102, 61, + 63, 103, 16, 45, 22, 59, 21, 80, 48, 48, 76, 11, 11, 11, 104, 46, + 40, 11, 105, 74, 2, 2, 2, 2, 2, 2, 2, 106, 22, 20, 20, 22, + 48, 48, 22, 107, 2, 2, 2, 9, 0, 0, 0, 0, 0, 0, 108, 109, + 109, 109, 109, 0, 0, 0, 0, 0, 0, 105, 74, 2, 2, 2, 2, 2, + 2, 60, 61, 59, 25, 22, 110, 61, 2, 2, 2, 2, 106, 22, 23, 45, + 45, 101, 111, 0, 0, 0, 0, 0, 0, 2, 2, 61, 18, 48, 23, 112, + 101, 101, 101, 113, 114, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 30, + 2, 11, 46, 115, 115, 115, 11, 115, 115, 15, 115, 115, 115, 26, 0, 40, + 0, 0, 0, 116, 51, 11, 5, 0, 0, 0, 0, 0, 0, 0, 117, 0, + 0, 0, 0, 0, 0, 0, 6, 118, 119, 42, 42, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 119, 119, 120, 119, 119, 119, 119, 119, 119, 119, + 119, 0, 0, 121, 0, 0, 0, 0, 0, 0, 7, 121, 0, 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 0, 0, 0, 0, 123, 123, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, - 30, 0, 0, 0, 0, 0, 0, 0, 124, 0, 123, 123, 0, 0, 0, 0, - 0, 2, 53, 2, 108, 2, 10, 2, 2, 2, 65, 19, 16, 0, 0, 31, + 0, 0, 0, 0, 122, 122, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, + 30, 0, 0, 0, 0, 0, 0, 0, 123, 0, 122, 122, 0, 0, 0, 0, + 0, 2, 53, 2, 107, 2, 10, 2, 2, 2, 65, 19, 16, 0, 0, 31, 0, 2, 2, 0, 0, 0, 0, 0, 0, 29, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 125, 23, 23, 23, 23, 23, 23, 23, 126, 0, 0, 0, 0, + 2, 2, 2, 124, 23, 23, 23, 23, 23, 23, 23, 125, 0, 0, 0, 0, 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, 0, 0, 0, 0, 0, - 52, 2, 2, 2, 22, 22, 127, 116, 0, 2, 2, 2, 128, 20, 59, 20, - 113, 102, 129, 0, 0, 0, 0, 0, 0, 11, 130, 2, 2, 2, 2, 2, - 2, 2, 131, 23, 22, 20, 48, 132, 133, 134, 0, 0, 0, 0, 0, 0, + 52, 2, 2, 2, 22, 22, 126, 115, 0, 2, 2, 2, 127, 20, 59, 20, + 112, 101, 128, 0, 0, 0, 0, 0, 0, 11, 129, 2, 2, 2, 2, 2, + 2, 2, 130, 23, 22, 20, 48, 131, 132, 133, 0, 0, 0, 0, 0, 0, 0, 2, 2, 52, 30, 2, 2, 2, 2, 2, 2, 2, 2, 10, 22, 59, - 99, 76, 135, 136, 137, 0, 0, 0, 0, 2, 138, 2, 2, 2, 2, 139, - 0, 30, 2, 42, 5, 0, 79, 15, 2, 53, 22, 140, 52, 53, 2, 2, - 105, 10, 9, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 141, 21, + 98, 76, 134, 135, 136, 0, 0, 0, 0, 2, 137, 2, 2, 2, 2, 138, + 0, 30, 2, 42, 5, 0, 79, 15, 2, 139, 20, 53, 127, 139, 2, 2, + 140, 10, 9, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 141, 21, 25, 0, 0, 142, 143, 0, 0, 0, 0, 2, 65, 45, 23, 80, 47, 144, 0, 81, 81, 81, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 0, 0, - 6, 120, 120, 120, 120, 121, 0, 0, 0, 2, 2, 2, 2, 2, 9, 2, + 6, 119, 119, 119, 119, 120, 0, 0, 0, 2, 2, 2, 2, 2, 9, 2, 2, 2, 9, 2, 30, 2, 2, 2, 2, 2, 30, 2, 2, 2, 30, 9, - 0, 128, 20, 27, 31, 0, 0, 145, 146, 2, 2, 30, 2, 30, 2, 2, + 0, 127, 20, 27, 31, 0, 0, 145, 146, 2, 2, 30, 2, 30, 2, 2, 2, 2, 2, 2, 0, 14, 37, 0, 147, 2, 2, 13, 37, 0, 30, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 2, 2, 9, 2, 2, 11, 41, 0, 0, 0, 0, 2, 2, 2, 0, 27, 22, 22, 30, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 27, 38, - 0, 2, 2, 2, 116, 116, 116, 116, 116, 148, 2, 9, 0, 0, 0, 0, + 0, 2, 2, 2, 115, 115, 115, 115, 115, 148, 2, 9, 0, 0, 0, 0, 0, 2, 14, 14, 0, 0, 0, 0, 0, 9, 2, 2, 9, 2, 2, 2, 2, 30, 2, 9, 0, 30, 2, 0, 0, 149, 150, 151, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 22, 22, 20, 20, 20, 22, 22, 134, 0, 0, 0, + 2, 2, 2, 2, 2, 22, 22, 20, 20, 20, 22, 22, 133, 0, 0, 0, 0, 0, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 2, 2, 2, 2, 2, 53, 52, 53, 0, 0, 0, 0, 153, 11, 74, 2, 2, 2, 2, 2, 2, 18, 19, 21, 16, 24, 37, 0, 0, 0, 31, 0, 0, 0, 0, 0, - 0, 11, 49, 2, 2, 2, 2, 2, 2, 2, 2, 2, 128, 20, 22, 154, + 0, 11, 49, 2, 2, 2, 2, 2, 2, 2, 2, 2, 127, 20, 22, 154, 22, 21, 155, 156, 2, 2, 2, 2, 2, 0, 0, 65, 157, 0, 0, 0, 0, 2, 13, 0, 0, 0, 0, 0, 0, 2, 65, 25, 20, 20, 20, 22, - 22, 108, 158, 0, 0, 56, 159, 31, 160, 30, 2, 2, 2, 2, 2, 2, + 22, 107, 158, 0, 0, 56, 159, 31, 160, 30, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 23, 19, 22, 22, 161, 44, 0, 0, 0, - 49, 128, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 9, 9, 2, 2, + 49, 127, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 9, 9, 2, 2, 30, 2, 2, 2, 2, 2, 2, 2, 30, 2, 2, 2, 2, 2, 2, 2, 10, 18, 19, 21, 22, 162, 31, 0, 0, 11, 11, 30, 2, 2, 2, 9, 30, 9, 2, 30, 2, 2, 58, 17, 23, 16, 23, 47, 32, 33, 32, 34, @@ -559,70 +557,69 @@ hb_use_u8[3657] = 0, 11, 11, 46, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 30, 0, 9, 2, 2, 2, 30, 45, 59, 20, 20, 31, 33, 32, 32, 25, 163, 29, 164, 165, 37, 0, 0, 0, 0, 0, 0, 12, 26, 0, 0, 0, 0, 0, - 0, 2, 2, 65, 25, 20, 20, 20, 22, 23, 126, 15, 17, 0, 0, 0, + 0, 2, 2, 65, 25, 20, 20, 20, 22, 23, 125, 15, 17, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 166, 167, 0, 0, 0, 0, 0, 0, - 0, 18, 19, 20, 20, 66, 99, 25, 160, 11, 168, 9, 0, 0, 0, 0, + 0, 18, 19, 20, 20, 66, 98, 25, 160, 11, 168, 9, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 65, 25, 20, 20, 0, 48, 48, 11, 169, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 20, 0, 23, 19, 20, 20, 21, 16, 82, 169, 38, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 10, 170, 25, 20, 22, 22, 168, 9, 0, 0, - 0, 2, 2, 2, 2, 2, 9, 43, 136, 23, 22, 20, 76, 21, 22, 0, + 0, 2, 2, 2, 2, 2, 9, 43, 135, 23, 22, 20, 76, 21, 22, 0, 0, 2, 2, 2, 9, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 18, - 19, 20, 21, 22, 105, 169, 37, 0, 0, 2, 2, 2, 9, 30, 0, 2, + 19, 20, 21, 22, 104, 169, 37, 0, 0, 2, 2, 2, 9, 30, 0, 2, 2, 2, 2, 30, 9, 2, 2, 2, 2, 23, 23, 18, 32, 33, 12, 171, 165, 172, 173, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 2, 2, - 2, 65, 25, 20, 20, 0, 22, 23, 29, 108, 0, 33, 0, 0, 0, 0, - 0, 52, 20, 22, 22, 22, 140, 2, 2, 2, 174, 175, 11, 15, 176, 61, - 177, 0, 0, 1, 147, 0, 0, 0, 0, 52, 20, 22, 16, 19, 20, 2, - 2, 2, 2, 158, 158, 158, 178, 178, 178, 178, 178, 178, 15, 179, 0, 30, - 0, 22, 20, 20, 31, 22, 22, 11, 169, 0, 61, 61, 61, 61, 61, 61, - 61, 66, 21, 82, 46, 0, 0, 0, 0, 2, 2, 2, 9, 2, 30, 2, - 2, 52, 22, 22, 31, 0, 38, 22, 27, 11, 159, 180, 181, 0, 0, 0, - 0, 2, 2, 2, 30, 9, 2, 2, 2, 2, 2, 2, 2, 2, 23, 23, - 47, 22, 35, 82, 68, 0, 0, 0, 0, 2, 182, 66, 47, 0, 0, 0, - 0, 11, 183, 2, 2, 2, 2, 2, 2, 2, 2, 23, 22, 20, 31, 0, - 48, 16, 143, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 156, 0, - 0, 184, 184, 184, 184, 184, 184, 184, 184, 185, 185, 185, 186, 187, 185, 184, - 184, 188, 184, 184, 189, 190, 190, 190, 190, 190, 190, 190, 0, 0, 0, 0, - 0, 184, 184, 184, 184, 184, 191, 0, 0, 2, 2, 2, 2, 2, 2, 2, - 22, 22, 22, 22, 22, 22, 192, 193, 194, 11, 11, 11, 46, 0, 0, 0, - 0, 29, 74, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 65, 47, - 0, 2, 2, 2, 2, 2, 9, 0, 58, 195, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, - 40, 116, 26, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 30, 2, 2, 2, 2, 2, 0, 58, - 37, 0, 6, 120, 120, 120, 121, 0, 0, 11, 11, 11, 49, 2, 2, 2, - 0, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, - 46, 2, 2, 2, 2, 2, 2, 11, 11, 2, 2, 2, 2, 2, 2, 22, - 22, 2, 2, 2, 2, 2, 2, 2, 20, 2, 2, 44, 44, 44, 92, 0, - 0, O, O, O, GB, B, B, O, SB, O, SE, GB, O, O, WJ,FMPst, - FMPst, O, CGJ, B, O, B,VMAbv,VMAbv,VMAbv, O,VMAbv, B,CMBlw,CMBlw,CMBlw,VMAbv, - VMPst, VAbv, VPst,CMBlw, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VPst, - VPst, VPst, H, VPre, VPst,VMBlw, O, O, VAbv, GB,VMAbv,VMPst,VMPst, O, B, VBlw, - O, O, VPre, VPre, O, VPre, H, O, VPst,FMAbv, O,CMBlw, O, VAbv, O, VAbv, - H, O,VMBlw,VMAbv,CMAbv, GB, GB, O, MBlw,CMAbv,CMAbv, VPst, VAbv,VMAbv, O, VPst, - O, VPre, VPre,VMAbv, B, O, CS, CS,VMPst, B, VAbv, VAbv, B, R, O, HVM, - O, O,FMBlw, O,CMAbv, O,CMBlw, VAbv, VBlw, B, SUB, SUB, SUB, O, SUB, SUB, - O,FMBlw, O, B, VPst, VBlw, VPre,VMAbv,VMBlw,VMPst, IS, VAbv, MPst, MPre, MBlw, MBlw, - B, MBlw, MBlw, VPst,VMPst,VMPst, B, MBlw, VPst, VPre, VAbv, VAbv,VMPst,VMPst,VMBlw, B, - VMPst, VBlw, VPst, CGJ, CGJ, VPst,VMAbv,VMAbv,FMAbv, FAbv,CMAbv,FMAbv,VMAbv,FMAbv, VAbv, IS, - FMAbv, B,FMAbv, B, CGJ, WJ, CGJ, GB,CMAbv,CMAbv, B, GB, B, VAbv, SUB, FPst, - FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre, B, MPre, MBlw, SUB, FAbv, FAbv, MAbv, - SUB, Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst, H, B, O,SMAbv,SMAbv,SMAbv, VPst, - IS, RK, RK, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw,VMBlw,VMAbv, CS, O,FMAbv, ZWNJ, - CGJ, WJ, WJ, WJ, O,FMPst, O, SB, SE, O, H, MPst, VPst, H,VMAbv, VAbv, - VMBlw, B, VBlw, FPst, VPst, FAbv,VMPst, B,CMAbv, VAbv, MBlw, MPst, MBlw, H, O, VBlw, - MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, FPst, VBlw, B, B, VPre, O,VMPst, IS, - O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv, O, IS,VMBlw, B,VMPst,VMAbv,VMPst, CS, CS, - B, N, N, O, HN, VPre, VBlw, VAbv, IS,CMAbv, O, VPst, B, R, R,CMBlw, - VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,VMPst, O,VMAbv,CMBlw, IS, R,FMAbv, B, CS, - CS, H,CMBlw,VMPst, H,VMPst, VAbv,VMAbv, VPst, MPst, R, MPst,CMBlw, B,FMBlw, VBlw, - VMAbv, CS, SUB, SUB, GB, FBlw, FBlw,CMAbv, IS, VBlw, IS, R, MBlw, GB, VAbv, R, - VMPst, G, G, J, J, J, SB, SE, J, HR, G, G, HM, HM, HM, G, - O, MPre, MPre, MPst,VMAbv, MBlw, VBlw, O, VBlw, + 2, 65, 25, 20, 20, 0, 22, 23, 29, 107, 0, 33, 0, 0, 0, 0, + 0, 52, 20, 22, 22, 22, 139, 2, 2, 2, 174, 140, 11, 15, 175, 61, + 176, 0, 0, 1, 147, 0, 0, 0, 0, 52, 20, 22, 16, 19, 20, 2, + 2, 2, 2, 158, 158, 158, 177, 177, 177, 177, 177, 177, 15, 178, 0, 30, + 0, 16, 20, 16, 16, 0, 0, 0, 0, 22, 20, 20, 31, 22, 22, 11, + 169, 0, 61, 61, 61, 61, 61, 61, 61, 66, 21, 82, 46, 0, 0, 0, + 0, 2, 2, 2, 9, 2, 30, 2, 2, 52, 22, 22, 31, 0, 38, 22, + 27, 11, 159, 179, 180, 0, 0, 0, 0, 2, 2, 2, 30, 9, 2, 2, + 2, 2, 2, 2, 2, 2, 23, 23, 47, 22, 35, 82, 68, 0, 0, 0, + 0, 2, 181, 66, 47, 0, 0, 0, 0, 11, 182, 2, 2, 2, 2, 2, + 2, 2, 2, 23, 22, 20, 31, 0, 48, 16, 143, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 156, 0, 0, 183, 183, 183, 183, 183, 183, 183, + 183, 184, 184, 184, 185, 186, 184, 183, 183, 187, 183, 183, 188, 189, 189, 189, + 189, 189, 189, 189, 0, 0, 0, 0, 0, 183, 183, 183, 183, 183, 190, 0, + 0, 2, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, 22, 22, 191, 192, + 193, 11, 11, 11, 46, 0, 0, 0, 0, 29, 74, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 65, 47, 0, 2, 2, 2, 2, 2, 9, 0, + 58, 194, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 0, 0, 0, 40, 115, 26, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 30, 2, 2, 2, 2, 2, 0, 58, 37, 0, 6, 119, 119, 119, 120, 0, + 0, 11, 11, 11, 49, 2, 2, 2, 0, 2, 2, 2, 2, 2, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 46, 2, 2, 2, 2, 2, 2, 11, + 11, 2, 2, 2, 2, 2, 2, 22, 22, 2, 2, 2, 2, 2, 2, 2, + 20, 2, 2, 44, 44, 44, 92, 0, 0, O, O, O, GB, B, B, O, + SB, O, SE, GB, O, O, WJ,FMPst,FMPst, O, CGJ, B, O, B,VMAbv,VMAbv, + VMAbv, O,VMAbv, B,CMBlw,CMBlw,CMBlw,VMAbv,VMPst, VAbv, VPst,CMBlw, B, VPst, VPre, VPst, + VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VPst, VPst, VPst, H, VPre, VPst,VMBlw, O, O, + VAbv, GB,VMAbv,VMPst,VMPst, O, B, VBlw, O, O, VPre, VPre, O, VPre, H, O, + VPst,FMAbv, O,CMBlw, O, VAbv, O, VAbv, H, O,VMBlw,VMAbv,CMAbv, GB, GB, O, + MBlw,CMAbv,CMAbv, VPst, VAbv,VMAbv, O, VPst, O, VPre, VPre,VMAbv, B, O, CS, CS, + VMPst, B, VAbv, VAbv, B, R, O, HVM, O, O,FMBlw, O,CMAbv, O,CMBlw, VAbv, + VBlw, B, SUB, SUB, SUB, O, SUB, SUB, O,FMBlw, O, B, VPst, VBlw, VPre,VMAbv, + VMBlw,VMPst, IS, VAbv, MPst, MPre, MBlw, MBlw, B, MBlw, MBlw, VPst,VMPst,VMPst, B, MBlw, + VPst, VPre, VAbv, VAbv,VMPst,VMPst,VMBlw, B,VMPst, VBlw, VPst, CGJ, CGJ, VPst,VMAbv,VMAbv, + FMAbv, FAbv,CMAbv,FMAbv,VMAbv,FMAbv, VAbv, IS,FMAbv, B,FMAbv, B, CGJ, WJ, CGJ, GB, + CMAbv,CMAbv, B, VAbv, SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre, B, + MPre, MBlw, SUB, FAbv, FAbv, MAbv, SUB, Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst, H, + B, O,SMAbv,SMAbv,SMAbv, VPst, IS, RK, RK, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw, + VMBlw,VMAbv, CS, O,FMAbv, ZWNJ, CGJ, WJ, WJ, WJ, O,FMPst, O, SB, SE, O, + H, MPst, VPst, H,VMAbv, VAbv,VMBlw, B, VBlw, FPst, VPst, FAbv,VMPst, B,CMAbv, VAbv, + MBlw, MPst, MBlw, H, O, VBlw, MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, FPst, VBlw, + B, VBlw,VMAbv, B, VPre, O,VMPst, IS, O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv, O, + IS,VMBlw, B,VMPst,VMAbv,VMPst, CS, CS, B, N, N, O, HN, VPre, VBlw, VAbv, + IS,CMAbv, O, VPst, B, R, R,CMBlw, VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,VMPst, + O,VMAbv,CMBlw, IS, R,FMAbv, B, CS, CS, H,CMBlw,VMPst, H,VMPst, VAbv,VMAbv, + VPst, MPst, R, MPst,CMBlw, B,FMBlw, CS, SUB, SUB, GB, FBlw, FBlw,CMAbv, IS, VBlw, + IS, R, MBlw, GB, VAbv, R,VMPst, G, G, J, J, J, SB, SE, J, HR, + G, G, HM, HM, HM, G, O, MPre, MPre, MPst,VMAbv, MBlw, VBlw, O, VBlw, }; -static const uint16_t -hb_use_u16[486] = +static const uint16_t hb_use_u16[488]= { 0, 0, 1, 2, 0, 3, 4, 5, 0, 6, 7, 0, 8, 0, 9, 10, 11, 12, 10, 13, 14, 10, 10, 15, 16, 17, 18, 19, 20, 21, 22, 23, @@ -633,43 +630,43 @@ hb_use_u16[486] = 31, 66, 67, 68, 10, 69, 70, 10, 71, 72, 73, 74, 75, 76, 77, 0, 10, 10, 78, 79, 80, 81, 82, 83, 84, 85, 10, 86, 10, 87, 10, 88, 89, 90, 10, 91, 92, 93, 2, 0, 94, 0, 10, 95, 96, 10, 97, 0, - 98, 99,100,101, 31, 10,102,103,104, 10,105,106, 10,107, 10,108, - 109,110, 2, 2,111, 10, 10,112,113, 2,114,115,116, 10,117, 10, - 118,119,120,121,122, 0, 0,123,124,125, 0,126,127,128,129, 0, - 130,131,132, 0, 0,133,134, 0,135, 0, 0, 10,136,137,138, 0, - 139, 10,140, 0, 10,141,142, 10, 10,143,144, 2,145,146,147, 10, - 148,149,150, 10, 10,151,152, 2,153, 99,154,155,156, 2, 10,157, - 10,158,159, 0,160,161,162, 2,163, 0, 0,164, 0,165, 0,166, - 166,167, 34,168,169,170, 10,171, 95, 0,172, 0, 10,173,174, 0, - 175, 2,176, 10,177, 0,178,173,179,180,181, 0, 0,182,183, 0, - 184, 10, 10,185,186,187,188,189,190, 10, 10,191,192, 0,193, 10, - 194,195,196, 10, 10,197, 10,198,199,106,200,103, 10, 34,201,202, - 203, 0,204,205, 95, 10, 10,206,207, 2,208, 21, 22,209,210,211, - 212,213,214, 10, 10,215,216,217,218, 0, 10,219,220,221,222, 0, - 200, 10, 10,223,224, 2,225,226,227,228, 10,229,230, 2,231,232, - 2, 10,141, 0, 10,233,234,104,235, 0,236,237,238,239, 10,240, - 241, 2,242, 10, 10,243,244, 0,245, 10, 10,246,247,248,249,250, - 22, 10,225,251, 8, 10, 71, 19, 10,252, 74,253,254, 10, 10,255, - 256, 2,257, 10,258,259, 10,260,261, 49, 10,262,263,264,265,265, - 265,266,267,268,265,269, 10,270,271, 2, 10,272,273, 10,274, 2, - 275,276,277,277,278,279,280, 0, 10,177, 0,281,106, 71, 95,282, - 0,283, 71,284,285, 0,286, 0,287, 2,288, 2,289,106,290, 2, - 130,130,163,163,163,130, + 10, 98, 99,100, 31, 10,101,102,103, 10,104,105, 10,106, 10,107, + 108,109, 2, 2,110, 10, 10,111,112, 2,113,114,115, 10,116, 10, + 117,118,119,120,121, 0, 0,122,123,124, 0,125,126,127,128, 0, + 129,130,131, 0, 0,132,133, 0,134, 0, 0, 10,135,136,137, 0, + 138, 10,139, 0, 10,140,141, 10, 10,142,143, 2,144,145,146, 10, + 147,148,149, 10, 10,150,151, 2,152, 98,153,154,155, 2, 10,156, + 10,157,158, 0,159,160,161, 2,162, 0, 0,163, 0,164, 0,165, + 165,166, 34,167,168,169, 10,170, 95, 0,171, 0, 10,172,173, 0, + 174, 2,175, 10,176, 0,177,172,178,179,180, 0, 0,181,182, 0, + 183, 10, 10,184,185,186,187,188,189, 10, 10,190,191, 0,192, 10, + 193,194,195, 10, 10,196, 10,197,198,105,199,102, 10, 34,200,201, + 202, 0,203,204, 95, 10, 10,205,206, 2,207, 21, 22,208,209,210, + 211,212,213, 10, 10,214,215,216,217, 0, 10,218,219,220,221, 0, + 199, 10, 10,222,223, 2,224,225,226,227, 10,228,229, 2,230,231, + 2, 10,140, 0, 10,232,233,103,234, 0,235,236,237,238, 10,239, + 240, 2,241, 10, 10,242,243, 0,244, 10, 10,245,246,247,248,249, + 250, 0, 22, 10,224,251, 8, 10, 71, 19, 10,252, 74,253,254, 10, + 10,255,256, 2,257, 10,258,259, 10,260,261, 49, 10,262,263,264, + 265,265,265,266,267,268,265,269, 10,270,271, 2, 10,272,273, 10, + 274, 2,275,276,277,277,278,279,280, 0, 10,176, 0,281,105, 71, + 95,282, 0,283, 71,284,285, 0,286, 0,287, 2,288, 2,289,105, + 290, 2,129,129,162,162,162,129, }; -static inline unsigned -hb_use_b4 (const uint8_t* a, unsigned i) +static inline uint8_t hb_use_b4 (const uint8_t* a, unsigned i) { - return (a[i>>1]>>((i&1u)<<2))&15u; + return (a[i>>1]>>((i&1)<<2))&15; } -static inline uint_fast8_t -hb_use_get_category (unsigned u) +static inline uint8_t hb_use_get_category (unsigned u) { - return u<921600u?hb_use_u8[3265+(((hb_use_u8[937+(((hb_use_u16[((hb_use_u8[369+(((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>1>>3>>4))<<4)+((u>>1>>3>>1>>3)&15u))])<<3)+((u>>1>>3>>1)&7u))])<<1)+((u>>1>>3)&1u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O; + return u<921600 ? hb_use_u8[3273u+((hb_use_u8[945u+((hb_use_u16[((hb_use_u8[369u+((hb_use_u8[113u+((hb_use_b4(hb_use_u8,((((((((((u)>>1))>>3))>>1))>>3))>>4)))<<4)+((((((((((u)>>1))>>3))>>1))>>3))&15)])<<3)+((((((((u)>>1))>>3))>>1))&7)])<<1)+((((((u)>>1))>>3))&1)])<<3)+((((u)>>1))&7)])<<1)+((u)&1)] : O; } + #endif + #undef B #undef CGJ #undef CS diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-vowel-constraints.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-vowel-constraints.cc index 4a112e1c289..bb586a68ce5 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-vowel-constraints.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-vowel-constraints.cc @@ -10,8 +10,8 @@ * # Date: 2015-03-12, 21:17:00 GMT [AG] * # Date: 2019-11-08, 23:22:00 GMT [AG] * - * # Scripts-16.0.0.txt - * # Date: 2024-04-30, 21:48:40 GMT + * # Scripts-17.0.0.txt + * # Date: 2025-07-24, 13:28:55 GMT */ #include "hb.hh" diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper.hh index 48cd5296ffd..9993507e360 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper.hh @@ -396,6 +396,12 @@ hb_ot_shaper_categorize (hb_script_t script, case HB_SCRIPT_TODHRI: case HB_SCRIPT_TULU_TIGALARI: + /* Unicode-17.0 additions */ + case HB_SCRIPT_BERIA_ERFE: + case HB_SCRIPT_SIDETIC: + case HB_SCRIPT_TAI_YO: + case HB_SCRIPT_TOLONG_SIKI: + /* If the designer designed the font for the 'DFLT' script, * (or we ended up arbitrarily pick 'latn'), use the default shaper. * Otherwise, use the specific shaper. diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh index 10165f57b75..28bc23d8f01 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh @@ -352,7 +352,7 @@ struct AxisValue { float get_value (unsigned int axis_index) const { - switch (u.format) + switch (u.format.v) { case 1: hb_barrier (); return u.format1.get_value (); case 2: hb_barrier (); return u.format2.get_value (); @@ -364,7 +364,7 @@ struct AxisValue unsigned int get_axis_index () const { - switch (u.format) + switch (u.format.v) { case 1: hb_barrier (); return u.format1.get_axis_index (); case 2: hb_barrier (); return u.format2.get_axis_index (); @@ -376,7 +376,7 @@ struct AxisValue hb_ot_name_id_t get_value_name_id () const { - switch (u.format) + switch (u.format.v) { case 1: hb_barrier (); return u.format1.get_value_name_id (); case 2: hb_barrier (); return u.format2.get_value_name_id (); @@ -389,9 +389,9 @@ struct AxisValue template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward (ds)...)); case 2: hb_barrier (); return_trace (c->dispatch (u.format2, std::forward (ds)...)); case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward (ds)...)); @@ -403,7 +403,7 @@ struct AxisValue bool keep_axis_value (const hb_array_t axis_records, hb_hashmap_t *user_axes_location) const { - switch (u.format) + switch (u.format.v) { case 1: hb_barrier (); return u.format1.keep_axis_value (axis_records, user_axes_location); case 2: hb_barrier (); return u.format2.keep_axis_value (axis_records, user_axes_location); @@ -420,7 +420,7 @@ struct AxisValue return_trace (false); hb_barrier (); - switch (u.format) + switch (u.format.v) { case 1: hb_barrier (); return_trace (u.format1.sanitize (c)); case 2: hb_barrier (); return_trace (u.format2.sanitize (c)); @@ -433,14 +433,14 @@ struct AxisValue protected: union { - HBUINT16 format; + struct { HBUINT16 v; } format; AxisValueFormat1 format1; AxisValueFormat2 format2; AxisValueFormat3 format3; AxisValueFormat4 format4; } u; public: - DEFINE_SIZE_UNION (2, format); + DEFINE_SIZE_UNION (2, format.v); }; struct AxisValueOffsetArray: UnsizedArrayOf> diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-tag-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-tag-table.hh index 50ddf5f6967..4933e661371 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-tag-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-tag-table.hh @@ -6,8 +6,8 @@ * * on files with these headers: * - * - * File-Date: 2025-01-21 + * + * File-Date: 2025-08-25 */ #ifndef HB_OT_TAG_TABLE_HH @@ -704,7 +704,7 @@ static const LangTag ot_languages3[] = { /*{HB_TAG('g','u','z',' '), HB_TAG('G','U','Z',' ')},*/ /* Gusii */ {HB_TAG('g','w','i',' '), HB_TAG('A','T','H',' ')}, /* Gwichʼin -> Athapaskan */ {HB_TAG('g','y','n',' '), HB_TAG('C','P','P',' ')}, /* Guyanese Creole English -> Creoles */ - {HB_TAG('h','a','a',' '), HB_TAG('A','T','H',' ')}, /* Han -> Athapaskan */ + {HB_TAG('h','a','a',' '), HB_TAG('A','T','H',' ')}, /* Hän -> Athapaskan */ {HB_TAG('h','a','e',' '), HB_TAG('O','R','O',' ')}, /* Eastern Oromo -> Oromo */ {HB_TAG('h','a','i',' '), HB_TAG('H','A','I','0')}, /* Haida [macrolanguage] */ {HB_TAG('h','a','k',' '), HB_TAG('Z','H','S',' ')}, /* Hakka Chinese -> Chinese, Simplified */ @@ -921,7 +921,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('k','v','t',' '), HB_TAG('K','R','N',' ')}, /* Lahta Karen -> Karen */ {HB_TAG('k','v','u',' '), HB_TAG('K','R','N',' ')}, /* Yinbaw Karen -> Karen */ {HB_TAG('k','v','y',' '), HB_TAG('K','R','N',' ')}, /* Yintale Karen -> Karen */ -/*{HB_TAG('k','w','k',' '), HB_TAG('K','W','K',' ')},*/ /* Kwakiutl -> Kwakʼwala */ +/*{HB_TAG('k','w','k',' '), HB_TAG('K','W','K',' ')},*/ /* Kwakʼwala */ {HB_TAG('k','w','w',' '), HB_TAG('C','P','P',' ')}, /* Kwinti -> Creoles */ {HB_TAG('k','w','y',' '), HB_TAG('K','O','N','0')}, /* San Salvador Kongo -> Kongo */ {HB_TAG('k','x','c',' '), HB_TAG('K','M','S',' ')}, /* Konso -> Komso */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-avar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-avar-table.hh index e26687c34ed..8a9307d6933 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-avar-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-avar-table.hh @@ -143,10 +143,13 @@ struct AxisValueMap struct SegmentMaps : Array16Of { - int map (int value, unsigned int from_offset = 0, unsigned int to_offset = 1) const + float map_float (float value, unsigned int from_offset = 0, unsigned int to_offset = 1) const { -#define fromCoord coords[from_offset].to_int () -#define toCoord coords[to_offset].to_int () +#define fromCoord coords[from_offset].to_float () +#define toCoord coords[to_offset].to_float () + + const auto *map = arrayZ; + /* The following special-cases are not part of OpenType, which requires * that at least -1, 0, and +1 must be mapped. But we include these as * part of a better error recovery scheme. */ @@ -155,47 +158,98 @@ struct SegmentMaps : Array16Of if (!len) return value; else /* len == 1*/ - return value - arrayZ[0].fromCoord + arrayZ[0].toCoord; + return value - map[0].fromCoord + map[0].toCoord; } - if (value <= arrayZ[0].fromCoord) - return value - arrayZ[0].fromCoord + arrayZ[0].toCoord; + // At least two mappings now. - unsigned int i; - unsigned int count = len - 1; - for (i = 1; i < count && value > arrayZ[i].fromCoord; i++) - ; + /* CoreText is wild... + * PingFangUI avar needs all this special-casing... + * So we implement an extended version of the spec here, + * which is more robust and more likely to be compatible with + * the wild. */ - if (value >= arrayZ[i].fromCoord) - return value - arrayZ[i].fromCoord + arrayZ[i].toCoord; + unsigned start = 0; + unsigned end = len; + if (map[start].fromCoord == -1 && map[start].toCoord == -1 && map[start+1].fromCoord == -1) + start++; + if (map[end-1].fromCoord == +1 && map[end-1].toCoord == +1 && map[end-2].fromCoord == +1) + end--; - if (unlikely (arrayZ[i-1].fromCoord == arrayZ[i].fromCoord)) - return arrayZ[i-1].toCoord; + /* Look for exact match first, and do lots of special-casing. */ + unsigned i; + for (i = start; i < end; i++) + if (value == map[i].fromCoord) + break; + if (i < end) + { + // There's at least one exact match. See if there are more. + unsigned j = i; + for (; j + 1 < end; j++) + if (value != map[j + 1].fromCoord) + break; + + // [i,j] inclusive are all exact matches: + + // If there's only one, return it. This is the only spec-compliant case. + if (i == j) + return map[i].toCoord; + // If there's exactly three, return the middle one. + if (i + 2 == j) + return map[i + 1].toCoord; + + // Ignore the middle ones. Return the one mapping closer to 0. + if (value < 0) return map[j].toCoord; + if (value > 0) return map[i].toCoord; + + // Mapping 0? CoreText seems confused. It seems to prefer 0 here... + // So we'll just return the smallest one. lol + return fabsf (map[i].toCoord) < fabsf (map[j].toCoord) ? map[i].toCoord : map[j].toCoord; + + // Mapping 0? Return one not mapping to 0. + if (map[i].toCoord == 0) + return map[j].toCoord; + else + return map[i].toCoord; + } + + /* There's at least two and we're not an exact match. Prepare to lerp. */ + + // Find the segment we're in. + for (i = start; i < end; i++) + if (value < map[i].fromCoord) + break; + + if (i == 0) + { + // Value before all segments; Shift. + return value - map[0].fromCoord + map[0].toCoord; + } + if (i == end) + { + // Value after all segments; Shift. + return value - map[end - 1].fromCoord + map[end - 1].toCoord; + } + + // Actually interpolate. + auto &before = map[i-1]; + auto &after = map[i]; + float denom = after.fromCoord - before.fromCoord; // Can't be zero by now. + return before.toCoord + ((after.toCoord - before.toCoord) * (value - before.fromCoord)) / denom; - int denom = arrayZ[i].fromCoord - arrayZ[i-1].fromCoord; - return roundf (arrayZ[i-1].toCoord + ((float) (arrayZ[i].toCoord - arrayZ[i-1].toCoord) * - (value - arrayZ[i-1].fromCoord)) / denom); #undef toCoord #undef fromCoord } - int unmap (int value) const { return map (value, 1, 0); } + float unmap_float (float value) const { return map_float (value, 1, 0); } + + // TODO Kill this. Triple unmap_axis_range (const Triple& axis_range) const { - F2DOT14 val, unmapped_val; - - val.set_float (axis_range.minimum); - unmapped_val.set_int (unmap (val.to_int ())); - float unmapped_min = unmapped_val.to_float (); - - val.set_float (axis_range.middle); - unmapped_val.set_int (unmap (val.to_int ())); - float unmapped_middle = unmapped_val.to_float (); - - val.set_float (axis_range.maximum); - unmapped_val.set_int (unmap (val.to_int ())); - float unmapped_max = unmapped_val.to_float (); + float unmapped_min = unmap_float (axis_range.minimum); + float unmapped_middle = unmap_float (axis_range.middle); + float unmapped_max = unmap_float (axis_range.maximum); return Triple{(double) unmapped_min, (double) unmapped_middle, (double) unmapped_max}; } @@ -203,6 +257,11 @@ struct SegmentMaps : Array16Of bool subset (hb_subset_context_t *c, hb_tag_t axis_tag) const { TRACE_SUBSET (this); + + /* This function cannot work on avar2 table (and currently doesn't). + * We should instead keep the design coords in the shape plan and use + * those. unmap_axis_range needs to be killed. */ + /* avar mapped normalized axis range*/ Triple *axis_range; if (!c->plan->axes_location.has (axis_tag, &axis_range)) @@ -304,14 +363,14 @@ struct avar return_trace (true); } - void map_coords (int *coords, unsigned int coords_length) const + void map_coords_16_16 (int *coords, unsigned int coords_length) const { unsigned int count = hb_min (coords_length, axisCount); const SegmentMaps *map = &firstAxisSegmentMaps; for (unsigned int i = 0; i < count; i++) { - coords[i] = map->map (coords[i]); + coords[i] = roundf (map->map_float (coords[i] / 65536.f) * 65536.f); map = &StructAfter (*map); } @@ -329,15 +388,20 @@ struct avar const auto &var_store = this+v2.varStore; auto *var_store_cache = var_store.create_cache (); + hb_vector_t coords_2_14; + coords_2_14.resize (coords_length); + for (unsigned i = 0; i < coords_length; i++) + coords_2_14[i] = roundf (coords[i] / 4.f); // 16.16 -> 2.14 + hb_vector_t out; out.alloc (coords_length); for (unsigned i = 0; i < coords_length; i++) { int v = coords[i]; uint32_t varidx = varidx_map.map (i); - float delta = var_store.get_delta (varidx, coords, coords_length, var_store_cache); - v += roundf (delta); - v = hb_clamp (v, -(1<<14), +(1<<14)); + float delta = var_store.get_delta (varidx, coords_2_14.arrayZ, coords_2_14.length, var_store_cache); + v += roundf (delta * 4); // 2.14 -> 16.16 + v = hb_clamp (v, -(1<<16), +(1<<16)); out.push (v); } for (unsigned i = 0; i < coords_length; i++) @@ -347,16 +411,54 @@ struct avar #endif } - void unmap_coords (int *coords, unsigned int coords_length) const + bool has_v2_data () const { return version.major > 1; } + + // axis normalization is done in 2.14 here + // TODO: deprecate this API once fonttools is updated to use 16.16 normalization + bool map_coords_2_14 (float *coords, unsigned int coords_length) const { + hb_vector_t coords_2_14; + if (!coords_2_14.resize (coords_length)) return false; unsigned int count = hb_min (coords_length, axisCount); const SegmentMaps *map = &firstAxisSegmentMaps; for (unsigned int i = 0; i < count; i++) { - coords[i] = map->unmap (coords[i]); + int v = roundf (map->map_float (coords[i]) * 16384.f); + coords_2_14[i] = v; + coords[i] = v / 16384.f; map = &StructAfter (*map); } + +#ifndef HB_NO_AVAR2 + if (version.major < 2) + return true; + hb_barrier (); + + for (; count < axisCount; count++) + map = &StructAfter (*map); + + const auto &v2 = * (const avarV2Tail *) map; + + const auto &varidx_map = this+v2.varIdxMap; + const auto &var_store = this+v2.varStore; + auto *var_store_cache = var_store.create_cache (); + + for (unsigned i = 0; i < coords_length; i++) + { + int v = coords_2_14[i]; + uint32_t varidx = varidx_map.map (i); + float delta = var_store.get_delta (varidx, coords_2_14.arrayZ, coords_2_14.length, var_store_cache); + v += roundf (delta); + v = hb_clamp (v, -(1<<16), +(1<<16)); + coords[i] = v / 16384.f; + } + + OT::ItemVariationStore::destroy_cache (var_store_cache); + return true; +#else + return version.major < 2; +#endif } bool subset (hb_subset_context_t *c) const diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-common.hh index 72deddef213..d0a4224c9b0 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-common.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-common.hh @@ -27,24 +27,35 @@ #define HB_OT_VAR_COMMON_HH #include "hb-ot-layout-common.hh" +#include "hb-alloc-pool.hh" #include "hb-priority-queue.hh" #include "hb-subset-instancer-iup.hh" namespace OT { +using rebase_tent_result_scratch_t = hb_pair_t; /* https://docs.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#tuplevariationheader */ struct TupleVariationHeader { friend struct tuple_delta_t; - unsigned get_size (unsigned axis_count) const - { return min_size + get_all_tuples (axis_count).get_size (); } + unsigned get_size (unsigned axis_count_times_2) const + { + // This function is super hot in mega-var-fonts with hundreds of masters. + unsigned ti = tupleIndex; + if (unlikely ((ti & (TupleIndex::EmbeddedPeakTuple | TupleIndex::IntermediateRegion)))) + { + unsigned count = ((ti & TupleIndex::EmbeddedPeakTuple) != 0) + ((ti & TupleIndex::IntermediateRegion) != 0) * 2; + return min_size + count * axis_count_times_2; + } + return min_size; + } unsigned get_data_size () const { return varDataSize; } - const TupleVariationHeader &get_next (unsigned axis_count) const - { return StructAtOffset (this, get_size (axis_count)); } + const TupleVariationHeader &get_next (unsigned axis_count_times_2) const + { return StructAtOffset (this, get_size (axis_count_times_2)); } bool unpack_axis_tuples (unsigned axis_count, const hb_array_t shared_tuples, @@ -53,7 +64,7 @@ struct TupleVariationHeader { const F2DOT14 *peak_tuple = nullptr; if (has_peak ()) - peak_tuple = get_peak_tuple (axis_count).arrayZ; + peak_tuple = get_peak_tuple (axis_count); else { unsigned int index = get_index (); @@ -68,8 +79,8 @@ struct TupleVariationHeader if (has_interm) { - start_tuple = get_start_tuple (axis_count).arrayZ; - end_tuple = get_end_tuple (axis_count).arrayZ; + start_tuple = get_start_tuple (axis_count); + end_tuple = get_end_tuple (axis_count); } for (unsigned i = 0; i < axis_count; i++) @@ -98,88 +109,109 @@ struct TupleVariationHeader return true; } + HB_ALWAYS_INLINE double calculate_scalar (hb_array_t coords, unsigned int coord_count, const hb_array_t shared_tuples, - const hb_vector_t> *shared_tuple_active_idx = nullptr) const + hb_scalar_cache_t *shared_tuple_scalar_cache = nullptr) const { + unsigned tuple_index = tupleIndex; + const F2DOT14 *peak_tuple; - unsigned start_idx = 0; - unsigned end_idx = coord_count; - unsigned step = 1; + bool has_interm = tuple_index & TupleIndex::IntermediateRegion; // Inlined for performance - if (has_peak ()) - peak_tuple = get_peak_tuple (coord_count).arrayZ; + if (unlikely (tuple_index & TupleIndex::EmbeddedPeakTuple)) // Inlined for performance + { + peak_tuple = get_peak_tuple (coord_count); + shared_tuple_scalar_cache = nullptr; + } else { - unsigned int index = get_index (); + unsigned int index = tuple_index & TupleIndex::TupleIndexMask; // Inlined for performance + + float scalar; + if (shared_tuple_scalar_cache && + shared_tuple_scalar_cache->get (index, &scalar)) + { + if (has_interm && (scalar != 0 && scalar != 1.f)) + shared_tuple_scalar_cache = nullptr; + else + return (double) scalar; + } + if (unlikely ((index + 1) * coord_count > shared_tuples.length)) return 0.0; - peak_tuple = shared_tuples.sub_array (coord_count * index, coord_count).arrayZ; + peak_tuple = shared_tuples.arrayZ + (coord_count * index); - if (shared_tuple_active_idx) - { - if (unlikely (index >= shared_tuple_active_idx->length)) - return 0.0; - auto _ = (*shared_tuple_active_idx).arrayZ[index]; - if (_.second != -1) - { - start_idx = _.first; - end_idx = _.second + 1; - step = _.second - _.first; - } - else if (_.first != -1) - { - start_idx = _.first; - end_idx = start_idx + 1; - } - } } const F2DOT14 *start_tuple = nullptr; const F2DOT14 *end_tuple = nullptr; - bool has_interm = has_intermediate (); + if (has_interm) { - start_tuple = get_start_tuple (coord_count).arrayZ; - end_tuple = get_end_tuple (coord_count).arrayZ; + start_tuple = get_start_tuple (coord_count); + end_tuple = get_end_tuple (coord_count); } double scalar = 1.0; - for (unsigned int i = start_idx; i < end_idx; i += step) +#ifndef HB_OPTIMIZE_SIZE +#if HB_FAST_NUM_ACCESS + bool skip = coord_count >= 16; +#endif +#endif + for (unsigned int i = 0; i < coord_count; i++) { +#ifndef HB_OPTIMIZE_SIZE +#if HB_FAST_NUM_ACCESS + if (skip) + { + while (i + 4 <= coord_count && * (HBUINT64LE *) &peak_tuple[i] == 0) + i += 4; + while (i < coord_count && peak_tuple[i].to_int () == 0) + i += 1; + if (i >= coord_count) + break; + } +#endif +#endif + int peak = peak_tuple[i].to_int (); if (!peak) continue; int v = coords[i]; + if (!v) { scalar = 0.0; break; } if (v == peak) continue; if (has_interm) { + shared_tuple_scalar_cache = nullptr; int start = start_tuple[i].to_int (); int end = end_tuple[i].to_int (); if (unlikely (start > peak || peak > end || (start < 0 && end > 0 && peak))) continue; - if (v < start || v > end) return 0.0; + if (v < start || v > end) { scalar = 0.0; break; } if (v < peak) { if (peak != start) scalar *= (double) (v - start) / (peak - start); } else { if (peak != end) scalar *= (double) (end - v) / (end - peak); } } - else if (!v || v < hb_min (0, peak) || v > hb_max (0, peak)) return 0.0; + else if (v < hb_min (0, peak) || v > hb_max (0, peak)) { scalar = 0.0; break; } else scalar *= (double) v / peak; } + if (shared_tuple_scalar_cache) + shared_tuple_scalar_cache->set (get_index (), scalar); return scalar; } - bool has_peak () const { return tupleIndex & TuppleIndex::EmbeddedPeakTuple; } - bool has_intermediate () const { return tupleIndex & TuppleIndex::IntermediateRegion; } - bool has_private_points () const { return tupleIndex & TuppleIndex::PrivatePointNumbers; } - unsigned get_index () const { return tupleIndex & TuppleIndex::TupleIndexMask; } + bool has_peak () const { return tupleIndex & TupleIndex::EmbeddedPeakTuple; } + bool has_intermediate () const { return tupleIndex & TupleIndex::IntermediateRegion; } + bool has_private_points () const { return tupleIndex & TupleIndex::PrivatePointNumbers; } + unsigned get_index () const { return tupleIndex & TupleIndex::TupleIndexMask; } protected: - struct TuppleIndex : HBUINT16 + struct TupleIndex : HBUINT16 { enum Flags { EmbeddedPeakTuple = 0x8000u, @@ -188,22 +220,24 @@ struct TupleVariationHeader TupleIndexMask = 0x0FFFu }; - TuppleIndex& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; } + TupleIndex& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; } DEFINE_SIZE_STATIC (2); }; hb_array_t get_all_tuples (unsigned axis_count) const { return StructAfter> (tupleIndex).as_array ((has_peak () + has_intermediate () * 2) * axis_count); } - hb_array_t get_peak_tuple (unsigned axis_count) const - { return get_all_tuples (axis_count).sub_array (0, axis_count); } - hb_array_t get_start_tuple (unsigned axis_count) const - { return get_all_tuples (axis_count).sub_array (has_peak () * axis_count, axis_count); } - hb_array_t get_end_tuple (unsigned axis_count) const - { return get_all_tuples (axis_count).sub_array (has_peak () * axis_count + axis_count, axis_count); } + const F2DOT14* get_all_tuples_base (unsigned axis_count) const + { return StructAfter> (tupleIndex).arrayZ; } + const F2DOT14* get_peak_tuple (unsigned axis_count) const + { return get_all_tuples_base (axis_count); } + const F2DOT14* get_start_tuple (unsigned axis_count) const + { return get_all_tuples_base (axis_count) + has_peak () * axis_count; } + const F2DOT14* get_end_tuple (unsigned axis_count) const + { return get_all_tuples_base (axis_count) + has_peak () * axis_count + axis_count; } HBUINT16 varDataSize; /* The size in bytes of the serialized * data for this tuple variation table. */ - TuppleIndex tupleIndex; /* A packed field. The high 4 bits are flags (see below). + TupleIndex tupleIndex; /* A packed field. The high 4 bits are flags (see below). The low 12 bits are an index into a shared tuple records array. */ /* UnsizedArrayOf peakTuple - optional */ @@ -221,6 +255,21 @@ struct TupleVariationHeader DEFINE_SIZE_MIN (4); }; +struct optimize_scratch_t +{ + iup_scratch_t iup; + hb_vector_t opt_indices; + hb_vector_t rounded_x_deltas; + hb_vector_t rounded_y_deltas; + hb_vector_t opt_deltas_x; + hb_vector_t opt_deltas_y; + hb_vector_t opt_point_data; + hb_vector_t opt_deltas_data; + hb_vector_t point_data; + hb_vector_t deltas_data; + hb_vector_t rounded_deltas; +}; + struct tuple_delta_t { static constexpr bool realloc_move = true; // Watch out when adding new members! @@ -241,11 +290,12 @@ struct tuple_delta_t hb_vector_t compiled_tuple_header; hb_vector_t compiled_deltas; - /* compiled peak coords, empty for non-gvar tuples */ - hb_vector_t compiled_peak_coords; + hb_vector_t compiled_peak_coords; + hb_vector_t compiled_interm_coords; - tuple_delta_t () = default; + tuple_delta_t (hb_alloc_pool_t *pool = nullptr) {} tuple_delta_t (const tuple_delta_t& o) = default; + tuple_delta_t& operator = (const tuple_delta_t& o) = default; friend void swap (tuple_delta_t& a, tuple_delta_t& b) noexcept { @@ -267,6 +317,18 @@ struct tuple_delta_t return *this; } + void copy_from (const tuple_delta_t& o, hb_alloc_pool_t *pool = nullptr) + { + axis_tuples = o.axis_tuples; + indices.duplicate_vector_from_pool (pool, o.indices); + deltas_x.duplicate_vector_from_pool (pool, o.deltas_x); + deltas_y.duplicate_vector_from_pool (pool, o.deltas_y); + compiled_tuple_header.duplicate_vector_from_pool (pool, o.compiled_tuple_header); + compiled_deltas.duplicate_vector_from_pool (pool, o.compiled_deltas); + compiled_peak_coords.duplicate_vector_from_pool (pool, o.compiled_peak_coords); + compiled_interm_coords.duplicate_vector_from_pool (pool, o.compiled_interm_coords); + } + void remove_axis (hb_tag_t axis_tag) { axis_tuples.del (axis_tag); } @@ -321,31 +383,44 @@ struct tuple_delta_t return *this; } - hb_vector_t change_tuple_var_axis_limit (hb_tag_t axis_tag, Triple axis_limit, - TripleDistances axis_triple_distances) const + void change_tuple_var_axis_limit (hb_tag_t axis_tag, Triple axis_limit, + TripleDistances axis_triple_distances, + hb_vector_t& out, + rebase_tent_result_scratch_t &scratch, + hb_alloc_pool_t *pool = nullptr) { - hb_vector_t out; + // May move *this out. + + out.reset (); Triple *tent; if (!axis_tuples.has (axis_tag, &tent)) { - out.push (*this); - return out; + out.push (std::move (*this)); + return; } if ((tent->minimum < 0.0 && tent->maximum > 0.0) || !(tent->minimum <= tent->middle && tent->middle <= tent->maximum)) - return out; + return; if (tent->middle == 0.0) { - out.push (*this); - return out; + out.push (std::move (*this)); + return; } - rebase_tent_result_t solutions = rebase_tent (*tent, axis_limit, axis_triple_distances); - for (auto &t : solutions) + rebase_tent_result_t &solutions = scratch.first; + rebase_tent (*tent, axis_limit, axis_triple_distances, solutions, scratch.second); + for (unsigned i = 0; i < solutions.length; i++) { - tuple_delta_t new_var = *this; + auto &t = solutions.arrayZ[i]; + + tuple_delta_t new_var; + if (i < solutions.length - 1) + new_var.copy_from (*this, pool); + else + new_var = std::move (*this); + if (t.second == Triple ()) new_var.remove_axis (axis_tag); else @@ -354,38 +429,76 @@ struct tuple_delta_t new_var *= t.first; out.push (std::move (new_var)); } - - return out; } - bool compile_peak_coords (const hb_map_t& axes_index_map, - const hb_map_t& axes_old_index_tag_map) + bool compile_coords (const hb_map_t& axes_index_map, + const hb_map_t& axes_old_index_tag_map, + hb_alloc_pool_t *pool= nullptr) { - unsigned axis_count = axes_index_map.get_population (); - if (unlikely (!compiled_peak_coords.alloc (axis_count * F2DOT14::static_size))) + unsigned cur_axis_count = axes_index_map.get_population (); + if (pool) + { + if (unlikely (!compiled_peak_coords.allocate_from_pool (pool, cur_axis_count))) + return false; + } + else if (unlikely (!compiled_peak_coords.resize (cur_axis_count))) return false; + hb_array_t start_coords, end_coords; + unsigned orig_axis_count = axes_old_index_tag_map.get_population (); + unsigned j = 0; for (unsigned i = 0; i < orig_axis_count; i++) { if (!axes_index_map.has (i)) continue; hb_tag_t axis_tag = axes_old_index_tag_map.get (i); - Triple *coords; - F2DOT14 peak_coord; + Triple *coords = nullptr; if (axis_tuples.has (axis_tag, &coords)) - peak_coord.set_float (coords->middle); - else - peak_coord.set_int (0); + { + float min_val = coords->minimum; + float val = coords->middle; + float max_val = coords->maximum; - /* push F2DOT14 value into char vector */ - int16_t val = peak_coord.to_int (); - compiled_peak_coords.push (static_cast (val >> 8)); - compiled_peak_coords.push (static_cast (val & 0xFF)); + compiled_peak_coords.arrayZ[j].set_float (val); + + if (min_val != hb_min (val, 0.f) || max_val != hb_max (val, 0.f)) + { + if (!compiled_interm_coords) + { + if (pool) + { + if (unlikely (!compiled_interm_coords.allocate_from_pool (pool, 2 * cur_axis_count))) + return false; + } + else if (unlikely (!compiled_interm_coords.resize (2 * cur_axis_count))) + return false; + start_coords = compiled_interm_coords.as_array ().sub_array (0, cur_axis_count); + end_coords = compiled_interm_coords.as_array ().sub_array (cur_axis_count); + + for (unsigned k = 0; k < j; k++) + { + signed peak = compiled_peak_coords.arrayZ[k].to_int (); + if (!peak) continue; + start_coords.arrayZ[k].set_int (hb_min (peak, 0)); + end_coords.arrayZ[k].set_int (hb_max (peak, 0)); + } + } + + } + + if (compiled_interm_coords) + { + start_coords.arrayZ[j].set_float (min_val); + end_coords.arrayZ[j].set_float (max_val); + } + } + + j++; } - return !compiled_peak_coords.in_error (); + return !compiled_peak_coords.in_error () && !compiled_interm_coords.in_error (); } /* deltas should be compiled already before we compile tuple @@ -394,7 +507,8 @@ struct tuple_delta_t bool compile_tuple_var_header (const hb_map_t& axes_index_map, unsigned points_data_length, const hb_map_t& axes_old_index_tag_map, - const hb_hashmap_t*, unsigned>* shared_tuples_idx_map) + const hb_hashmap_t*, unsigned>* shared_tuples_idx_map, + hb_alloc_pool_t *pool = nullptr) { /* compiled_deltas could be empty after iup delta optimization, we can skip * compiling this tuple and return true */ @@ -403,7 +517,7 @@ struct tuple_delta_t unsigned cur_axis_count = axes_index_map.get_population (); /* allocate enough memory: 1 peak + 2 intermediate coords + fixed header size */ unsigned alloc_len = 3 * cur_axis_count * (F2DOT14::static_size) + 4; - if (unlikely (!compiled_tuple_header.resize (alloc_len))) return false; + if (unlikely (!compiled_tuple_header.allocate_from_pool (pool, alloc_len, false))) return false; unsigned flag = 0; /* skip the first 4 header bytes: variationDataSize+tupleIndex */ @@ -411,6 +525,9 @@ struct tuple_delta_t F2DOT14* end = reinterpret_cast (compiled_tuple_header.end ()); hb_array_t coords (p, end - p); + if (!shared_tuples_idx_map) + compile_coords (axes_index_map, axes_old_index_tag_map); // non-gvar tuples do not have compiled coords yet + /* encode peak coords */ unsigned peak_count = 0; unsigned *shared_tuple_idx; @@ -421,16 +538,16 @@ struct tuple_delta_t } else { - peak_count = encode_peak_coords(coords, flag, axes_index_map, axes_old_index_tag_map); + peak_count = encode_peak_coords(coords, flag); if (!peak_count) return false; } /* encode interim coords, it's optional so returned num could be 0 */ - unsigned interim_count = encode_interm_coords (coords.sub_array (peak_count), flag, axes_index_map, axes_old_index_tag_map); + unsigned interim_count = encode_interm_coords (coords.sub_array (peak_count), flag); /* pointdata length = 0 implies "use shared points" */ if (points_data_length) - flag |= TupleVariationHeader::TuppleIndex::PrivatePointNumbers; + flag |= TupleVariationHeader::TupleIndex::PrivatePointNumbers; unsigned serialized_data_size = points_data_length + compiled_deltas.length; TupleVariationHeader *o = reinterpret_cast (compiled_tuple_header.begin ()); @@ -438,105 +555,63 @@ struct tuple_delta_t o->tupleIndex = flag; unsigned total_header_len = 4 + (peak_count + interim_count) * (F2DOT14::static_size); - return compiled_tuple_header.resize (total_header_len); + compiled_tuple_header.shrink_back_to_pool (pool, total_header_len); + return true; } unsigned encode_peak_coords (hb_array_t peak_coords, - unsigned& flag, - const hb_map_t& axes_index_map, - const hb_map_t& axes_old_index_tag_map) const + unsigned& flag) const { - unsigned orig_axis_count = axes_old_index_tag_map.get_population (); - auto it = peak_coords.iter (); - unsigned count = 0; - for (unsigned i = 0; i < orig_axis_count; i++) - { - if (!axes_index_map.has (i)) /* axis pinned */ - continue; - hb_tag_t axis_tag = axes_old_index_tag_map.get (i); - Triple *coords; - if (!axis_tuples.has (axis_tag, &coords)) - (*it).set_int (0); - else - (*it).set_float (coords->middle); - it++; - count++; - } - flag |= TupleVariationHeader::TuppleIndex::EmbeddedPeakTuple; - return count; + hb_memcpy (&peak_coords[0], &compiled_peak_coords[0], compiled_peak_coords.length * sizeof (compiled_peak_coords[0])); + flag |= TupleVariationHeader::TupleIndex::EmbeddedPeakTuple; + return compiled_peak_coords.length; } /* if no need to encode intermediate coords, then just return p */ unsigned encode_interm_coords (hb_array_t coords, - unsigned& flag, - const hb_map_t& axes_index_map, - const hb_map_t& axes_old_index_tag_map) const + unsigned& flag) const { - unsigned orig_axis_count = axes_old_index_tag_map.get_population (); - unsigned cur_axis_count = axes_index_map.get_population (); - - auto start_coords_iter = coords.sub_array (0, cur_axis_count).iter (); - auto end_coords_iter = coords.sub_array (cur_axis_count).iter (); - bool encode_needed = false; - unsigned count = 0; - for (unsigned i = 0; i < orig_axis_count; i++) + if (compiled_interm_coords) { - if (!axes_index_map.has (i)) /* axis pinned */ - continue; - hb_tag_t axis_tag = axes_old_index_tag_map.get (i); - Triple *coords; - float min_val = 0.f, val = 0.f, max_val = 0.f; - if (axis_tuples.has (axis_tag, &coords)) - { - min_val = coords->minimum; - val = coords->middle; - max_val = coords->maximum; - } - - (*start_coords_iter).set_float (min_val); - (*end_coords_iter).set_float (max_val); - - start_coords_iter++; - end_coords_iter++; - count += 2; - if (min_val != hb_min (val, 0.f) || max_val != hb_max (val, 0.f)) - encode_needed = true; + hb_memcpy (&coords[0], &compiled_interm_coords[0], compiled_interm_coords.length * sizeof (compiled_interm_coords[0])); + flag |= TupleVariationHeader::TupleIndex::IntermediateRegion; } - - if (encode_needed) - { - flag |= TupleVariationHeader::TuppleIndex::IntermediateRegion; - return count; - } - return 0; + return compiled_interm_coords.length; } - bool compile_deltas () - { return compile_deltas (indices, deltas_x, deltas_y, compiled_deltas); } + bool compile_deltas (hb_vector_t &rounded_deltas_scratch, + hb_alloc_pool_t *pool = nullptr) + { return compile_deltas (indices, deltas_x, deltas_y, compiled_deltas, rounded_deltas_scratch, pool); } static bool compile_deltas (hb_array_t point_indices, hb_array_t x_deltas, hb_array_t y_deltas, - hb_vector_t &compiled_deltas /* OUT */) + hb_vector_t &compiled_deltas, /* OUT */ + hb_vector_t &rounded_deltas, /* scratch */ + hb_alloc_pool_t *pool = nullptr) { - hb_vector_t rounded_deltas; - if (unlikely (!rounded_deltas.alloc (point_indices.length))) + if (unlikely (!rounded_deltas.resize_dirty (point_indices.length))) return false; + unsigned j = 0; for (unsigned i = 0; i < point_indices.length; i++) { if (!point_indices[i]) continue; - int rounded_delta = (int) roundf (x_deltas.arrayZ[i]); - rounded_deltas.push (rounded_delta); + rounded_deltas.arrayZ[j++] = (int) roundf (x_deltas.arrayZ[i]); } + rounded_deltas.resize (j); if (!rounded_deltas) return true; - /* allocate enough memories 5 * num_deltas */ - unsigned alloc_len = 5 * rounded_deltas.length; + /* Allocate enough memory: this is the correct bound: + * Worst case scenario is that each delta has to be encoded in 4 bytes, and there + * are runs of 64 items each. Any delta encoded in less than 4 bytes (2, 1, or 0) + * is still smaller than the 4-byte encoding even with their control byte. + * The initial 2 is to handle length==0, for both x and y deltas. */ + unsigned alloc_len = 2 + 4 * rounded_deltas.length + (rounded_deltas.length + 63) / 64; if (y_deltas) alloc_len *= 2; - if (unlikely (!compiled_deltas.resize (alloc_len))) return false; + if (unlikely (!compiled_deltas.allocate_from_pool (pool, alloc_len, false))) return false; unsigned encoded_len = compile_deltas (compiled_deltas, rounded_deltas); @@ -557,28 +632,30 @@ struct tuple_delta_t if (j != rounded_deltas.length) return false; encoded_len += compile_deltas (compiled_deltas.as_array ().sub_array (encoded_len), rounded_deltas); } - return compiled_deltas.resize (encoded_len); + compiled_deltas.shrink_back_to_pool (pool, encoded_len); + return true; } static unsigned compile_deltas (hb_array_t encoded_bytes, hb_array_t deltas) { - return TupleValues::compile (deltas, encoded_bytes); + return TupleValues::compile_unsafe (deltas, encoded_bytes); } - bool calc_inferred_deltas (const contour_point_vector_t& orig_points) + bool calc_inferred_deltas (const contour_point_vector_t& orig_points, + hb_vector_t &scratch) { unsigned point_count = orig_points.length; if (point_count != indices.length) return false; unsigned ref_count = 0; - hb_vector_t end_points; + + hb_vector_t &end_points = scratch.reset (); for (unsigned i = 0; i < point_count; i++) { - if (indices.arrayZ[i]) - ref_count++; + ref_count += indices.arrayZ[i]; if (orig_points.arrayZ[i].is_end_point) end_points.push (i); } @@ -587,7 +664,7 @@ struct tuple_delta_t return true; if (unlikely (end_points.in_error ())) return false; - hb_set_t inferred_idxes; + hb_bit_set_t inferred_idxes; unsigned start_point = 0; for (unsigned end_point : end_points) { @@ -661,6 +738,7 @@ struct tuple_delta_t bool optimize (const contour_point_vector_t& contour_points, bool is_composite, + optimize_scratch_t &scratch, double tolerance = 0.5 + 1e-10) { unsigned count = contour_points.length; @@ -668,22 +746,21 @@ struct tuple_delta_t deltas_y.length != count) return false; - hb_vector_t opt_indices; - hb_vector_t rounded_x_deltas, rounded_y_deltas; + hb_vector_t &opt_indices = scratch.opt_indices.reset (); + hb_vector_t &rounded_x_deltas = scratch.rounded_x_deltas; + hb_vector_t &rounded_y_deltas = scratch.rounded_y_deltas; - if (unlikely (!rounded_x_deltas.alloc (count) || - !rounded_y_deltas.alloc (count))) + if (unlikely (!rounded_x_deltas.resize_dirty (count) || + !rounded_y_deltas.resize_dirty (count))) return false; for (unsigned i = 0; i < count; i++) { - int rounded_x_delta = (int) roundf (deltas_x.arrayZ[i]); - int rounded_y_delta = (int) roundf (deltas_y.arrayZ[i]); - rounded_x_deltas.push (rounded_x_delta); - rounded_y_deltas.push (rounded_y_delta); + rounded_x_deltas.arrayZ[i] = (int) roundf (deltas_x.arrayZ[i]); + rounded_y_deltas.arrayZ[i] = (int) roundf (deltas_y.arrayZ[i]); } - if (!iup_delta_optimize (contour_points, rounded_x_deltas, rounded_y_deltas, opt_indices, tolerance)) + if (!iup_delta_optimize (contour_points, rounded_x_deltas, rounded_y_deltas, opt_indices, scratch.iup, tolerance)) return false; unsigned ref_count = 0; @@ -692,7 +769,8 @@ struct tuple_delta_t if (ref_count == count) return true; - hb_vector_t opt_deltas_x, opt_deltas_y; + hb_vector_t &opt_deltas_x = scratch.opt_deltas_x.reset (); + hb_vector_t &opt_deltas_y = scratch.opt_deltas_y.reset (); bool is_comp_glyph_wo_deltas = (is_composite && ref_count == 0); if (is_comp_glyph_wo_deltas) { @@ -705,34 +783,31 @@ struct tuple_delta_t opt_indices.arrayZ[i] = false; } - hb_vector_t opt_point_data; + hb_vector_t &opt_point_data = scratch.opt_point_data.reset (); if (!compile_point_set (opt_indices, opt_point_data)) return false; - hb_vector_t opt_deltas_data; + hb_vector_t &opt_deltas_data = scratch.opt_deltas_data.reset (); if (!compile_deltas (opt_indices, is_comp_glyph_wo_deltas ? opt_deltas_x : deltas_x, is_comp_glyph_wo_deltas ? opt_deltas_y : deltas_y, - opt_deltas_data)) + opt_deltas_data, + scratch.rounded_deltas)) return false; - hb_vector_t point_data; + hb_vector_t &point_data = scratch.point_data.reset (); if (!compile_point_set (indices, point_data)) return false; - hb_vector_t deltas_data; - if (!compile_deltas (indices, deltas_x, deltas_y, deltas_data)) + hb_vector_t &deltas_data = scratch.deltas_data.reset (); + if (!compile_deltas (indices, deltas_x, deltas_y, deltas_data, scratch.rounded_deltas)) return false; if (opt_point_data.length + opt_deltas_data.length < point_data.length + deltas_data.length) { - indices.fini (); indices = std::move (opt_indices); if (is_comp_glyph_wo_deltas) { - deltas_x.fini (); deltas_x = std::move (opt_deltas_x); - - deltas_y.fini (); deltas_y = std::move (opt_deltas_y); } } @@ -757,7 +832,7 @@ struct tuple_delta_t /* allocate enough memories: 2 bytes for count + 3 bytes for each point */ unsigned num_bytes = 2 + 3 *num_points; - if (unlikely (!compiled_points.resize (num_bytes, false))) + if (unlikely (!compiled_points.resize_dirty (num_bytes))) return false; unsigned pos = 0; @@ -821,7 +896,7 @@ struct tuple_delta_t else compiled_points.arrayZ[header_pos] = (run_length - 1) | 0x80; } - return compiled_points.resize (pos, false); + return compiled_points.resize_dirty (pos); } static double infer_delta (double target_val, double prev_val, double next_val, double prev_delta, double next_delta) @@ -852,15 +927,15 @@ struct TupleVariationData return_trace (c->check_struct (this)); } - unsigned get_size (unsigned axis_count) const + unsigned get_size (unsigned axis_count_times_2) const { unsigned total_size = min_size; unsigned count = tupleVarCount.get_count (); const TupleVariationHeader *tuple_var_header = &(get_tuple_var_header()); for (unsigned i = 0; i < count; i++) { - total_size += tuple_var_header->get_size (axis_count) + tuple_var_header->get_data_size (); - tuple_var_header = &tuple_var_header->get_next (axis_count); + total_size += tuple_var_header->get_size (axis_count_times_2) + tuple_var_header->get_data_size (); + tuple_var_header = &tuple_var_header->get_next (axis_count_times_2); } return total_size; @@ -925,8 +1000,12 @@ struct TupleVariationData const hb_map_t *axes_old_index_tag_map, const hb_vector_t &shared_indices, const hb_array_t shared_tuples, - bool is_composite_glyph) + hb_alloc_pool_t *pool = nullptr, + bool is_composite_glyph = false) { + hb_vector_t private_indices; + hb_vector_t deltas_x; + hb_vector_t deltas_y; do { const HBUINT8 *p = iterator.get_serialized_data (); @@ -939,7 +1018,7 @@ struct TupleVariationData || axis_tuples.is_empty ()) return false; - hb_vector_t private_indices; + private_indices.reset (); bool has_private_points = iterator.current_tuple->has_private_points (); const HBUINT8 *end = p + length; if (has_private_points && @@ -950,27 +1029,24 @@ struct TupleVariationData bool apply_to_all = (indices.length == 0); unsigned num_deltas = apply_to_all ? point_count : indices.length; - hb_vector_t deltas_x; - - if (unlikely (!deltas_x.resize (num_deltas, false) || + if (unlikely (!deltas_x.resize_dirty (num_deltas) || !TupleVariationData::decompile_deltas (p, deltas_x, end))) return false; - hb_vector_t deltas_y; if (is_gvar) { - if (unlikely (!deltas_y.resize (num_deltas, false) || + if (unlikely (!deltas_y.resize_dirty (num_deltas) || !TupleVariationData::decompile_deltas (p, deltas_y, end))) return false; } tuple_delta_t var; var.axis_tuples = std::move (axis_tuples); - if (unlikely (!var.indices.resize (point_count) || - !var.deltas_x.resize (point_count, false))) + if (unlikely (!var.indices.allocate_from_pool (pool, point_count) || + !var.deltas_x.allocate_from_pool (pool, point_count, false))) return false; - if (is_gvar && unlikely (!var.deltas_y.resize (point_count, false))) + if (is_gvar && unlikely (!var.deltas_y.allocate_from_pool (pool, point_count, false))) return false; for (unsigned i = 0; i < num_deltas; i++) @@ -1012,8 +1088,8 @@ struct TupleVariationData /* In VarData, deltas are organized in rows, convert them into * column(region) based tuples, resize deltas_x first */ tuple_delta_t tuple; - if (!tuple.deltas_x.resize (item_count, false) || - !tuple.indices.resize (item_count, false)) + if (!tuple.deltas_x.resize_dirty (item_count) || + !tuple.indices.resize_dirty (item_count)) return false; for (unsigned i = 0; i < item_count; i++) @@ -1041,7 +1117,8 @@ struct TupleVariationData } bool change_tuple_variations_axis_limits (const hb_hashmap_t& normalized_axes_location, - const hb_hashmap_t& axes_triple_distances) + const hb_hashmap_t& axes_triple_distances, + hb_alloc_pool_t *pool = nullptr) { /* sort axis_tag/axis_limits, make result deterministic */ hb_vector_t axis_tags; @@ -1050,6 +1127,10 @@ struct TupleVariationData for (auto t : normalized_axes_location.keys ()) axis_tags.push (t); + // Reused vectors for reduced malloc pressure. + rebase_tent_result_scratch_t scratch; + hb_vector_t out; + axis_tags.qsort (_cmp_axis_tag); for (auto axis_tag : axis_tags) { @@ -1061,9 +1142,10 @@ struct TupleVariationData axis_triple_distances = axes_triple_distances.get (axis_tag); hb_vector_t new_vars; - for (const tuple_delta_t& var : tuple_vars) + for (tuple_delta_t& var : tuple_vars) { - hb_vector_t out = var.change_tuple_var_axis_limit (axis_tag, *axis_limit, axis_triple_distances); + // This may move var out. + var.change_tuple_var_axis_limit (axis_tag, *axis_limit, axis_triple_distances, out, scratch, pool); if (!out) continue; unsigned new_len = new_vars.length + out.length; @@ -1074,7 +1156,6 @@ struct TupleVariationData for (unsigned i = 0; i < out.length; i++) new_vars.push (std::move (out[i])); } - tuple_vars.fini (); tuple_vars = std::move (new_vars); } return true; @@ -1085,9 +1166,12 @@ struct TupleVariationData bool merge_tuple_variations (contour_point_vector_t* contour_points = nullptr) { hb_vector_t new_vars; + // The pre-allocation is essential for address stability of pointers + // we store in the hashmap. + if (unlikely (!new_vars.alloc (tuple_vars.length))) + return false; hb_hashmap_t*, unsigned> m; - unsigned i = 0; - for (const tuple_delta_t& var : tuple_vars) + for (tuple_delta_t& var : tuple_vars) { /* if all axes are pinned, drop the tuple variation */ if (var.axis_tuples.is_empty ()) @@ -1107,13 +1191,17 @@ struct TupleVariationData } else { - new_vars.push (var); - if (!m.set (&(var.axis_tuples), i)) + auto *new_var = new_vars.push (); + if (unlikely (new_vars.in_error ())) + return false; + hb_swap (*new_var, var); + if (unlikely (!m.set (&(new_var->axis_tuples), new_vars.length - 1))) return false; - i++; } } - tuple_vars.fini (); + m.fini (); // Just in case, since it points into new_vars data. + // Shouldn't be necessary though, since we only move new_vars, not its + // contents. tuple_vars = std::move (new_vars); return true; } @@ -1173,20 +1261,22 @@ struct TupleVariationData } } - bool calc_inferred_deltas (const contour_point_vector_t& contour_points) + bool calc_inferred_deltas (const contour_point_vector_t& contour_points, + hb_vector_t &scratch) { for (tuple_delta_t& var : tuple_vars) - if (!var.calc_inferred_deltas (contour_points)) + if (!var.calc_inferred_deltas (contour_points, scratch)) return false; return true; } - bool iup_optimize (const contour_point_vector_t& contour_points) + bool iup_optimize (const contour_point_vector_t& contour_points, + optimize_scratch_t &scratch) { for (tuple_delta_t& var : tuple_vars) { - if (!var.optimize (contour_points, is_composite)) + if (!var.optimize (contour_points, is_composite, scratch)) return false; } return true; @@ -1195,16 +1285,21 @@ struct TupleVariationData public: bool instantiate (const hb_hashmap_t& normalized_axes_location, const hb_hashmap_t& axes_triple_distances, + optimize_scratch_t &scratch, + hb_alloc_pool_t *pool = nullptr, contour_point_vector_t* contour_points = nullptr, bool optimize = false) { if (!tuple_vars) return true; - if (!change_tuple_variations_axis_limits (normalized_axes_location, axes_triple_distances)) + if (!change_tuple_variations_axis_limits (normalized_axes_location, axes_triple_distances, pool)) return false; /* compute inferred deltas only for gvar */ if (contour_points) - if (!calc_inferred_deltas (*contour_points)) + { + hb_vector_t scratch; + if (!calc_inferred_deltas (*contour_points, scratch)) return false; + } /* if iup delta opt is on, contour_points can't be null */ if (optimize && !contour_points) @@ -1213,7 +1308,7 @@ struct TupleVariationData if (!merge_tuple_variations (optimize ? contour_points : nullptr)) return false; - if (optimize && !iup_optimize (*contour_points)) return false; + if (optimize && !iup_optimize (*contour_points, scratch)) return false; return !tuple_vars.in_error (); } @@ -1221,7 +1316,8 @@ struct TupleVariationData const hb_map_t& axes_old_index_tag_map, bool use_shared_points, bool is_gvar = false, - const hb_hashmap_t*, unsigned>* shared_tuples_idx_map = nullptr) + const hb_hashmap_t*, unsigned>* shared_tuples_idx_map = nullptr, + hb_alloc_pool_t *pool = nullptr) { // return true for empty glyph if (!tuple_vars) @@ -1241,6 +1337,7 @@ struct TupleVariationData if (shared_points_bytes) compiled_byte_size += shared_points_bytes->length; } + hb_vector_t rounded_deltas_scratch; // compile delta and tuple var header for each tuple variation for (auto& tuple: tuple_vars) { @@ -1254,12 +1351,13 @@ struct TupleVariationData * this tuple */ if (!points_data->length) continue; - if (!tuple.compile_deltas ()) + if (!tuple.compile_deltas (rounded_deltas_scratch, pool)) return false; unsigned points_data_length = (points_data != shared_points_bytes) ? points_data->length : 0; if (!tuple.compile_tuple_var_header (axes_index_map, points_data_length, axes_old_index_tag_map, - shared_tuples_idx_map)) + shared_tuples_idx_map, + pool)) return false; compiled_byte_size += tuple.compiled_tuple_header.length + points_data_length + tuple.compiled_deltas.length; } @@ -1330,8 +1428,9 @@ struct TupleVariationData { var_data_bytes = var_data_bytes_; var_data = var_data_bytes_.as (); - index = 0; + tuples_left = var_data->tupleVarCount.get_count (); axis_count = axis_count_; + axis_count_times_2 = axis_count_ * 2; current_tuple = &var_data->get_tuple_var_header (); data_offset = 0; table_base = table_base_; @@ -1349,30 +1448,42 @@ struct TupleVariationData return true; } - bool is_valid () const + bool is_valid () { - return (index < var_data->tupleVarCount.get_count ()) && - var_data_bytes.check_range (current_tuple, TupleVariationHeader::min_size) && - var_data_bytes.check_range (current_tuple, hb_max (current_tuple->get_data_size (), - current_tuple->get_size (axis_count))); + if (unlikely (tuples_left <= 0)) + return false; + + current_tuple_size = TupleVariationHeader::min_size; + if (unlikely (!var_data_bytes.check_end ((const char *) current_tuple + current_tuple_size))) + return false; + + current_tuple_size = current_tuple->get_size (axis_count_times_2); + if (unlikely (!var_data_bytes.check_end ((const char *) current_tuple + current_tuple_size))) + return false; + + return true; } + HB_ALWAYS_INLINE bool move_to_next () { data_offset += current_tuple->get_data_size (); - current_tuple = ¤t_tuple->get_next (axis_count); - index++; + current_tuple = &StructAtOffset (current_tuple, current_tuple_size); + tuples_left--; return is_valid (); } + // TODO: Make it return (sanitized) hb_bytes_t const HBUINT8 *get_serialized_data () const { return &(table_base+var_data->data) + data_offset; } private: + signed tuples_left; const TupleVariationData *var_data; - unsigned int index; unsigned int axis_count; + unsigned int axis_count_times_2; unsigned int data_offset; + unsigned int current_tuple_size; const void *table_base; public: @@ -1411,7 +1522,7 @@ struct TupleVariationData if (unlikely (p + 1 > end)) return false; count = ((count & POINT_RUN_COUNT_MASK) << 8) | *p++; } - if (unlikely (!points.resize (count, false))) return false; + if (unlikely (!points.resize_dirty (count))) return false; unsigned n = 0; unsigned i = 0; @@ -1446,12 +1557,14 @@ struct TupleVariationData } template + HB_ALWAYS_INLINE static bool decompile_deltas (const HBUINT8 *&p /* IN/OUT */, hb_vector_t &deltas /* IN/OUT */, const HBUINT8 *end, - bool consume_all = false) + bool consume_all = false, + unsigned start = 0) { - return TupleValues::decompile (p, deltas, end, consume_all); + return TupleValues::decompile (p, deltas, end, consume_all, start); } bool has_data () const { return tupleVarCount; } @@ -1463,6 +1576,7 @@ struct TupleVariationData const hb_vector_t &shared_indices, const hb_array_t shared_tuples, tuple_variations_t& tuple_variations, /* OUT */ + hb_alloc_pool_t *pool = nullptr, bool is_composite_glyph = false) const { return tuple_variations.create_from_tuple_var_data (iterator, tupleVarCount, @@ -1470,6 +1584,7 @@ struct TupleVariationData axes_old_index_tag_map, shared_indices, shared_tuples, + pool, is_composite_glyph); } @@ -1634,8 +1749,9 @@ struct item_variations_t bool instantiate_tuple_vars (const hb_hashmap_t& normalized_axes_location, const hb_hashmap_t& axes_triple_distances) { + optimize_scratch_t scratch; for (tuple_variations_t& tuple_vars : vars) - if (!tuple_vars.instantiate (normalized_axes_location, axes_triple_distances)) + if (!tuple_vars.instantiate (normalized_axes_location, axes_triple_distances, scratch)) return false; if (!build_region_list ()) return false; @@ -1720,30 +1836,28 @@ struct item_variations_t struct combined_gain_idx_tuple_t { - int gain; - unsigned idx_1; - unsigned idx_2; + uint64_t encoded; combined_gain_idx_tuple_t () = default; - combined_gain_idx_tuple_t (int gain_, unsigned i, unsigned j) - :gain (gain_), idx_1 (i), idx_2 (j) {} + combined_gain_idx_tuple_t (unsigned gain, unsigned i, unsigned j) + : encoded ((uint64_t (0xFFFFFF - gain) << 40) | (uint64_t (i) << 20) | uint64_t (j)) + { + assert (gain < 0xFFFFFF); + assert (i < 0xFFFFFFF && j < 0xFFFFFFF); + } bool operator < (const combined_gain_idx_tuple_t& o) { - if (gain != o.gain) - return gain < o.gain; - - if (idx_1 != o.idx_1) - return idx_1 < o.idx_1; - - return idx_2 < o.idx_2; + return encoded < o.encoded; } bool operator <= (const combined_gain_idx_tuple_t& o) { - if (*this < o) return true; - return gain == o.gain && idx_1 == o.idx_1 && idx_2 == o.idx_2; + return encoded <= o.encoded; } + + unsigned idx_1 () const { return (encoded >> 20) & 0xFFFFF; }; + unsigned idx_2 () const { return encoded & 0xFFFFF; }; }; bool as_item_varstore (bool optimize=true, bool use_no_variation_idx=true) @@ -1765,9 +1879,9 @@ struct item_variations_t hb_hashmap_t*> front_mapping; unsigned start_row = 0; hb_vector_t encoding_objs; - hb_hashmap_t, unsigned> chars_idx_map; /* delta_rows map, used for filtering out duplicate rows */ + hb_vector_t *> major_rows; hb_hashmap_t*, unsigned> delta_rows_map; for (unsigned major = 0; major < vars.length; major++) { @@ -1775,6 +1889,9 @@ struct item_variations_t * (row based) delta */ const tuple_variations_t& tuples = vars[major]; unsigned num_rows = var_data_num_rows[major]; + + if (!num_rows) continue; + for (const tuple_delta_t& tuple: tuples.tuple_vars) { if (tuple.deltas_x.length != num_rows) @@ -1789,24 +1906,11 @@ struct item_variations_t { int rounded_delta = roundf (tuple.deltas_x[i]); delta_rows[start_row + i][*col_idx] += rounded_delta; - if ((!has_long) && (rounded_delta < -65536 || rounded_delta > 65535)) - has_long = true; + has_long |= rounded_delta < -65536 || rounded_delta > 65535; } } - if (!optimize) - { - /* assemble a delta_row_encoding_t for this subtable, skip optimization so - * chars is not initialized, we only need delta rows for serialization */ - delta_row_encoding_t obj; - for (unsigned r = start_row; r < start_row + num_rows; r++) - obj.add_row (&(delta_rows.arrayZ[r])); - - encodings.push (std::move (obj)); - start_row += num_rows; - continue; - } - + major_rows.reset (); for (unsigned minor = 0; minor < num_rows; minor++) { const hb_vector_t& row = delta_rows[start_row + minor]; @@ -1828,42 +1932,40 @@ struct item_variations_t if (!front_mapping.set ((major<<16) + minor, &row)) return false; - hb_vector_t chars = delta_row_encoding_t::get_row_chars (row); - if (!chars) return false; - if (delta_rows_map.has (&row)) continue; delta_rows_map.set (&row, 1); - unsigned *obj_idx; - if (chars_idx_map.has (chars, &obj_idx)) - { - delta_row_encoding_t& obj = encoding_objs[*obj_idx]; - if (!obj.add_row (&row)) - return false; - } - else - { - if (!chars_idx_map.set (chars, encoding_objs.length)) - return false; - delta_row_encoding_t obj (std::move (chars), &row); - encoding_objs.push (std::move (obj)); - } + + major_rows.push (&row); } + if (major_rows) + encoding_objs.push (delta_row_encoding_t (std::move (major_rows), num_cols)); + start_row += num_rows; } /* return directly if no optimization, maintain original VariationIndex so * varidx_map would be empty */ - if (!optimize) return !encodings.in_error (); + if (!optimize) + { + encodings = std::move (encoding_objs); + return !encodings.in_error (); + } - /* sort encoding_objs */ + /* NOTE: Fonttools instancer always optimizes VarStore from scratch. This + * is too costly for large fonts. So, instead, we retain the encodings of + * the original VarStore, and just try to combine them if possible. This + * is a compromise between optimization and performance and practically + * works very well. */ + + // This produces slightly smaller results in some cases. encoding_objs.qsort (); - /* main algorithm: repeatedly pick 2 best encodings to combine, and combine - * them */ - hb_priority_queue_t queue; + /* main algorithm: repeatedly pick 2 best encodings to combine, and combine them */ + using item_t = hb_priority_queue_t::item_t; + hb_vector_t queue_items; unsigned num_todos = encoding_objs.length; for (unsigned i = 0; i < num_todos; i++) { @@ -1871,16 +1973,18 @@ struct item_variations_t { int combining_gain = encoding_objs.arrayZ[i].gain_from_merging (encoding_objs.arrayZ[j]); if (combining_gain > 0) - queue.insert (combined_gain_idx_tuple_t (-combining_gain, i, j), 0); + queue_items.push (item_t (combined_gain_idx_tuple_t (combining_gain, i, j), 0)); } } - hb_set_t removed_todo_idxes; + hb_priority_queue_t queue (std::move (queue_items)); + + hb_bit_set_t removed_todo_idxes; while (queue) { auto t = queue.pop_minimum ().first; - unsigned i = t.idx_1; - unsigned j = t.idx_2; + unsigned i = t.idx_1 (); + unsigned j = t.idx_2 (); if (removed_todo_idxes.has (i) || removed_todo_idxes.has (j)) continue; @@ -1891,40 +1995,36 @@ struct item_variations_t removed_todo_idxes.add (i); removed_todo_idxes.add (j); - hb_vector_t combined_chars; - if (!combined_chars.alloc (encoding.chars.length)) - return false; - - for (unsigned idx = 0; idx < encoding.chars.length; idx++) - { - uint8_t v = hb_max (encoding.chars.arrayZ[idx], other_encoding.chars.arrayZ[idx]); - combined_chars.push (v); - } - - delta_row_encoding_t combined_encoding_obj (std::move (combined_chars)); - for (const auto& row : hb_concat (encoding.items, other_encoding.items)) - combined_encoding_obj.add_row (row); + encoding.merge (other_encoding); for (unsigned idx = 0; idx < encoding_objs.length; idx++) { if (removed_todo_idxes.has (idx)) continue; const delta_row_encoding_t& obj = encoding_objs.arrayZ[idx]; - if (obj.chars == combined_chars) + // In the unlikely event that the same encoding exists already, combine it. + if (obj.width == encoding.width && obj.chars == encoding.chars) { + // This is straight port from fonttools algorithm. I added this branch there + // because I thought it can happen. But looks like we never get in here in + // practice. I'm not confident enough to remove it though; in theory it can + // happen. I think it's just that our tests are not extensive enough to hit + // this path. + for (const auto& row : obj.items) - combined_encoding_obj.add_row (row); + encoding.add_row (row); removed_todo_idxes.add (idx); continue; } - int combined_gain = combined_encoding_obj.gain_from_merging (obj); + int combined_gain = encoding.gain_from_merging (obj); if (combined_gain > 0) - queue.insert (combined_gain_idx_tuple_t (-combined_gain, idx, encoding_objs.length), 0); + queue.insert (combined_gain_idx_tuple_t (combined_gain, idx, encoding_objs.length), 0); } - encoding_objs.push (std::move (combined_encoding_obj)); + auto moved_encoding = std::move (encoding); + encoding_objs.push (moved_encoding); } int num_final_encodings = (int) encoding_objs.length - (int) removed_todo_idxes.get_population (); @@ -1937,9 +2037,6 @@ struct item_variations_t encodings.push (std::move (encoding_objs.arrayZ[i])); } - /* sort again based on width, make result deterministic */ - encodings.qsort (delta_row_encoding_t::cmp_width); - return compile_varidx_map (front_mapping); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-cvar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-cvar-table.hh index 3dc4ebaebd8..d8f497d5346 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-cvar-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-cvar-table.hh @@ -84,7 +84,7 @@ struct cvar if (!coords) return true; hb_vector_t shared_indices; TupleVariationData<>::tuple_iterator_t iterator; - unsigned var_data_length = tuple_var_data->get_size (axis_count); + unsigned var_data_length = tuple_var_data->get_size (axis_count * 2); hb_bytes_t var_data_bytes = hb_bytes_t (reinterpret_cast (tuple_var_data), var_data_length); if (!TupleVariationData<>::get_tuple_iterator (var_data_bytes, axis_count, base, shared_indices, &iterator)) @@ -113,7 +113,7 @@ struct cvar bool apply_to_all = (indices.length == 0); unsigned num_deltas = apply_to_all ? num_cvt_item : indices.length; - if (unlikely (!unpacked_deltas.resize (num_deltas, false))) return false; + if (unlikely (!unpacked_deltas.resize_dirty (num_deltas))) return false; if (unlikely (!TupleVariationData<>::decompile_deltas (p, unpacked_deltas, end))) return false; for (unsigned int i = 0; i < num_deltas; i++) @@ -158,7 +158,8 @@ struct cvar tuple_variations)) return_trace (false); - if (!tuple_variations.instantiate (c->plan->axes_location, c->plan->axes_triple_distances)) + optimize_scratch_t scratch; + if (!tuple_variations.instantiate (c->plan->axes_location, c->plan->axes_triple_distances, scratch)) return_trace (false); if (!tuple_variations.compile_bytes (c->plan->axes_index_map, c->plan->axes_old_index_tag_map, diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-fvar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-fvar-table.hh index f2725eaa282..74d392de9b7 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-fvar-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-fvar-table.hh @@ -179,7 +179,7 @@ struct AxisRecord hb_tag_t get_axis_tag () const { return axisTag; } - int normalize_axis_value (float v) const + float normalize_axis_value (float v) const { float min_value, default_value, max_value; get_coordinates (min_value, default_value, max_value); @@ -189,23 +189,9 @@ struct AxisRecord if (v == default_value) return 0; else if (v < default_value) - v = (v - default_value) / (default_value - min_value); + return (v - default_value) / (default_value - min_value); else - v = (v - default_value) / (max_value - default_value); - return roundf (v * 16384.f); - } - - float unnormalize_axis_value (int v) const - { - float min_value, default_value, max_value; - get_coordinates (min_value, default_value, max_value); - - if (v == 0) - return default_value; - else if (v < 0) - return v * (default_value - min_value) / 16384.f + default_value; - else - return v * (max_value - default_value) / 16384.f + default_value; + return (v - default_value) / (max_value - default_value); } hb_ot_name_id_t get_name_id () const { return axisNameID; } @@ -341,12 +327,9 @@ struct fvar return axes.lfind (tag, &i) && ((void) axes[i].get_axis_info (i, info), true); } - int normalize_axis_value (unsigned int axis_index, float v) const + float normalize_axis_value (unsigned int axis_index, float v) const { return get_axes ()[axis_index].normalize_axis_value (v); } - float unnormalize_axis_value (unsigned int axis_index, int v) const - { return get_axes ()[axis_index].unnormalize_axis_value (v); } - unsigned int get_instance_count () const { return instanceCount; } hb_ot_name_id_t get_instance_subfamily_name_id (unsigned int instance_index) const diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh index 9f9b5be3cbe..7c42f548456 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh @@ -66,12 +66,14 @@ struct glyph_variations_t hb_vector_t glyph_variations; - hb_vector_t compiled_shared_tuples; + hb_vector_t compiled_shared_tuples; private: unsigned shared_tuples_count = 0; /* shared coords-> index map after instantiation */ - hb_hashmap_t*, unsigned> shared_tuples_idx_map; + hb_hashmap_t*, unsigned> shared_tuples_idx_map; + + hb_alloc_pool_t pool; public: unsigned compiled_shared_tuples_count () const @@ -128,6 +130,7 @@ struct glyph_variations_t iterator, &(plan->axes_old_index_tag_map), shared_indices, shared_tuples, tuple_vars, /* OUT */ + &pool, is_composite_glyph)) return false; glyph_variations.push (std::move (tuple_vars)); @@ -139,6 +142,7 @@ struct glyph_variations_t { unsigned count = plan->new_to_old_gid_list.length; bool iup_optimize = false; + optimize_scratch_t scratch; iup_optimize = plan->flags & HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS; for (unsigned i = 0; i < count; i++) { @@ -146,7 +150,7 @@ struct glyph_variations_t contour_point_vector_t *all_points; if (!plan->new_gid_contour_points_map.has (new_gid, &all_points)) return false; - if (!glyph_variations[i].instantiate (plan->axes_location, plan->axes_triple_distances, all_points, iup_optimize)) + if (!glyph_variations[i].instantiate (plan->axes_location, plan->axes_triple_distances, scratch, &pool, all_points, iup_optimize)) return false; } return true; @@ -161,7 +165,8 @@ struct glyph_variations_t if (!vars.compile_bytes (axes_index_map, axes_old_index_tag_map, true, /* use shared points*/ true, - &shared_tuples_idx_map)) + &shared_tuples_idx_map, + &pool)) return false; return true; @@ -172,20 +177,21 @@ struct glyph_variations_t { /* key is pointer to compiled_peak_coords inside each tuple, hashing * function will always deref pointers first */ - hb_hashmap_t*, unsigned> coords_count_map; + hb_hashmap_t*, unsigned> coords_count_map; /* count the num of shared coords */ for (tuple_variations_t& vars: glyph_variations) { for (tuple_delta_t& var : vars.tuple_vars) { - if (!var.compile_peak_coords (axes_index_map, axes_old_index_tag_map)) + if (!var.compile_coords (axes_index_map, axes_old_index_tag_map, &pool)) return false; - unsigned* count; - if (coords_count_map.has (&(var.compiled_peak_coords), &count)) - coords_count_map.set (&(var.compiled_peak_coords), *count + 1); + unsigned *count; + unsigned hash = hb_hash (&var.compiled_peak_coords); + if (coords_count_map.has_with_hash (&(var.compiled_peak_coords), hash, &count)) + (*count)++; else - coords_count_map.set (&(var.compiled_peak_coords), 1); + coords_count_map.set_with_hash (&(var.compiled_peak_coords), hash, 1); } } @@ -193,66 +199,45 @@ struct glyph_variations_t return false; /* add only those coords that are used more than once into the vector and sort */ - hb_vector_t*> shared_coords; - if (unlikely (!shared_coords.alloc (coords_count_map.get_population ()))) - return false; - - for (const auto _ : coords_count_map.iter ()) - { - if (_.second == 1) continue; - shared_coords.push (_.first); - } + hb_vector_t*, unsigned>> shared_coords { + + hb_iter (coords_count_map) + | hb_filter ([] (const hb_pair_t*, unsigned>& p) { return p.second > 1; }) + }; + if (unlikely (shared_coords.in_error ())) return false; /* no shared tuples: no coords are used more than once */ if (!shared_coords) return true; /* sorting based on the coords frequency first (high to low), then compare * the coords bytes */ - hb_qsort (shared_coords.arrayZ, shared_coords.length, sizeof (hb_vector_t*), _cmp_coords, (void *) (&coords_count_map)); + shared_coords.qsort (_cmp_coords); /* build shared_coords->idx map and shared tuples byte array */ shared_tuples_count = hb_min (0xFFFu + 1, shared_coords.length); - unsigned len = shared_tuples_count * (shared_coords[0]->length); + unsigned len = shared_tuples_count * (shared_coords[0].first->length); if (unlikely (!compiled_shared_tuples.alloc (len))) return false; for (unsigned i = 0; i < shared_tuples_count; i++) { - shared_tuples_idx_map.set (shared_coords[i], i); + shared_tuples_idx_map.set (shared_coords[i].first, i); /* add a concat() in hb_vector_t? */ - for (char c : shared_coords[i]->iter ()) + for (auto c : shared_coords[i].first->iter ()) compiled_shared_tuples.push (c); } return true; } - static int _cmp_coords (const void *pa, const void *pb, void *arg) + static int _cmp_coords (const void *pa, const void *pb) { - const hb_hashmap_t*, unsigned>* coords_count_map = - reinterpret_cast*, unsigned>*> (arg); + const hb_pair_t *, unsigned> *a = (const hb_pair_t *, unsigned> *) pa; + const hb_pair_t *, unsigned> *b = (const hb_pair_t *, unsigned> *) pb; - /* shared_coords is hb_vector_t*> so casting pa/pb - * to be a pointer to a pointer */ - const hb_vector_t** a = reinterpret_cast**> (const_cast(pa)); - const hb_vector_t** b = reinterpret_cast**> (const_cast(pb)); + if (a->second != b->second) + return b->second - a->second; // high to low - bool has_a = coords_count_map->has (*a); - bool has_b = coords_count_map->has (*b); - - if (has_a && has_b) - { - unsigned a_num = coords_count_map->get (*a); - unsigned b_num = coords_count_map->get (*b); - - if (a_num != b_num) - return b_num - a_num; - - return (*b)->as_array().cmp ((*a)->as_array ()); - } - else if (has_a) return -1; - else if (has_b) return 1; - else return 0; + return b->first->as_array().cmp (a->first->as_array ()); } templatesharedTuples = 0; else { - hb_array_t shared_tuples = glyph_vars.compiled_shared_tuples.as_array ().copy (c); + hb_array_t shared_tuples = glyph_vars.compiled_shared_tuples.as_array ().copy (c); if (!shared_tuples.arrayZ) return_trace (false); - out->sharedTuples = shared_tuples.arrayZ - (char *) out; + out->sharedTuples = (const char *) shared_tuples.arrayZ - (char *) out; } char *glyph_var_data = c->start_embed (); @@ -463,10 +448,18 @@ struct gvar_GVAR if (it->first == 0 && !(c->plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) it++; unsigned int subset_data_size = 0; + unsigned padding_size = 0; for (auto &_ : it) { hb_codepoint_t old_gid = _.second; - subset_data_size += get_glyph_var_data_bytes (c->source_blob, glyph_count, old_gid).length; + unsigned glyph_data_size = get_glyph_var_data_bytes (c->source_blob, glyph_count, old_gid).length; + if (glyph_data_size % 2) + { + glyph_data_size++; + padding_size++; + } + + subset_data_size += glyph_data_size; } /* According to the spec: If the short format (Offset16) is used for offsets, @@ -495,6 +488,8 @@ struct gvar_GVAR /* This ordering relative to the shared tuples array, which puts the glyphVariationData last in the table, is required when HB_SUBSET_FLAGS_IFTB_REQUIREMENTS is set */ + if (long_offset) + subset_data_size -= padding_size; char *subset_data = c->serializer->allocate_size (subset_data_size, false); if (!subset_data) return_trace (false); out->dataZ = subset_data - (char *) out; @@ -533,8 +528,16 @@ struct gvar_GVAR old_gid); hb_memcpy (subset_data, var_data_bytes.arrayZ, var_data_bytes.length); - subset_data += var_data_bytes.length; - glyph_offset += var_data_bytes.length; + unsigned glyph_data_size = var_data_bytes.length; + subset_data += glyph_data_size; + glyph_offset += glyph_data_size; + + if (!long_offset && (glyph_data_size % 2)) + { + *subset_data = 0; + subset_data++; + glyph_offset++; + } if (long_offset) ((HBUINT32 *) subset_offsets)[gid] = glyph_offset; @@ -582,6 +585,17 @@ struct gvar_GVAR public: struct accelerator_t { + + hb_scalar_cache_t *create_cache () const + { + return hb_scalar_cache_t::create (table->sharedTupleCount); + } + + static void destroy_cache (hb_scalar_cache_t *cache) + { + hb_scalar_cache_t::destroy (cache); + } + bool has_data () const { return table->has_data (); } accelerator_t (hb_face_t *face) @@ -589,36 +603,6 @@ struct gvar_GVAR table = hb_sanitize_context_t ().reference_table (face); /* If sanitize failed, set glyphCount to 0. */ glyphCount = table->version.to_int () ? face->get_num_glyphs () : 0; - - /* For shared tuples that only have one or two axes active, shared the index - * of that axis as a cache. This will speed up caclulate_scalar() a lot - * for fonts with lots of axes and many "monovar" or "duovar" tuples. */ - hb_array_t shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * table->axisCount); - unsigned count = table->sharedTupleCount; - if (unlikely (!shared_tuple_active_idx.resize (count, false))) return; - unsigned axis_count = table->axisCount; - for (unsigned i = 0; i < count; i++) - { - hb_array_t tuple = shared_tuples.sub_array (axis_count * i, axis_count); - int idx1 = -1, idx2 = -1; - for (unsigned j = 0; j < axis_count; j++) - { - const F2DOT14 &peak = tuple.arrayZ[j]; - if (peak.to_int () != 0) - { - if (idx1 == -1) - idx1 = j; - else if (idx2 == -1) - idx2 = j; - else - { - idx1 = idx2 = -1; - break; - } - } - } - shared_tuple_active_idx.arrayZ[i] = {idx1, idx2}; - } } ~accelerator_t () { table.destroy (); } @@ -655,6 +639,7 @@ struct gvar_GVAR hb_array_t coords, const hb_array_t points, hb_glyf_scratch_t &scratch, + hb_scalar_cache_t *gvar_cache = nullptr, bool phantom_only = false) const { if (unlikely (glyph >= glyphCount)) return true; @@ -690,10 +675,12 @@ struct gvar_GVAR unsigned count = points.length; bool flush = false; + do { float scalar = iterator.current_tuple->calculate_scalar (coords, num_coords, shared_tuples, - &shared_tuple_active_idx); + gvar_cache); + if (scalar == 0.f) continue; const HBUINT8 *p = iterator.get_serialized_data (); unsigned int length = iterator.current_tuple->get_data_size (); @@ -702,7 +689,7 @@ struct gvar_GVAR if (!deltas) { - if (unlikely (!deltas_vec.resize (count, false))) return false; + if (unlikely (!deltas_vec.resize_dirty (count))) return false; deltas = deltas_vec.as_array (); hb_memset (deltas.arrayZ + (phantom_only ? count - 4 : 0), 0, (phantom_only ? 4 : count) * sizeof (deltas[0])); @@ -717,11 +704,12 @@ struct gvar_GVAR const hb_array_t &indices = has_private_points ? private_indices : shared_indices; bool apply_to_all = (indices.length == 0); - unsigned int num_deltas = apply_to_all ? points.length : indices.length; - if (unlikely (!x_deltas.resize (num_deltas, false))) return false; - if (unlikely (!GlyphVariationData::decompile_deltas (p, x_deltas, end))) return false; - if (unlikely (!y_deltas.resize (num_deltas, false))) return false; - if (unlikely (!GlyphVariationData::decompile_deltas (p, y_deltas, end))) return false; + unsigned num_deltas = apply_to_all ? points.length : indices.length; + unsigned start_deltas = (apply_to_all && phantom_only && num_deltas >= 4 ? num_deltas - 4 : 0); + if (unlikely (!x_deltas.resize_dirty (num_deltas))) return false; + if (unlikely (!GlyphVariationData::decompile_deltas (p, x_deltas, end, false, start_deltas))) return false; + if (unlikely (!y_deltas.resize_dirty (num_deltas))) return false; + if (unlikely (!GlyphVariationData::decompile_deltas (p, y_deltas, end, false, start_deltas))) return false; if (!apply_to_all) { @@ -884,7 +872,6 @@ struct gvar_GVAR private: hb_blob_ptr_t table; unsigned glyphCount; - hb_vector_t> shared_tuple_active_idx; }; protected: diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-hvar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-hvar-table.hh index 40a85a62b78..652d738e7b5 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-hvar-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-hvar-table.hh @@ -42,57 +42,62 @@ struct index_map_subset_plan_t VORG_INDEX }; - void init (const DeltaSetIndexMap &index_map, + void init (const DeltaSetIndexMap *index_map, hb_inc_bimap_t &outer_map, hb_vector_t &inner_sets, const hb_subset_plan_t *plan, bool bypass_empty = true) { map_count = 0; - outer_bit_count = 0; - inner_bit_count = 1; max_inners.init (); output_map.init (); - if (bypass_empty && !index_map.get_map_count ()) return; + if (bypass_empty && (!index_map || !index_map->get_map_count ())) return; unsigned int last_val = (unsigned int)-1; hb_codepoint_t last_gid = HB_CODEPOINT_INVALID; - outer_bit_count = (index_map.get_width () * 8) - index_map.get_inner_bit_count (); max_inners.resize (inner_sets.length); for (unsigned i = 0; i < inner_sets.length; i++) max_inners[i] = 0; /* Search backwards for a map value different from the last map value */ auto &new_to_old_gid_list = plan->new_to_old_gid_list; unsigned count = new_to_old_gid_list.length; - for (unsigned j = count; j; j--) + if (!index_map) { - hb_codepoint_t gid = new_to_old_gid_list.arrayZ[j - 1].first; - hb_codepoint_t old_gid = new_to_old_gid_list.arrayZ[j - 1].second; - - unsigned int v = index_map.map (old_gid); - if (last_gid == HB_CODEPOINT_INVALID) + map_count = new_to_old_gid_list.tail ().first + 1; + } + else + { + for (unsigned j = count; j; j--) { + hb_codepoint_t gid = new_to_old_gid_list.arrayZ[j - 1].first; + hb_codepoint_t old_gid = new_to_old_gid_list.arrayZ[j - 1].second; + + unsigned int v = index_map->map (old_gid); + if (last_gid == HB_CODEPOINT_INVALID) + { last_val = v; last_gid = gid; continue; - } - if (v != last_val) + } + if (v != last_val) break; - last_gid = gid; + last_gid = gid; + } + + if (unlikely (last_gid == (hb_codepoint_t)-1)) return; + map_count = last_gid + 1; } - if (unlikely (last_gid == (hb_codepoint_t)-1)) return; - map_count = last_gid + 1; for (auto _ : plan->new_to_old_gid_list) { hb_codepoint_t gid = _.first; if (gid >= map_count) break; hb_codepoint_t old_gid = _.second; - unsigned int v = index_map.map (old_gid); + unsigned int v = index_map ? index_map->map (old_gid): old_gid; unsigned int outer = v >> 16; unsigned int inner = v & 0xFFFF; outer_map.add (outer); @@ -113,6 +118,9 @@ struct index_map_subset_plan_t const hb_vector_t &inner_maps, const hb_subset_plan_t *plan) { + outer_bit_count = 1; + inner_bit_count = 1; + for (unsigned int i = 0; i < max_inners.length; i++) { if (inner_maps[i].get_population () == 0) continue; @@ -128,9 +136,13 @@ struct index_map_subset_plan_t if (unlikely (new_gid >= map_count)) break; - uint32_t v = input_map->map (old_gid); - unsigned int outer = v >> 16; - output_map.arrayZ[new_gid] = (outer_map[outer] << 16) | (inner_maps[outer][v & 0xFFFF]); + uint32_t v = input_map? input_map->map (old_gid) : old_gid; + unsigned outer = v >> 16; + unsigned new_outer = outer_map[outer]; + unsigned bit_count = (new_outer == 0) ? 1 : hb_bit_storage (new_outer); + outer_bit_count = hb_max (bit_count, outer_bit_count); + + output_map.arrayZ[new_gid] = (new_outer << 16) | (inner_maps[outer][v & 0xFFFF]); } } @@ -204,8 +216,8 @@ struct hvarvvar_subset_plan_t if (unlikely (!index_map_plans.length || !inner_sets.length || !inner_maps.length)) return; bool retain_adv_map = false; - index_map_plans[0].init (*index_maps[0], outer_map, inner_sets, plan, false); - if (index_maps[0] == &Null (DeltaSetIndexMap)) + index_map_plans[0].init (index_maps[0], outer_map, inner_sets, plan, false); + if (!index_maps[0]) { retain_adv_map = plan->flags & HB_SUBSET_FLAGS_RETAIN_GIDS; outer_map.add (0); @@ -215,7 +227,7 @@ struct hvarvvar_subset_plan_t } for (unsigned int i = 1; i < index_maps.length; i++) - index_map_plans[i].init (*index_maps[i], outer_map, inner_sets, plan); + index_map_plans[i].init (index_maps[i], outer_map, inner_sets, plan); outer_map.sort (); @@ -284,6 +296,8 @@ struct HVARVVAR static constexpr hb_tag_t HVARTag = HB_OT_TAG_HVAR; static constexpr hb_tag_t VVARTag = HB_OT_TAG_VVAR; + bool has_data () const { return version.major != 0; } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -301,9 +315,14 @@ struct HVARVVAR void listup_index_maps (hb_vector_t &index_maps) const { - index_maps.push (&(this+advMap)); - index_maps.push (&(this+lsbMap)); - index_maps.push (&(this+rsbMap)); + if (advMap) index_maps.push (&(this+advMap)); + else index_maps.push (nullptr); + + if (lsbMap) index_maps.push (&(this+lsbMap)); + else index_maps.push (nullptr); + + if (rsbMap) index_maps.push (&(this+rsbMap)); + else index_maps.push (nullptr); } bool serialize_index_maps (hb_serialize_context_t *c, @@ -382,9 +401,10 @@ struct HVARVVAR hvar_plan.index_map_plans.as_array ())); } + HB_ALWAYS_INLINE float get_advance_delta_unscaled (hb_codepoint_t glyph, const int *coords, unsigned int coord_count, - ItemVariationStore::cache_t *store_cache = nullptr) const + hb_scalar_cache_t *store_cache = nullptr) const { uint32_t varidx = (this+advMap).map (glyph); return (this+varStore).get_delta (varidx, @@ -392,16 +412,6 @@ struct HVARVVAR store_cache); } - bool get_lsb_delta_unscaled (hb_codepoint_t glyph, - const int *coords, unsigned int coord_count, - float *lsb) const - { - if (!lsbMap) return false; - uint32_t varidx = (this+lsbMap).map (glyph); - *lsb = (this+varStore).get_delta (varidx, coords, coord_count); - return true; - } - public: FixedVersion<>version; /* Version of the metrics variation table * initially set to 0x00010000u */ @@ -435,7 +445,8 @@ struct VVAR : HVARVVAR { void listup_index_maps (hb_vector_t &index_maps) const { HVARVVAR::listup_index_maps (index_maps); - index_maps.push (&(this+vorgMap)); + if (vorgMap) index_maps.push (&(this+vorgMap)); + else index_maps.push (nullptr); } bool serialize_index_maps (hb_serialize_context_t *c, @@ -454,14 +465,16 @@ struct VVAR : HVARVVAR { bool subset (hb_subset_context_t *c) const { return HVARVVAR::_subset (c); } - bool get_vorg_delta_unscaled (hb_codepoint_t glyph, - const int *coords, unsigned int coord_count, - float *delta) const + HB_ALWAYS_INLINE + float get_vorg_delta_unscaled (hb_codepoint_t glyph, + const int *coords, unsigned int coord_count, + hb_scalar_cache_t *store_cache = nullptr) const { - if (!vorgMap) return false; + if (!vorgMap) return 0.f; uint32_t varidx = (this+vorgMap).map (glyph); - *delta = (this+varStore).get_delta (varidx, coords, coord_count); - return true; + return (this+varStore).get_delta (varidx, + coords, coord_count, + store_cache); } protected: diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-var.cc index 8c695c41e24..4d594d587d8 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var.cc @@ -286,10 +286,14 @@ hb_ot_var_normalize_variations (hb_face_t *face, hb_ot_var_axis_info_t info; if (hb_ot_var_find_axis_info (face, variations[i].tag, &info) && info.axis_index < coords_length) - coords[info.axis_index] = fvar.normalize_axis_value (info.axis_index, variations[i].value); + coords[info.axis_index] = roundf (fvar.normalize_axis_value (info.axis_index, variations[i].value) * 65536.0f); } - face->table.avar->map_coords (coords, coords_length); + face->table.avar->map_coords_16_16 (coords, coords_length); + + // Round to 2.14 + for (unsigned i = 0; i < coords_length; i++) + coords[i] = (coords[i] + 2) >> 2; } /** @@ -309,6 +313,10 @@ hb_ot_var_normalize_variations (hb_face_t *face, * Any additional scaling defined in the face's `avar` table is also * applied, as described at https://docs.microsoft.com/en-us/typography/opentype/spec/avar * + * Note: @coords_length must be the same as the number of axes in the face, as + * for example returned by hb_ot_var_get_axis_count(). + * Otherwise, the behavior is undefined. + * * Since: 1.4.2 **/ void @@ -319,9 +327,13 @@ hb_ot_var_normalize_coords (hb_face_t *face, { const OT::fvar &fvar = *face->table.fvar; for (unsigned int i = 0; i < coords_length; i++) - normalized_coords[i] = fvar.normalize_axis_value (i, design_coords[i]); + normalized_coords[i] = roundf (fvar.normalize_axis_value (i, design_coords[i]) * 65536.0f); - face->table.avar->map_coords (normalized_coords, coords_length); + face->table.avar->map_coords_16_16 (normalized_coords, coords_length); + + // Round to 2.14 + for (unsigned i = 0; i < coords_length; i++) + normalized_coords[i] = (normalized_coords[i] + 2) >> 2; } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-vorg-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-vorg-table.hh index b2300a327da..ff7ce678e4e 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-vorg-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-vorg-table.hh @@ -61,6 +61,7 @@ struct VORG bool has_data () const { return version.to_int (); } + HB_ALWAYS_INLINE int get_y_origin (hb_codepoint_t glyph) const { unsigned int i; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-outline.cc b/src/java.desktop/share/native/libharfbuzz/hb-outline.cc index 85ffc793678..12963fe46e3 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-outline.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-outline.cc @@ -84,6 +84,15 @@ void hb_outline_t::replay (hb_draw_funcs_t *pen, void *pen_data) const } } +void hb_outline_t::translate (float dx, float dy) +{ + for (auto &p : points) + { + p.x += dx; + p.y += dy; + } +} + void hb_outline_t::slant (float slant_xy) { for (auto &p : points) diff --git a/src/java.desktop/share/native/libharfbuzz/hb-outline.hh b/src/java.desktop/share/native/libharfbuzz/hb-outline.hh index c5b68c05dd7..9e394a68d9c 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-outline.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-outline.hh @@ -69,6 +69,7 @@ struct hb_outline_t HB_INTERNAL void replay (hb_draw_funcs_t *pen, void *pen_data) const; HB_INTERNAL float control_area () const; + HB_INTERNAL void translate (float dx, float dy); HB_INTERNAL void slant (float slant_xy); HB_INTERNAL void embolden (float x_strength, float y_strength, float x_shift, float y_shift); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-paint-extents.cc b/src/java.desktop/share/native/libharfbuzz/hb-paint-extents.cc index bc08c5a9e14..e867f37f3c5 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-paint-extents.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-paint-extents.cc @@ -49,7 +49,7 @@ hb_paint_extents_push_transform (hb_paint_funcs_t *funcs HB_UNUSED, { hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; - c->push_transform (hb_transform_t {xx, yx, xy, yy, dx, dy}); + c->push_transform (hb_transform_t<> {xx, yx, xy, yy, dx, dy}); } static void @@ -71,7 +71,7 @@ hb_paint_extents_push_clip_glyph (hb_paint_funcs_t *funcs HB_UNUSED, { hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; - hb_extents_t extents; + hb_extents_t<> extents; hb_draw_funcs_t *draw_extent_funcs = hb_draw_extents_get_funcs (); hb_font_draw_glyph (font, glyph, draw_extent_funcs, &extents); c->push_clip (extents); @@ -85,7 +85,7 @@ hb_paint_extents_push_clip_rectangle (hb_paint_funcs_t *funcs HB_UNUSED, { hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; - hb_extents_t extents = {xmin, ymin, xmax, ymax}; + hb_extents_t<> extents = {xmin, ymin, xmax, ymax}; c->push_clip (extents); } @@ -136,10 +136,10 @@ hb_paint_extents_paint_image (hb_paint_funcs_t *funcs HB_UNUSED, if (!glyph_extents) return false; // Happens with SVG images. - hb_extents_t extents = {(float) glyph_extents->x_bearing, - (float) glyph_extents->y_bearing + glyph_extents->height, - (float) glyph_extents->x_bearing + glyph_extents->width, - (float) glyph_extents->y_bearing}; + hb_extents_t<> extents = {(float) glyph_extents->x_bearing, + (float) glyph_extents->y_bearing + glyph_extents->height, + (float) glyph_extents->x_bearing + glyph_extents->width, + (float) glyph_extents->y_bearing}; c->push_clip (extents); c->paint (); c->pop_clip (); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-paint-extents.hh b/src/java.desktop/share/native/libharfbuzz/hb-paint-extents.hh index 60374eaa2d2..531eb3c7c52 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-paint-extents.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-paint-extents.hh @@ -41,9 +41,9 @@ struct hb_paint_extents_context_t clips.clear (); groups.clear (); - transforms.push (hb_transform_t{}); - clips.push (hb_bounds_t{hb_bounds_t::UNBOUNDED}); - groups.push (hb_bounds_t{hb_bounds_t::EMPTY}); + transforms.push (hb_transform_t<>{}); + clips.push (hb_bounds_t<>{hb_bounds_t<>::UNBOUNDED}); + groups.push (hb_bounds_t<>{hb_bounds_t<>::EMPTY}); } hb_paint_extents_context_t () @@ -51,19 +51,19 @@ struct hb_paint_extents_context_t clear (); } - hb_extents_t get_extents () + hb_extents_t<> get_extents () { return groups.tail().extents; } bool is_bounded () { - return groups.tail().status != hb_bounds_t::UNBOUNDED; + return groups.tail().status != hb_bounds_t<>::UNBOUNDED; } - void push_transform (const hb_transform_t &trans) + void push_transform (const hb_transform_t<> &trans) { - hb_transform_t t = transforms.tail (); + hb_transform_t<> t = transforms.tail (); t.multiply (trans); transforms.push (t); } @@ -73,13 +73,13 @@ struct hb_paint_extents_context_t transforms.pop (); } - void push_clip (hb_extents_t extents) + void push_clip (hb_extents_t<> extents) { /* Transform extents and push a new clip. */ - const hb_transform_t &t = transforms.tail (); + const hb_transform_t<> &t = transforms.tail (); t.transform_extents (extents); - auto bounds = hb_bounds_t {extents}; + auto bounds = hb_bounds_t<> {extents}; bounds.intersect (clips.tail ()); clips.push (bounds); @@ -92,19 +92,19 @@ struct hb_paint_extents_context_t void push_group () { - groups.push (hb_bounds_t {hb_bounds_t::EMPTY}); + groups.push (hb_bounds_t<> {hb_bounds_t<>::EMPTY}); } void pop_group (hb_paint_composite_mode_t mode) { - const hb_bounds_t src_bounds = groups.pop (); - hb_bounds_t &backdrop_bounds = groups.tail (); + const hb_bounds_t<> src_bounds = groups.pop (); + hb_bounds_t<> &backdrop_bounds = groups.tail (); // https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-32-paintcomposite switch ((int) mode) { case HB_PAINT_COMPOSITE_MODE_CLEAR: - backdrop_bounds.status = hb_bounds_t::EMPTY; + backdrop_bounds.status = hb_bounds_t<>::EMPTY; break; case HB_PAINT_COMPOSITE_MODE_SRC: case HB_PAINT_COMPOSITE_MODE_SRC_OUT: @@ -125,16 +125,16 @@ struct hb_paint_extents_context_t void paint () { - const hb_bounds_t &clip = clips.tail (); - hb_bounds_t &group = groups.tail (); + const hb_bounds_t<> &clip = clips.tail (); + hb_bounds_t<> &group = groups.tail (); group.union_ (clip); } protected: - hb_vector_t transforms; - hb_vector_t clips; - hb_vector_t groups; + hb_vector_t> transforms; + hb_vector_t> clips; + hb_vector_t> groups; }; HB_INTERNAL hb_paint_funcs_t * diff --git a/src/java.desktop/share/native/libharfbuzz/hb-paint.hh b/src/java.desktop/share/native/libharfbuzz/hb-paint.hh index 2abadebab3c..aedbcbdcbe2 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-paint.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-paint.hh @@ -28,6 +28,7 @@ #include "hb.hh" #include "hb-face.hh" #include "hb-font.hh" +#include "hb-geometry.hh" #define HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS \ HB_PAINT_FUNC_IMPLEMENT (push_transform) \ @@ -72,7 +73,11 @@ struct hb_paint_funcs_t float xx, float yx, float xy, float yy, float dx, float dy) - { func.push_transform (this, paint_data, + { + // Handle -0.f to avoid -0.f == 0.f in the transform matrix. + if (dx == -0.f) dx = 0.f; + if (dy == -0.f) dy = 0.f; + func.push_transform (this, paint_data, xx, yx, xy, yy, dx, dy, !user_data ? nullptr : user_data->push_transform); } void pop_transform (void *paint_data) @@ -182,54 +187,59 @@ struct hb_paint_funcs_t 0, 0); } - HB_NODISCARD - bool push_translate (void *paint_data, + void push_transform (void *paint_data, hb_transform_t t) + { + push_transform (paint_data, t.xx, t.yx, t.xy, t.yy, t.x0, t.y0); + } + + void push_translate (void *paint_data, float dx, float dy) { - if (!dx && !dy) - return false; - push_transform (paint_data, - 1.f, 0.f, 0.f, 1.f, dx, dy); - return true; + hb_transform_t::translation (dx, dy)); } - HB_NODISCARD - bool push_scale (void *paint_data, + void push_scale (void *paint_data, float sx, float sy) { - if (sx == 1.f && sy == 1.f) - return false; - push_transform (paint_data, - sx, 0.f, 0.f, sy, 0.f, 0.f); - return true; + hb_transform_t::scaling (sx, sy)); + } + void push_scale_around_center (void *paint_data, + float sx, float sy, + float cx, float cy) + { + push_transform (paint_data, + hb_transform_t::scaling_around_center (sx, sy, cx, cy)); } - HB_NODISCARD - bool push_rotate (void *paint_data, + void push_rotate (void *paint_data, float a) { - if (!a) - return false; - - float cc = cosf (a * HB_PI); - float ss = sinf (a * HB_PI); - push_transform (paint_data, cc, ss, -ss, cc, 0.f, 0.f); - return true; + push_transform (paint_data, + hb_transform_t::rotation (a * HB_PI)); } - HB_NODISCARD - bool push_skew (void *paint_data, + void push_rotate_around_center (void *paint_data, + float a, + float cx, float cy) + { + push_transform (paint_data, + hb_transform_t::rotation_around_center (a * HB_PI, cx, cy)); + } + + void push_skew (void *paint_data, float sx, float sy) { - if (!sx && !sy) - return false; - - float x = tanf (-sx * HB_PI); - float y = tanf (+sy * HB_PI); - push_transform (paint_data, 1.f, y, x, 1.f, 0.f, 0.f); - return true; + push_transform (paint_data, + hb_transform_t::skewing (-sx * HB_PI, sy * HB_PI)); + } + void push_skew_around_center (void *paint_data, + float sx, float sy, + float cx, float cy) + { + push_transform (paint_data, + hb_transform_t::skewing_around_center (-sx * HB_PI, sy * HB_PI, cx, cy)); } }; DECLARE_NULL_INSTANCE (hb_paint_funcs_t); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-priority-queue.hh b/src/java.desktop/share/native/libharfbuzz/hb-priority-queue.hh index 274d5df4c54..753e86b8ca6 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-priority-queue.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-priority-queue.hh @@ -45,12 +45,22 @@ template struct hb_priority_queue_t { - private: + public: typedef hb_pair_t item_t; + + private: hb_vector_t heap; public: + hb_priority_queue_t () = default; + hb_priority_queue_t (hb_vector_t&& other) : heap (std::move (other)) + { + // Heapify the vector. + for (int i = (heap.length / 2) - 1; i >= 0; i--) + bubble_down (i); + } + void reset () { heap.resize (0); } bool in_error () const { return heap.in_error (); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-repacker.hh b/src/java.desktop/share/native/libharfbuzz/hb-repacker.hh index cb4fdeead2e..7d118b52169 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-repacker.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-repacker.hh @@ -217,11 +217,17 @@ bool _try_isolating_subgraphs (const hb_vector_t& over unsigned maximum_to_move = hb_max ((sorted_graph.num_roots_for_space (space) / 2u), 1u); if (roots_to_isolate.get_population () > maximum_to_move) { // Only move at most half of the roots in a space at a time. - unsigned extra = roots_to_isolate.get_population () - maximum_to_move; - while (extra--) { - uint32_t root = HB_SET_VALUE_INVALID; - roots_to_isolate.previous (&root); - roots_to_isolate.del (root); + // + // Note: this was ported from non-stable ids to stable ids. So to retain the same behaviour + // with regards to which roots are removed from the set we need to remove them in the topological + // order, not the object id order. + int extra = roots_to_isolate.get_population () - maximum_to_move; + for (unsigned id : sorted_graph.ordering_) { + if (!extra) break; + if (roots_to_isolate.has(id)) { + roots_to_isolate.del(id); + extra--; + } } } @@ -266,7 +272,7 @@ bool _resolve_shared_overflow(const hb_vector_t& overf result = sorted_graph.duplicate(&parents, r.child); } - if (result == (unsigned) -1) return result; + if (result == (unsigned) -1) return false; if (parents.get_population() > 1) { // If the duplicated node has more than one parent pre-emptively raise it's priority to the maximum. @@ -283,7 +289,7 @@ bool _resolve_shared_overflow(const hb_vector_t& overf sorted_graph.vertices_[result].give_max_priority(); } - return result; + return true; } static inline @@ -302,8 +308,11 @@ bool _process_overflows (const hb_vector_t& overflows, { // The child object is shared, we may be able to eliminate the overflow // by duplicating it. - if (!_resolve_shared_overflow(overflows, i, sorted_graph)) continue; - return true; + if (_resolve_shared_overflow(overflows, i, sorted_graph)) + return true; + + // Sometimes we can't duplicate a node which looks shared because it's not actually shared + // (eg. all links from the same parent) in this case continue on to other resolution options. } if (child.is_leaf () && !priority_bumped_parents.has (r.parent)) diff --git a/src/java.desktop/share/native/libharfbuzz/hb-sanitize.hh b/src/java.desktop/share/native/libharfbuzz/hb-sanitize.hh index 1f8ba32bae2..1e9ee9ba960 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-sanitize.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-sanitize.hh @@ -64,9 +64,6 @@ * * - Cast blob content to T*, call sanitize() method of it, * - If sanitize succeeded, return blob. - * - Otherwise, if blob is not writable, try making it writable, - * or copy if cannot be made writable in-place, - * - Call sanitize() again. Return blob if sanitize succeeded. * - Return empty blob otherwise. * * @@ -98,6 +95,12 @@ * structure is so complicated that by checking all offsets at sanitize() time, * we make the code much simpler in other methods, as offsets and referenced * objects do not need to be validated at each use site. + * + * Note: + * Sanitize was named so because it used to try to recover from errors by + * modifying the data to make it valid. This is no longer the case, as it + * could make HarfBuzz hallucinate new rules if there was aliasing in the + * data. However, the name stuck. See: https://behdad.github.io/harfbust/ */ /* This limits sanitizing time on really broken fonts. */ @@ -120,12 +123,12 @@ struct hb_sanitize_context_t : hb_dispatch_context_t { - hb_sanitize_context_t () : - start (nullptr), end (nullptr), + hb_sanitize_context_t (const char *start_ = nullptr, const char *end_ = nullptr) : + start (start_), end (end_), length (0), max_ops (0), max_subtables (0), recursion_depth (0), - writable (false), edit_count (0), + writable (false), blob (nullptr), num_glyphs (65536), num_glyphs_set (false), @@ -212,14 +215,22 @@ struct hb_sanitize_context_t : void reset_object () { - this->start = this->blob->data; - this->end = this->start + this->blob->length; + if (this->blob) + { + this->start = this->blob->data; + this->end = this->start + this->blob->length; + } this->length = this->end - this->start; assert (this->start <= this->end); /* Must not overflow. */ } - void start_processing () + void start_processing (const char *start_ = nullptr, const char *end_ = nullptr) { + if (start_) + { + this->start = start_; + this->end = end_; + } reset_object (); unsigned m; if (unlikely (hb_unsigned_mul_overflows (this->end - this->start, HB_SANITIZE_MAX_OPS_FACTOR, &m))) @@ -228,7 +239,6 @@ struct hb_sanitize_context_t : this->max_ops = hb_clamp (m, (unsigned) HB_SANITIZE_MAX_OPS_MIN, (unsigned) HB_SANITIZE_MAX_OPS_MAX); - this->edit_count = 0; this->debug_depth = 0; this->recursion_depth = 0; @@ -241,8 +251,8 @@ struct hb_sanitize_context_t : void end_processing () { DEBUG_MSG_LEVEL (SANITIZE, this->start, 0, -1, - "end [%p..%p] %u edit requests", - this->start, this->end, this->edit_count); + "end [%p..%p]", + this->start, this->end); hb_blob_destroy (this->blob); this->blob = nullptr; @@ -250,9 +260,6 @@ struct hb_sanitize_context_t : this->length = 0; } - unsigned get_edit_count () { return edit_count; } - - bool check_ops(unsigned count) { /* Avoid underflow */ @@ -396,35 +403,6 @@ struct hb_sanitize_context_t : return likely (this->check_point ((const char *) obj + obj->min_size)); } - bool may_edit (const void *base, unsigned int len) - { - if (this->edit_count >= HB_SANITIZE_MAX_EDITS) - return false; - - const char *p = (const char *) base; - this->edit_count++; - - DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0, - "may_edit(%u) [%p..%p] (%u bytes) in [%p..%p] -> %s", - this->edit_count, - p, p + len, len, - this->start, this->end, - this->writable ? "GRANTED" : "DENIED"); - - return this->writable; - } - - template - bool try_set (const Type *obj, const ValueType &v) - { - if (this->may_edit (obj, hb_static_size (Type))) - { - * const_cast (obj) = v; - return true; - } - return false; - } - template hb_blob_t *sanitize_blob (hb_blob_t *blob) { @@ -432,7 +410,6 @@ struct hb_sanitize_context_t : init (blob); - retry: DEBUG_MSG_FUNC (SANITIZE, start, "start"); start_processing (); @@ -446,36 +423,6 @@ struct hb_sanitize_context_t : Type *t = reinterpret_cast (const_cast (start)); sane = t->sanitize (this); - if (sane) - { - if (edit_count) - { - DEBUG_MSG_FUNC (SANITIZE, start, "passed first round with %u edits; going for second round", edit_count); - - /* sanitize again to ensure no toe-stepping */ - edit_count = 0; - sane = t->sanitize (this); - if (edit_count) { - DEBUG_MSG_FUNC (SANITIZE, start, "requested %u edits in second round; FAILING", edit_count); - sane = false; - } - } - } - else - { - if (edit_count && !writable) { - start = hb_blob_get_data_writable (blob, nullptr); - end = start + blob->length; - - if (start) - { - writable = true; - /* ok, we made it writable by relocating. try again */ - DEBUG_MSG_FUNC (SANITIZE, start, "retry"); - goto retry; - } - } - } end_processing (); @@ -506,7 +453,6 @@ struct hb_sanitize_context_t : private: int recursion_depth; bool writable; - unsigned int edit_count; hb_blob_t *blob; unsigned int num_glyphs; bool num_glyphs_set; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-script-list.h b/src/java.desktop/share/native/libharfbuzz/hb-script-list.h index f811dbc3408..16347b9d84e 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-script-list.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-script-list.h @@ -223,6 +223,10 @@ HB_END_DECLS * @HB_SCRIPT_SUNUWAR: `Sunu`, Since: 10.0.0 * @HB_SCRIPT_TODHRI: `Todr`, Since: 10.0.0 * @HB_SCRIPT_TULU_TIGALARI: `Tutg`, Since: 10.0.0 + * @HB_SCRIPT_BERIA_ERFE: `Berf`, Since: 11.5.0 + * @HB_SCRIPT_SIDETIC: `Sidt`, Since: 11.5.0 + * @HB_SCRIPT_TAI_YO: `Tayo`, Since: 11.5.0 + * @HB_SCRIPT_TOLONG_SIKI: `Tols`, Since: 11.5.0 * @HB_SCRIPT_INVALID: No script set * * Data type for scripts. Each #hb_script_t's value is an #hb_tag_t corresponding @@ -461,6 +465,14 @@ typedef enum HB_SCRIPT_TODHRI = HB_TAG ('T','o','d','r'), /*16.0*/ HB_SCRIPT_TULU_TIGALARI = HB_TAG ('T','u','t','g'), /*16.0*/ + /* + * Since 11.5.0 + */ + HB_SCRIPT_BERIA_ERFE = HB_TAG ('B','e','r','f'), /*17.0*/ + HB_SCRIPT_SIDETIC = HB_TAG ('S','i','d','t'), /*17.0*/ + HB_SCRIPT_TAI_YO = HB_TAG ('T','a','y','o'), /*17.0*/ + HB_SCRIPT_TOLONG_SIKI = HB_TAG ('T','o','l','s'), /*17.0*/ + /* No script set. */ HB_SCRIPT_INVALID = HB_TAG_NONE, diff --git a/src/java.desktop/share/native/libharfbuzz/hb-serialize.hh b/src/java.desktop/share/native/libharfbuzz/hb-serialize.hh index 704d0ffd12b..9fe99c85ea7 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-serialize.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-serialize.hh @@ -34,7 +34,7 @@ #include "hb.hh" #include "hb-blob.hh" #include "hb-map.hh" -#include "hb-pool.hh" +#include "hb-free-pool.hh" #include "hb-subset-serialize.h" @@ -724,7 +724,7 @@ struct hb_serialize_context_t hb_requires (hb_is_iterator (Iterator)), typename ...Ts> void copy_all (Iterator it, Ts&&... ds) - { for (decltype (*it) _ : it) copy (_, std::forward (ds)...); } + { for (decltype (*it) _ : it) copy (_, ds...); } template hb_serialize_context_t& operator << (const Type &obj) & { embed (obj); return *this; } @@ -794,7 +794,8 @@ struct hb_serialize_context_t template void assign_offset (const object_t* parent, const object_t::link_t &link, unsigned offset) { - auto &off = * ((BEInt *) (parent->head + link.position)); + // XXX We should stop assuming big-endian! + auto &off = * ((HBInt *) (parent->head + link.position)); assert (0 == off); check_assign (off, offset, HB_SERIALIZE_ERROR_OFFSET_OVERFLOW); } @@ -814,7 +815,7 @@ struct hb_serialize_context_t } /* Object memory pool. */ - hb_pool_t object_pool; + hb_free_pool_t object_pool; /* Stack of currently under construction objects. */ object_t *current; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-set-digest.hh b/src/java.desktop/share/native/libharfbuzz/hb-set-digest.hh index f0416d5fa1d..f8cb0998260 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-set-digest.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-set-digest.hh @@ -55,11 +55,11 @@ * - For each glyph, if it doesn't match the subtable digest, * skip it. * - * The main filter we use is a combination of four bits-pattern + * The filter we use is a combination of three bits-pattern * filters. A bits-pattern filter checks a number of bits (5 or 6) - * of the input number (glyph-id in this case) and checks whether + * of the input number (glyph-id in most cases) and checks whether * its pattern is amongst the patterns of any of the accepted values. - * The accepted patterns are represented as a "long" integer. The + * The accepted patterns are represented as a "long" integer. Each * check is done using four bitwise operations only. */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-shape.cc b/src/java.desktop/share/native/libharfbuzz/hb-shape.cc index d14f577be00..a36fa14fb28 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-shape.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-shape.cc @@ -149,14 +149,11 @@ hb_shape_full (hb_font_t *font, hb_bool_t res = hb_shape_plan_execute (shape_plan, font, buffer, features, num_features); - if (buffer->max_ops <= 0) - buffer->shaping_failed = true; - hb_shape_plan_destroy (shape_plan); if (text_buffer) { - if (res && buffer->successful && !buffer->shaping_failed + if (res && buffer->successful && text_buffer->successful && !buffer->verify (text_buffer, font, @@ -199,6 +196,7 @@ hb_shape (hb_font_t *font, #ifdef HB_EXPERIMENTAL_API +#ifndef HB_NO_VAR static float buffer_advance (hb_buffer_t *buffer) @@ -440,7 +438,7 @@ hb_shape_justify (hb_font_t *font, return true; } - +#endif #endif diff --git a/src/java.desktop/share/native/libharfbuzz/hb-shaper-list.hh b/src/java.desktop/share/native/libharfbuzz/hb-shaper-list.hh index f079caf4d35..cb386f26827 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-shaper-list.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-shaper-list.hh @@ -57,6 +57,14 @@ HB_SHAPER_IMPLEMENT (directwrite) HB_SHAPER_IMPLEMENT (coretext) #endif +#ifdef HAVE_HARFRUST +HB_SHAPER_IMPLEMENT (harfrust) +#endif + +#ifdef HAVE_KBTS +HB_SHAPER_IMPLEMENT (kbts) +#endif + #ifndef HB_NO_FALLBACK_SHAPE HB_SHAPER_IMPLEMENT (fallback) /* <--- This should be last. */ #endif diff --git a/src/java.desktop/share/native/libharfbuzz/hb-static.cc b/src/java.desktop/share/native/libharfbuzz/hb-static.cc index 4e70e413651..06cc80b5f38 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-static.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-static.cc @@ -113,27 +113,4 @@ hb_face_t::load_upem () const return ret; } - -#ifndef HB_NO_VAR -bool -_glyf_get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical, - int *lsb) -{ - return font->face->table.glyf->get_leading_bearing_with_var_unscaled (font, glyph, is_vertical, lsb); -} - -unsigned -_glyf_get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical) -{ - return font->face->table.glyf->get_advance_with_var_unscaled (font, glyph, is_vertical); -} -#endif - -bool -_glyf_get_leading_bearing_without_var_unscaled (hb_face_t *face, hb_codepoint_t gid, bool is_vertical, int *lsb) -{ - return face->table.glyf->get_leading_bearing_without_var_unscaled (gid, is_vertical, lsb); -} - - #endif diff --git a/src/java.desktop/share/native/libharfbuzz/hb-string-array.hh b/src/java.desktop/share/native/libharfbuzz/hb-string-array.hh index 9d00cae6c32..51413b6da44 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-string-array.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-string-array.hh @@ -45,25 +45,25 @@ static const union HB_STRING_ARRAY_TYPE_NAME { * but C++ does not allow that. * https://stackoverflow.com/q/28433862 */ -#define _S(s) char HB_PASTE (str, __LINE__)[sizeof (s)]; +#define HB_STR(s) char HB_PASTE (str, __LINE__)[sizeof (s)]; #include HB_STRING_ARRAY_LIST -#undef _S +#undef HB_STR } st; char str[HB_VAR_ARRAY]; } HB_STRING_ARRAY_POOL_NAME = { { -#define _S(s) s, +#define HB_STR(s) s, #include HB_STRING_ARRAY_LIST -#undef _S +#undef HB_STR } }; static const unsigned int HB_STRING_ARRAY_OFFS_NAME[] = { -#define _S(s) offsetof (union HB_STRING_ARRAY_TYPE_NAME, st.HB_PASTE(str, __LINE__)), +#define HB_STR(s) offsetof (union HB_STRING_ARRAY_TYPE_NAME, st.HB_PASTE(str, __LINE__)), #include HB_STRING_ARRAY_LIST -#undef _S +#undef HB_STR sizeof (HB_STRING_ARRAY_TYPE_NAME) }; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.hh index e7bddaef723..843ad69f2f9 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.hh @@ -861,8 +861,7 @@ struct subr_subsetter_t { // Hack to point vector to static string. auto &b = buffArray.arrayZ[last]; - b.length = 1; - b.arrayZ = const_cast(endchar_str); + b.set_storage (const_cast(endchar_str), 1); } last++; // Skip over gid @@ -877,8 +876,7 @@ struct subr_subsetter_t { // Hack to point vector to static string. auto &b = buffArray.arrayZ[last]; - b.length = 1; - b.arrayZ = const_cast(endchar_str); + b.set_storage (const_cast(endchar_str), 1); } return true; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-iup.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-iup.hh index 01987bd258d..8ee02c07dbe 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-iup.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-iup.hh @@ -26,12 +26,27 @@ #define HB_SUBSET_INSTANCER_IUP_HH #include "hb-subset-plan.hh" + +struct iup_scratch_t +{ + hb_vector_t end_points; + hb_vector_t interp_x_deltas; + hb_vector_t interp_y_deltas; + hb_vector_t costs; + hb_vector_t chain; + hb_vector_t rot_indices; + hb_vector_t rot_x_deltas; + hb_vector_t rot_y_deltas; + contour_point_vector_t rot_points; +}; + /* given contour points and deltas, optimize a set of referenced points within error * tolerance. Returns optimized referenced point indices */ HB_INTERNAL bool iup_delta_optimize (const contour_point_vector_t& contour_points, const hb_vector_t& x_deltas, const hb_vector_t& y_deltas, hb_vector_t& opt_indices, /* OUT */ + iup_scratch_t &scratch, double tolerance = 0.0); #endif /* HB_SUBSET_INSTANCER_IUP_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.cc b/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.cc index c67fee421c2..15227bdab48 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.cc @@ -62,9 +62,10 @@ static inline double supportScalar (double coord, const Triple &tent) return (end - coord) / (end - peak); } -static inline rebase_tent_result_t -_solve (Triple tent, Triple axisLimit, bool negative = false) +static inline void +_solve (Triple tent, Triple axisLimit, rebase_tent_result_t &out, bool negative = false) { + out.reset(); double axisMin = axisLimit.minimum; double axisDef = axisLimit.middle; double axisMax = axisLimit.maximum; @@ -75,14 +76,12 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) // Mirror the problem such that axisDef <= peak if (axisDef > peak) { - rebase_tent_result_t vec = _solve (_reverse_negate (tent), - _reverse_negate (axisLimit), - !negative); + _solve (_reverse_negate (tent), _reverse_negate (axisLimit), out, !negative); - for (auto &p : vec) + for (auto &p : out) p = hb_pair (p.first, _reverse_negate (p.second)); - return vec; + return; } // axisDef <= peak @@ -98,7 +97,7 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) * axisMin axisDef axisMax lower upper */ if (axisMax <= lower && axisMax < peak) - return rebase_tent_result_t{}; // No overlap + return; // No overlap /* case 2: Only the peak and outermost bound fall outside the new limit; * we keep the deltaset, update peak and outermost bound and scale deltas @@ -133,18 +132,18 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) double mult = supportScalar (axisMax, tent); tent = Triple{lower, axisMax, axisMax}; - rebase_tent_result_t vec = _solve (tent, axisLimit); + _solve (tent, axisLimit, out); - for (auto &p : vec) + for (auto &p : out) p = hb_pair (p.first * mult, p.second); - return vec; + return; } // lower <= axisDef <= peak <= axisMax double gain = supportScalar (axisDef, tent); - rebase_tent_result_t out {hb_pair (gain, Triple{})}; + out.push(hb_pair (gain, Triple{})); // First, the positive side @@ -362,8 +361,6 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) out.push (hb_pair (scalar1 - gain, loc1)); out.push (hb_pair (scalar2 - gain, loc2)); } - - return out; } static inline TripleDistances _reverse_triple_distances (const TripleDistances &v) @@ -405,18 +402,21 @@ double renormalizeValue (double v, const Triple &triple, return (-v_distance) /total_distance; } -rebase_tent_result_t -rebase_tent (Triple tent, Triple axisLimit, TripleDistances axis_triple_distances) +void +rebase_tent (Triple tent, Triple axisLimit, TripleDistances axis_triple_distances, + rebase_tent_result_t &out, + rebase_tent_result_t &scratch) { assert (-1.0 <= axisLimit.minimum && axisLimit.minimum <= axisLimit.middle && axisLimit.middle <= axisLimit.maximum && axisLimit.maximum <= +1.0); assert (-2.0 <= tent.minimum && tent.minimum <= tent.middle && tent.middle <= tent.maximum && tent.maximum <= +2.0); assert (tent.middle != 0.0); - rebase_tent_result_t sols = _solve (tent, axisLimit); + rebase_tent_result_t &sols = scratch; + _solve (tent, axisLimit, sols); auto n = [&axisLimit, &axis_triple_distances] (double v) { return renormalizeValue (v, axisLimit, axis_triple_distances); }; - rebase_tent_result_t out; + out.reset(); for (auto &p : sols) { if (!p.first) continue; @@ -429,6 +429,4 @@ rebase_tent (Triple tent, Triple axisLimit, TripleDistances axis_triple_distance out.push (hb_pair (p.first, Triple{n (t.minimum), n (t.middle), n (t.maximum)})); } - - return out; } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.hh index 9764dcc1725..574d58d53d8 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.hh @@ -42,10 +42,9 @@ struct TripleDistances double positive; }; -struct Triple { - - Triple () : - minimum (0.0), middle (0.0), maximum (0.0) {} +struct Triple +{ + Triple () = default; Triple (double minimum_, double middle_, double maximum_) : minimum (minimum_), middle (middle_), maximum (maximum_) {} @@ -81,10 +80,9 @@ struct Triple { return current; } - - double minimum; - double middle; - double maximum; + double minimum = 0; + double middle = 0; + double maximum = 0; }; using rebase_tent_result_item_t = hb_pair_t; @@ -107,8 +105,10 @@ HB_INTERNAL double renormalizeValue (double v, const Triple &triple, * If tent value is Triple{}, that is a special deltaset that should * be always-enabled (called "gain"). */ -HB_INTERNAL rebase_tent_result_t rebase_tent (Triple tent, - Triple axisLimit, - TripleDistances axis_triple_distances); +HB_INTERNAL void rebase_tent (Triple tent, + Triple axisLimit, + TripleDistances axis_triple_distances, + rebase_tent_result_t &out, + rebase_tent_result_t &scratch); #endif /* HB_SUBSET_INSTANCER_SOLVER_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan-member-list.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan-member-list.hh index ade8278c40f..398fe81eca9 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan-member-list.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan-member-list.hh @@ -81,6 +81,10 @@ HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(>), gpo HB_SUBSET_PLAN_MEMBER (hb_map_t, gsub_features) HB_SUBSET_PLAN_MEMBER (hb_map_t, gpos_features) +//active features(with duplicates) old index -> new index mapping +HB_SUBSET_PLAN_MEMBER (hb_map_t, gsub_features_w_duplicates) +HB_SUBSET_PLAN_MEMBER (hb_map_t, gpos_features_w_duplicates) + //active feature variation records/condition index with variations HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(>), gsub_feature_record_cond_idx_map) HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(>), gpos_feature_record_cond_idx_map) diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc index 3ba726d925e..8c3fd97899b 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc @@ -418,7 +418,8 @@ _nameid_closure (hb_subset_plan_t* plan, hb_set_t* drop_tables) { #ifndef HB_NO_STYLE - plan->source->table.STAT->collect_name_ids (&plan->user_axes_location, &plan->name_ids); + if (!drop_tables->has (HB_OT_TAG_STAT)) + plan->source->table.STAT->collect_name_ids (&plan->user_axes_location, &plan->name_ids); #endif #ifndef HB_NO_VAR if (!plan->all_axes_pinned) @@ -676,7 +677,8 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, return; #ifndef HB_NO_VAR - normalize_axes_location (face, this); + if (!check_success (normalize_axes_location (face, this))) + return; #endif _populate_unicodes_to_retain (input->sets.unicodes, input->sets.glyphs, this); @@ -697,6 +699,15 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, return; } +#ifdef HB_EXPERIMENTAL_API + if ((input->flags & HB_SUBSET_FLAGS_RETAIN_GIDS) && + (input->flags & HB_SUBSET_FLAGS_RETAIN_NUM_GLYPHS)) { + // We've been requested to maintain the num glyphs count from the + // input face. + _num_output_glyphs = source->get_num_glyphs (); + } +#endif + _create_glyph_map_gsub ( &_glyphset_gsub, glyph_map, @@ -710,10 +721,10 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, glyph_map->get(unicode_to_new_gid_list.arrayZ[i].second); } - bounds_width_vec.resize (_num_output_glyphs, false); + bounds_width_vec.resize_dirty (_num_output_glyphs); for (auto &v : bounds_width_vec) v = 0xFFFFFFFF; - bounds_height_vec.resize (_num_output_glyphs, false); + bounds_height_vec.resize_dirty (_num_output_glyphs); for (auto &v : bounds_height_vec) v = 0xFFFFFFFF; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh index 8a6574365ed..0362ed7292e 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh @@ -300,6 +300,7 @@ struct hb_subset_plan_t // compile times more reasonable: // - hb-subset-plan.cc // - hb-subset-plan-layout.cc +// - hb-subset-plan-var.cc // // The functions below are those needed to connect the split files // above together. @@ -332,7 +333,7 @@ generate_varstore_inner_maps (const hb_set_t& varidx_set, unsigned subtable_count, hb_vector_t &inner_maps /* OUT */); -HB_INTERNAL void +HB_INTERNAL bool normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan); HB_INTERNAL void diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset.cc b/src/java.desktop/share/native/libharfbuzz/hb-subset.cc index 079c94eddfe..51134ed09ce 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset.cc @@ -25,65 +25,19 @@ */ #include "hb.hh" + #include "hb-open-type.hh" +#include "hb-open-file.hh" #include "hb-subset.hh" - -#include "hb-open-file.hh" -#include "hb-ot-cmap-table.hh" -#include "hb-ot-glyf-table.hh" -#include "hb-ot-hdmx-table.hh" -#include "hb-ot-head-table.hh" -#include "hb-ot-hhea-table.hh" -#include "hb-ot-hmtx-table.hh" -#include "hb-ot-maxp-table.hh" -#include "OT/Color/CBDT/CBDT.hh" -#include "OT/Color/COLR/COLR.hh" -#include "OT/Color/CPAL/CPAL.hh" -#include "OT/Color/sbix/sbix.hh" -#include "hb-ot-os2-table.hh" -#include "hb-ot-post-table.hh" -#include "hb-ot-post-table-v2subset.hh" -#include "hb-ot-cff1-table.hh" -#include "hb-ot-cff2-table.hh" -#include "hb-ot-vorg-table.hh" -#include "hb-ot-name-table.hh" -#include "hb-ot-layout-base-table.hh" -#include "hb-ot-layout-gsub-table.hh" -#include "hb-ot-layout-gpos-table.hh" -#include "hb-ot-var-avar-table.hh" -#include "hb-ot-var-cvar-table.hh" -#include "hb-ot-var-fvar-table.hh" -#include "hb-ot-var-gvar-table.hh" -#include "hb-ot-var-hvar-table.hh" -#include "hb-ot-var-mvar-table.hh" -#include "hb-ot-math-table.hh" -#include "hb-ot-stat-table.hh" -#include "hb-repacker.hh" +#include "hb-subset-table.hh" #include "hb-subset-accelerator.hh" -using OT::Layout::GSUB; -using OT::Layout::GPOS; - - -#ifndef HB_NO_SUBSET_CFF -template<> -struct hb_subset_plan_t::source_table_loader -{ - auto operator () (hb_subset_plan_t *plan) - HB_AUTO_RETURN (plan->accelerator ? plan->accelerator->cff1_accel : - plan->inprogress_accelerator ? plan->inprogress_accelerator->cff1_accel : - plan->cff1_accel) -}; -template<> -struct hb_subset_plan_t::source_table_loader -{ - auto operator () (hb_subset_plan_t *plan) - HB_AUTO_RETURN (plan->accelerator ? plan->accelerator->cff2_accel : - plan->inprogress_accelerator ? plan->inprogress_accelerator->cff2_accel : - plan->cff2_accel) -}; -#endif +#include "hb-ot-cmap-table.hh" +#include "hb-ot-var-cvar-table.hh" +#include "hb-ot-head-table.hh" +#include "hb-ot-stat-table.hh" +#include "hb-ot-post-table-v2subset.hh" /** @@ -116,56 +70,56 @@ hb_user_data_key_t _hb_subset_accelerator_user_data_key = {}; * if we are unable to list the tables in a face. */ static hb_tag_t known_tables[] { - HB_TAG ('a', 'v', 'a', 'r'), - HB_OT_TAG_BASE, - HB_OT_TAG_CBDT, - HB_OT_TAG_CBLC, - HB_OT_TAG_CFF1, - HB_OT_TAG_CFF2, - HB_OT_TAG_cmap, - HB_OT_TAG_COLR, - HB_OT_TAG_CPAL, - HB_TAG ('c', 'v', 'a', 'r'), - HB_TAG ('c', 'v', 't', ' '), - HB_TAG ('D', 'S', 'I', 'G'), - HB_TAG ('E', 'B', 'D', 'T'), - HB_TAG ('E', 'B', 'L', 'C'), - HB_TAG ('E', 'B', 'S', 'C'), - HB_TAG ('f', 'p', 'g', 'm'), - HB_TAG ('f', 'v', 'a', 'r'), - HB_TAG ('g', 'a', 's', 'p'), - HB_OT_TAG_GDEF, - HB_OT_TAG_glyf, - HB_OT_TAG_GPOS, - HB_OT_TAG_GSUB, - HB_OT_TAG_gvar, - HB_OT_TAG_hdmx, - HB_OT_TAG_head, - HB_OT_TAG_hhea, - HB_OT_TAG_hmtx, - HB_OT_TAG_HVAR, - HB_OT_TAG_JSTF, - HB_TAG ('k', 'e', 'r', 'n'), - HB_OT_TAG_loca, - HB_TAG ('L', 'T', 'S', 'H'), - HB_OT_TAG_MATH, - HB_OT_TAG_maxp, - HB_TAG ('M', 'E', 'R', 'G'), - HB_TAG ('m', 'e', 't', 'a'), - HB_TAG ('M', 'V', 'A', 'R'), - HB_TAG ('P', 'C', 'L', 'T'), - HB_OT_TAG_post, - HB_TAG ('p', 'r', 'e', 'p'), - HB_OT_TAG_sbix, - HB_TAG ('S', 'T', 'A', 'T'), - HB_TAG ('S', 'V', 'G', ' '), - HB_TAG ('V', 'D', 'M', 'X'), - HB_OT_TAG_vhea, - HB_OT_TAG_vmtx, - HB_OT_TAG_VORG, - HB_OT_TAG_VVAR, - HB_OT_TAG_name, - HB_OT_TAG_OS2 + HB_TAG('a','v','a','r'), + HB_TAG('B','A','S','E'), + HB_TAG('C','B','D','T'), + HB_TAG('C','B','L','C'), + HB_TAG('C','F','F',' '), + HB_TAG('C','F','F','2'), + HB_TAG('c','m','a','p'), + HB_TAG('C','O','L','R'), + HB_TAG('C','P','A','L'), + HB_TAG('c','v','a','r'), + HB_TAG('c','v','t',' '), + HB_TAG('D','S','I','G'), + HB_TAG('E','B','D','T'), + HB_TAG('E','B','L','C'), + HB_TAG('E','B','S','C'), + HB_TAG('f','p','g','m'), + HB_TAG('f','v','a','r'), + HB_TAG('g','a','s','p'), + HB_TAG('G','D','E','F'), + HB_TAG('g','l','y','f'), + HB_TAG('G','P','O','S'), + HB_TAG('G','S','U','B'), + HB_TAG('g','v','a','r'), + HB_TAG('h','d','m','x'), + HB_TAG('h','e','a','d'), + HB_TAG('h','h','e','a'), + HB_TAG('h','m','t','x'), + HB_TAG('H','V','A','R'), + HB_TAG('J','S','T','F'), + HB_TAG('k','e','r','n'), + HB_TAG('l','o','c','a'), + HB_TAG('L','T','S','H'), + HB_TAG('M','A','T','H'), + HB_TAG('m','a','x','p'), + HB_TAG('M','E','R','G'), + HB_TAG('m','e','t','a'), + HB_TAG('M','V','A','R'), + HB_TAG('P','C','L','T'), + HB_TAG('p','o','s','t'), + HB_TAG('p','r','e','p'), + HB_TAG('s','b','i','x'), + HB_TAG('S','T','A','T'), + HB_TAG('S','V','G',' '), + HB_TAG('V','D','M','X'), + HB_TAG('v','h','e','a'), + HB_TAG('v','m','t','x'), + HB_TAG('V','O','R','G'), + HB_TAG('V','V','A','R'), + HB_TAG('n','a','m','e'), + HB_TAG('O','S','/','2') }; static bool _table_is_empty (const hb_face_t *face, hb_tag_t tag) @@ -213,169 +167,6 @@ _get_table_tags (const hb_subset_plan_t* plan, } -static unsigned -_plan_estimate_subset_table_size (hb_subset_plan_t *plan, - unsigned table_len, - hb_tag_t table_tag) -{ - unsigned src_glyphs = plan->source->get_num_glyphs (); - unsigned dst_glyphs = plan->glyphset ()->get_population (); - - unsigned bulk = 8192; - /* Tables that we want to allocate same space as the source table. For GSUB/GPOS it's - * because those are expensive to subset, so giving them more room is fine. */ - bool same_size = table_tag == HB_OT_TAG_GSUB || - table_tag == HB_OT_TAG_GPOS || - table_tag == HB_OT_TAG_name; - - if (plan->flags & HB_SUBSET_FLAGS_RETAIN_GIDS) - { - if (table_tag == HB_OT_TAG_CFF1) - { - /* Add some extra room for the CFF charset. */ - bulk += src_glyphs * 16; - } - else if (table_tag == HB_OT_TAG_CFF2) - { - /* Just extra CharString offsets. */ - bulk += src_glyphs * 4; - } - } - - if (unlikely (!src_glyphs) || same_size) - return bulk + table_len; - - return bulk + (unsigned) (table_len * sqrt ((double) dst_glyphs / src_glyphs)); -} - -/* - * Repack the serialization buffer if any offset overflows exist. - */ -static hb_blob_t* -_repack (hb_tag_t tag, const hb_serialize_context_t& c) -{ - if (!c.offset_overflow ()) - return c.copy_blob (); - - hb_blob_t* result = hb_resolve_overflows (c.object_graph (), tag); - - if (unlikely (!result)) - { - DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c offset overflow resolution failed.", - HB_UNTAG (tag)); - return nullptr; - } - - return result; -} - -template -static -bool -_try_subset (const TableType *table, - hb_vector_t* buf, - hb_subset_context_t* c /* OUT */) -{ - c->serializer->start_serialize (); - if (c->serializer->in_error ()) return false; - - bool needed = table->subset (c); - if (!c->serializer->ran_out_of_room ()) - { - c->serializer->end_serialize (); - return needed; - } - - unsigned buf_size = buf->allocated; - buf_size = buf_size * 2 + 16; - - - - - DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.", - HB_UNTAG (c->table_tag), buf_size); - - if (unlikely (buf_size > c->source_blob->length * 256 || - !buf->alloc_exact (buf_size))) - { - DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.", - HB_UNTAG (c->table_tag), buf_size); - return needed; - } - - c->serializer->reset (buf->arrayZ, buf->allocated); - return _try_subset (table, buf, c); -} - -template -static auto _do_destroy (T &t, hb_priority<1>) HB_RETURN (void, t.destroy ()) - -template -static void _do_destroy (T &t, hb_priority<0>) {} - -template -static bool -_subset (hb_subset_plan_t *plan, hb_vector_t &buf) -{ - auto &&source_blob = plan->source_table (); - auto *table = source_blob.get (); - - hb_tag_t tag = TableType::tableTag; - hb_blob_t *blob = source_blob.get_blob(); - if (unlikely (!blob || !blob->data)) - { - DEBUG_MSG (SUBSET, nullptr, - "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag)); - _do_destroy (source_blob, hb_prioritize); - return false; - } - - unsigned buf_size = _plan_estimate_subset_table_size (plan, blob->length, TableType::tableTag); - DEBUG_MSG (SUBSET, nullptr, - "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG (tag), buf_size); - if (unlikely (!buf.alloc (buf_size))) - { - DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG (tag), buf_size); - _do_destroy (source_blob, hb_prioritize); - return false; - } - - bool needed = false; - hb_serialize_context_t serializer (buf.arrayZ, buf.allocated); - { - hb_subset_context_t c (blob, plan, &serializer, tag); - needed = _try_subset (table, &buf, &c); - } - _do_destroy (source_blob, hb_prioritize); - - if (serializer.in_error () && !serializer.only_offset_overflow ()) - { - DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset FAILED!", HB_UNTAG (tag)); - return false; - } - - if (!needed) - { - DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG (tag)); - return true; - } - - bool result = false; - hb_blob_t *dest_blob = _repack (tag, serializer); - if (dest_blob) - { - DEBUG_MSG (SUBSET, nullptr, - "OT::%c%c%c%c final subset table size: %u bytes.", - HB_UNTAG (tag), dest_blob->length); - result = plan->add_table (tag, dest_blob); - hb_blob_destroy (dest_blob); - } - - DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset %s", - HB_UNTAG (tag), result ? "success" : "FAILED!"); - return result; -} - static bool _is_table_present (hb_face_t *source, hb_tag_t tag) { @@ -407,34 +198,34 @@ _should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag) switch (tag) { - case HB_TAG ('c','v','a','r'): /* hint table, fallthrough */ + case HB_TAG('c','v','a','r'): /* hint table, fallthrough */ return plan->all_axes_pinned || (plan->flags & HB_SUBSET_FLAGS_NO_HINTING); - case HB_TAG ('c','v','t',' '): /* hint table, fallthrough */ - case HB_TAG ('f','p','g','m'): /* hint table, fallthrough */ - case HB_TAG ('p','r','e','p'): /* hint table, fallthrough */ - case HB_TAG ('h','d','m','x'): /* hint table, fallthrough */ - case HB_TAG ('V','D','M','X'): /* hint table, fallthrough */ + case HB_TAG('c','v','t',' '): /* hint table, fallthrough */ + case HB_TAG('f','p','g','m'): /* hint table, fallthrough */ + case HB_TAG('p','r','e','p'): /* hint table, fallthrough */ + case HB_TAG('h','d','m','x'): /* hint table, fallthrough */ + case HB_TAG('V','D','M','X'): /* hint table, fallthrough */ return plan->flags & HB_SUBSET_FLAGS_NO_HINTING; #ifdef HB_NO_SUBSET_LAYOUT // Drop Layout Tables if requested. - case HB_OT_TAG_GDEF: - case HB_OT_TAG_GPOS: - case HB_OT_TAG_GSUB: - case HB_TAG ('m','o','r','x'): - case HB_TAG ('m','o','r','t'): - case HB_TAG ('k','e','r','x'): - case HB_TAG ('k','e','r','n'): + case HB_TAG('G','D','E','F'): + case HB_TAG('G','P','O','S'): + case HB_TAG('G','S','U','B'): + case HB_TAG('m','o','r','x'): + case HB_TAG('m','o','r','t'): + case HB_TAG('k','e','r','x'): + case HB_TAG('k','e','r','n'): return true; #endif - case HB_TAG ('a','v','a','r'): - case HB_TAG ('f','v','a','r'): - case HB_TAG ('g','v','a','r'): - case HB_OT_TAG_HVAR: - case HB_OT_TAG_VVAR: - case HB_TAG ('M','V','A','R'): + case HB_TAG('a','v','a','r'): + case HB_TAG('f','v','a','r'): + case HB_TAG('g','v','a','r'): + case HB_TAG('H','V','A','R'): + case HB_TAG('V','V','A','R'): + case HB_TAG('M','V','A','R'): return plan->all_axes_pinned; default: @@ -442,15 +233,6 @@ _should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag) } } -static bool -_passthrough (hb_subset_plan_t *plan, hb_tag_t tag) -{ - hb_blob_t *source_table = hb_face_reference_table (plan->source, tag); - bool result = plan->add_table (tag, source_table); - hb_blob_destroy (source_table); - return result; -} - static bool _dependencies_satisfied (hb_subset_plan_t *plan, hb_tag_t tag, const hb_set_t &subsetted_tags, @@ -458,13 +240,13 @@ _dependencies_satisfied (hb_subset_plan_t *plan, hb_tag_t tag, { switch (tag) { - case HB_OT_TAG_hmtx: - case HB_OT_TAG_vmtx: - case HB_OT_TAG_maxp: - case HB_OT_TAG_OS2: - return !plan->normalized_coords || !pending_subset_tags.has (HB_OT_TAG_glyf); - case HB_OT_TAG_GPOS: - return plan->all_axes_pinned || !pending_subset_tags.has (HB_OT_TAG_GDEF); + case HB_TAG('h','m','t','x'): + case HB_TAG('v','m','t','x'): + case HB_TAG('m','a','x','p'): + case HB_TAG('O','S','/','2'): + return !plan->normalized_coords || !pending_subset_tags.has (HB_TAG('g','l','y','f')); + case HB_TAG('G','P','O','S'): + return plan->all_axes_pinned || !pending_subset_tags.has (HB_TAG('G','D','E','F')); default: return true; } @@ -476,88 +258,48 @@ _subset_table (hb_subset_plan_t *plan, hb_tag_t tag) { if (plan->no_subset_tables.has (tag)) { - return _passthrough (plan, tag); + return _hb_subset_table_passthrough (plan, tag); } DEBUG_MSG (SUBSET, nullptr, "subset %c%c%c%c", HB_UNTAG (tag)); + + bool success; + if (_hb_subset_table_layout (plan, buf, tag, &success) || + _hb_subset_table_var (plan, buf, tag, &success) || + _hb_subset_table_cff (plan, buf, tag, &success) || + _hb_subset_table_color (plan, buf, tag, &success) || + _hb_subset_table_other (plan, buf, tag, &success)) + return success; + + switch (tag) { - case HB_OT_TAG_glyf: return _subset (plan, buf); - case HB_OT_TAG_hdmx: return _subset (plan, buf); - case HB_OT_TAG_name: return _subset (plan, buf); - case HB_OT_TAG_head: - if (_is_table_present (plan->source, HB_OT_TAG_glyf) && !_should_drop_table (plan, HB_OT_TAG_glyf)) + case HB_TAG('h','e','a','d'): + if (_is_table_present (plan->source, HB_TAG('g','l','y','f')) && !_should_drop_table (plan, HB_TAG('g','l','y','f'))) return true; /* skip head, handled by glyf */ - return _subset (plan, buf); - case HB_OT_TAG_hhea: return true; /* skip hhea, handled by hmtx */ - case HB_OT_TAG_hmtx: return _subset (plan, buf); - case HB_OT_TAG_vhea: return true; /* skip vhea, handled by vmtx */ - case HB_OT_TAG_vmtx: return _subset (plan, buf); - case HB_OT_TAG_maxp: return _subset (plan, buf); - case HB_OT_TAG_sbix: return _subset (plan, buf); - case HB_OT_TAG_loca: return true; /* skip loca, handled by glyf */ - case HB_OT_TAG_cmap: return _subset (plan, buf); - case HB_OT_TAG_OS2 : return _subset (plan, buf); - case HB_OT_TAG_post: return _subset (plan, buf); - case HB_OT_TAG_COLR: return _subset (plan, buf); - case HB_OT_TAG_CPAL: return _subset (plan, buf); - case HB_OT_TAG_CBLC: return _subset (plan, buf); - case HB_OT_TAG_CBDT: return true; /* skip CBDT, handled by CBLC */ - case HB_OT_TAG_MATH: return _subset (plan, buf); - case HB_OT_TAG_BASE: return _subset (plan, buf); + return _hb_subset_table (plan, buf); -#ifndef HB_NO_SUBSET_CFF - case HB_OT_TAG_CFF1: return _subset (plan, buf); - case HB_OT_TAG_CFF2: return _subset (plan, buf); - case HB_OT_TAG_VORG: return _subset (plan, buf); -#endif - -#ifndef HB_NO_SUBSET_LAYOUT - case HB_OT_TAG_GDEF: return _subset (plan, buf); - case HB_OT_TAG_GSUB: return _subset (plan, buf); - case HB_OT_TAG_GPOS: return _subset (plan, buf); - case HB_OT_TAG_gvar: return _subset (plan, buf); - case HB_OT_TAG_HVAR: return _subset (plan, buf); - case HB_OT_TAG_VVAR: return _subset (plan, buf); -#endif + case HB_TAG('S','T','A','T'): + if (!plan->user_axes_location.is_empty ()) return _hb_subset_table (plan, buf); + else return _hb_subset_table_passthrough (plan, tag); + case HB_TAG('c','v','t',' '): #ifndef HB_NO_VAR - case HB_OT_TAG_fvar: - if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag); - return _subset (plan, buf); - case HB_OT_TAG_avar: - if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag); - return _subset (plan, buf); - case HB_OT_TAG_cvar: - if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag); - return _subset (plan, buf); - case HB_OT_TAG_MVAR: - if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag); - return _subset (plan, buf); -#endif - - case HB_OT_TAG_STAT: - if (!plan->user_axes_location.is_empty ()) return _subset (plan, buf); - else return _passthrough (plan, tag); - - case HB_TAG ('c', 'v', 't', ' '): -#ifndef HB_NO_VAR - if (_is_table_present (plan->source, HB_OT_TAG_cvar) && + if (_is_table_present (plan->source, HB_TAG('c','v','a','r')) && plan->normalized_coords && !plan->pinned_at_default) { auto &cvar = *plan->source->table.cvar; return OT::cvar::add_cvt_and_apply_deltas (plan, cvar.get_tuple_var_data (), &cvar); } #endif - return _passthrough (plan, tag); - - default: - if (plan->flags & HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED) - return _passthrough (plan, tag); - - // Drop table - return true; + return _hb_subset_table_passthrough (plan, tag); } + + if (plan->flags & HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED) + return _hb_subset_table_passthrough (plan, tag); + + // Drop table + return true; } static void _attach_accelerator_data (hb_subset_plan_t* plan, @@ -707,108 +449,4 @@ hb_subset_plan_execute_or_fail (hb_subset_plan_t *plan) end: return success ? hb_face_reference (plan->dest) : nullptr; -} - - -#ifdef HB_EXPERIMENTAL_API - -#include "hb-ot-cff1-table.hh" - -template -static hb_blob_t* get_charstrings_data(accel_t& accel, hb_codepoint_t glyph_index) { - if (!accel.is_valid()) { - return hb_blob_get_empty (); - } - - hb_ubytes_t bytes = (*accel.charStrings)[glyph_index]; - if (!bytes) { - return hb_blob_get_empty (); - } - - hb_blob_t* cff_blob = accel.get_blob(); - uint32_t length; - const char* cff_data = hb_blob_get_data(cff_blob, &length) ; - - long int offset = (const char*) bytes.arrayZ - cff_data; - if (offset < 0 || offset > INT32_MAX) { - return hb_blob_get_empty (); - } - - return hb_blob_create_sub_blob(cff_blob, (uint32_t) offset, bytes.length); -} - -template -static hb_blob_t* get_charstrings_index(accel_t& accel) { - if (!accel.is_valid()) { - return hb_blob_get_empty (); - } - - const char* charstrings_start = (const char*) accel.charStrings; - unsigned charstrings_length = accel.charStrings->get_size(); - - hb_blob_t* cff_blob = accel.get_blob(); - uint32_t length; - const char* cff_data = hb_blob_get_data(cff_blob, &length) ; - - long int offset = charstrings_start - cff_data; - if (offset < 0 || offset > INT32_MAX) { - return hb_blob_get_empty (); - } - - return hb_blob_create_sub_blob(cff_blob, (uint32_t) offset, charstrings_length); -} - -/** - * hb_subset_cff_get_charstring_data: - * @face: A face object - * @glyph_index: Glyph index to get data for. - * - * Returns the raw outline data from the CFF/CFF2 table associated with the given glyph index. - * - * XSince: EXPERIMENTAL - **/ -HB_EXTERN hb_blob_t* -hb_subset_cff_get_charstring_data(hb_face_t* face, hb_codepoint_t glyph_index) { - return get_charstrings_data(*face->table.cff1, glyph_index); -} - -/** - * hb_subset_cff_get_charstrings_index: - * @face: A face object - * - * Returns the raw CFF CharStrings INDEX from the CFF table. - * - * XSince: EXPERIMENTAL - **/ -HB_EXTERN hb_blob_t* -hb_subset_cff_get_charstrings_index (hb_face_t* face) { - return get_charstrings_index (*face->table.cff1); -} - -/** - * hb_subset_cff2_get_charstring_data: - * @face: A face object - * @glyph_index: Glyph index to get data for. - * - * Returns the raw outline data from the CFF/CFF2 table associated with the given glyph index. - * - * XSince: EXPERIMENTAL - **/ -HB_EXTERN hb_blob_t* -hb_subset_cff2_get_charstring_data(hb_face_t* face, hb_codepoint_t glyph_index) { - return get_charstrings_data(*face->table.cff2, glyph_index); -} - -/** - * hb_subset_cff2_get_charstrings_index: - * @face: A face object - * - * Returns the raw CFF2 CharStrings INDEX from the CFF2 table. - * - * XSince: EXPERIMENTAL - **/ -HB_EXTERN hb_blob_t* -hb_subset_cff2_get_charstrings_index (hb_face_t* face) { - return get_charstrings_index (*face->table.cff2); -} -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset.h b/src/java.desktop/share/native/libharfbuzz/hb-subset.h index 3eccd25738e..fd2908e8308 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset.h @@ -80,6 +80,10 @@ typedef struct hb_subset_plan_t hb_subset_plan_t; * @HB_SUBSET_FLAGS_IFTB_REQUIREMENTS: If set enforce requirements on the output subset * to allow it to be used with incremental font transfer IFTB patches. Primarily, * this forces all outline data to use long (32 bit) offsets. Since: EXPERIMENTAL + * @HB_SUBSET_FLAGS_RETAIN_NUM_GLYPHS: If this flag is set along side + * HB_SUBSET_FLAGS_RETAIN_GIDS then the number of glyphs in the font won't + * be reduced as a result of subsetting. If necessary empty glyphs will be + * included at the end of the font to keep the number of glyphs unchanged. * * List of boolean properties that can be configured on the subset input. * @@ -101,6 +105,7 @@ typedef enum { /*< flags >*/ HB_SUBSET_FLAGS_NO_BIDI_CLOSURE = 0x00000800u, #ifdef HB_EXPERIMENTAL_API HB_SUBSET_FLAGS_IFTB_REQUIREMENTS = 0x00001000u, + HB_SUBSET_FLAGS_RETAIN_NUM_GLYPHS = 0x00002000u, #endif } hb_subset_flags_t; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset.hh index bc7c24c94de..009919764f5 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset.hh @@ -70,5 +70,4 @@ struct hb_subset_context_t : table_tag (table_tag_) {} }; - #endif /* HB_SUBSET_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ucd-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ucd-table.hh index 8731a0bcf8d..868428ab1e7 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ucd-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ucd-table.hh @@ -2,9 +2,9 @@ /* * The following table is generated by running: * - * ./gen-ucd-table.py ucd.nounihan.grouped.xml + * ./gen-ucd-table.py ucd.nounihan.grouped.xml hb-script-list.h * - * on file with this description: Unicode 16.0.0 + * on file with this description: Unicode 17.0.0 */ #ifndef HB_UCD_TABLE_HH @@ -12,8 +12,9 @@ #include "hb.hh" -static const hb_script_t -_hb_ucd_sc_map[172] = +#include + +static const hb_script_t _hb_ucd_sc_map[176]= { HB_SCRIPT_COMMON, HB_SCRIPT_INHERITED, HB_SCRIPT_UNKNOWN, HB_SCRIPT_ARABIC, @@ -101,1040 +102,805 @@ _hb_ucd_sc_map[172] = HB_SCRIPT_GURUNG_KHEMA, HB_SCRIPT_KIRAT_RAI, HB_SCRIPT_OL_ONAL, HB_SCRIPT_SUNUWAR, HB_SCRIPT_TODHRI, HB_SCRIPT_TULU_TIGALARI, + HB_SCRIPT_BERIA_ERFE, HB_SCRIPT_SIDETIC, + HB_SCRIPT_TAI_YO, HB_SCRIPT_TOLONG_SIKI, }; -static const uint16_t -_hb_ucd_dm1_p0_map[825] = +static const uint16_t _hb_ucd_dm1_p0_map[825]= { - 0x003Bu, 0x004Bu, 0x0060u, 0x00B4u, 0x00B7u, 0x00C5u, 0x02B9u, 0x0300u, - 0x0301u, 0x0313u, 0x0385u, 0x0386u, 0x0388u, 0x0389u, 0x038Au, 0x038Cu, - 0x038Eu, 0x038Fu, 0x0390u, 0x03A9u, 0x03ACu, 0x03ADu, 0x03AEu, 0x03AFu, - 0x03B0u, 0x03B9u, 0x03CCu, 0x03CDu, 0x03CEu, 0x2002u, 0x2003u, 0x3008u, - 0x3009u, 0x349Eu, 0x34B9u, 0x34BBu, 0x34DFu, 0x3515u, 0x36EEu, 0x36FCu, - 0x3781u, 0x382Fu, 0x3862u, 0x387Cu, 0x38C7u, 0x38E3u, 0x391Cu, 0x393Au, - 0x3A2Eu, 0x3A6Cu, 0x3AE4u, 0x3B08u, 0x3B19u, 0x3B49u, 0x3B9Du, 0x3C18u, - 0x3C4Eu, 0x3D33u, 0x3D96u, 0x3EACu, 0x3EB8u, 0x3F1Bu, 0x3FFCu, 0x4008u, - 0x4018u, 0x4039u, 0x4046u, 0x4096u, 0x40E3u, 0x412Fu, 0x4202u, 0x4227u, - 0x42A0u, 0x4301u, 0x4334u, 0x4359u, 0x43D5u, 0x43D9u, 0x440Bu, 0x446Bu, - 0x452Bu, 0x455Du, 0x4561u, 0x456Bu, 0x45D7u, 0x45F9u, 0x4635u, 0x46BEu, - 0x46C7u, 0x4995u, 0x49E6u, 0x4A6Eu, 0x4A76u, 0x4AB2u, 0x4B33u, 0x4BCEu, - 0x4CCEu, 0x4CEDu, 0x4CF8u, 0x4D56u, 0x4E0Du, 0x4E26u, 0x4E32u, 0x4E38u, - 0x4E39u, 0x4E3Du, 0x4E41u, 0x4E82u, 0x4E86u, 0x4EAEu, 0x4EC0u, 0x4ECCu, - 0x4EE4u, 0x4F60u, 0x4F80u, 0x4F86u, 0x4F8Bu, 0x4FAEu, 0x4FBBu, 0x4FBFu, - 0x5002u, 0x502Bu, 0x507Au, 0x5099u, 0x50CFu, 0x50DAu, 0x50E7u, 0x5140u, - 0x5145u, 0x514Du, 0x5154u, 0x5164u, 0x5167u, 0x5168u, 0x5169u, 0x516Du, - 0x5177u, 0x5180u, 0x518Du, 0x5192u, 0x5195u, 0x5197u, 0x51A4u, 0x51ACu, - 0x51B5u, 0x51B7u, 0x51C9u, 0x51CCu, 0x51DCu, 0x51DEu, 0x51F5u, 0x5203u, - 0x5207u, 0x5217u, 0x5229u, 0x523Au, 0x523Bu, 0x5246u, 0x5272u, 0x5277u, - 0x5289u, 0x529Bu, 0x52A3u, 0x52B3u, 0x52C7u, 0x52C9u, 0x52D2u, 0x52DEu, - 0x52E4u, 0x52F5u, 0x52FAu, 0x5305u, 0x5306u, 0x5317u, 0x533Fu, 0x5349u, - 0x5351u, 0x535Au, 0x5373u, 0x5375u, 0x537Du, 0x537Fu, 0x53C3u, 0x53CAu, - 0x53DFu, 0x53E5u, 0x53EBu, 0x53F1u, 0x5406u, 0x540Fu, 0x541Du, 0x5438u, - 0x5442u, 0x5448u, 0x5468u, 0x549Eu, 0x54A2u, 0x54BDu, 0x54F6u, 0x5510u, - 0x5553u, 0x5555u, 0x5563u, 0x5584u, 0x5587u, 0x5599u, 0x559Du, 0x55ABu, - 0x55B3u, 0x55C0u, 0x55C2u, 0x55E2u, 0x5606u, 0x5651u, 0x5668u, 0x5674u, - 0x56F9u, 0x5716u, 0x5717u, 0x578Bu, 0x57CEu, 0x57F4u, 0x580Du, 0x5831u, - 0x5832u, 0x5840u, 0x585Au, 0x585Eu, 0x58A8u, 0x58ACu, 0x58B3u, 0x58D8u, - 0x58DFu, 0x58EEu, 0x58F2u, 0x58F7u, 0x5906u, 0x591Au, 0x5922u, 0x5944u, - 0x5948u, 0x5951u, 0x5954u, 0x5962u, 0x5973u, 0x59D8u, 0x59ECu, 0x5A1Bu, - 0x5A27u, 0x5A62u, 0x5A66u, 0x5AB5u, 0x5B08u, 0x5B28u, 0x5B3Eu, 0x5B85u, - 0x5BC3u, 0x5BD8u, 0x5BE7u, 0x5BEEu, 0x5BF3u, 0x5BFFu, 0x5C06u, 0x5C22u, - 0x5C3Fu, 0x5C60u, 0x5C62u, 0x5C64u, 0x5C65u, 0x5C6Eu, 0x5C8Du, 0x5CC0u, - 0x5D19u, 0x5D43u, 0x5D50u, 0x5D6Bu, 0x5D6Eu, 0x5D7Cu, 0x5DB2u, 0x5DBAu, - 0x5DE1u, 0x5DE2u, 0x5DFDu, 0x5E28u, 0x5E3Du, 0x5E69u, 0x5E74u, 0x5EA6u, - 0x5EB0u, 0x5EB3u, 0x5EB6u, 0x5EC9u, 0x5ECAu, 0x5ED2u, 0x5ED3u, 0x5ED9u, - 0x5EECu, 0x5EFEu, 0x5F04u, 0x5F22u, 0x5F53u, 0x5F62u, 0x5F69u, 0x5F6Bu, - 0x5F8Bu, 0x5F9Au, 0x5FA9u, 0x5FADu, 0x5FCDu, 0x5FD7u, 0x5FF5u, 0x5FF9u, - 0x6012u, 0x601Cu, 0x6075u, 0x6081u, 0x6094u, 0x60C7u, 0x60D8u, 0x60E1u, - 0x6108u, 0x6144u, 0x6148u, 0x614Cu, 0x614Eu, 0x6160u, 0x6168u, 0x617Au, - 0x618Eu, 0x6190u, 0x61A4u, 0x61AFu, 0x61B2u, 0x61DEu, 0x61F2u, 0x61F6u, - 0x6200u, 0x6210u, 0x621Bu, 0x622Eu, 0x6234u, 0x625Du, 0x62B1u, 0x62C9u, - 0x62CFu, 0x62D3u, 0x62D4u, 0x62FCu, 0x62FEu, 0x633Du, 0x6350u, 0x6368u, - 0x637Bu, 0x6383u, 0x63A0u, 0x63A9u, 0x63C4u, 0x63C5u, 0x63E4u, 0x641Cu, - 0x6422u, 0x6452u, 0x6469u, 0x6477u, 0x647Eu, 0x649Au, 0x649Du, 0x64C4u, - 0x654Fu, 0x6556u, 0x656Cu, 0x6578u, 0x6599u, 0x65C5u, 0x65E2u, 0x65E3u, - 0x6613u, 0x6649u, 0x6674u, 0x6688u, 0x6691u, 0x669Cu, 0x66B4u, 0x66C6u, - 0x66F4u, 0x66F8u, 0x6700u, 0x6717u, 0x671Bu, 0x6721u, 0x674Eu, 0x6753u, - 0x6756u, 0x675Eu, 0x677Bu, 0x6785u, 0x6797u, 0x67F3u, 0x67FAu, 0x6817u, - 0x681Fu, 0x6852u, 0x6881u, 0x6885u, 0x688Eu, 0x68A8u, 0x6914u, 0x6942u, - 0x69A3u, 0x69EAu, 0x6A02u, 0x6A13u, 0x6AA8u, 0x6AD3u, 0x6ADBu, 0x6B04u, - 0x6B21u, 0x6B54u, 0x6B72u, 0x6B77u, 0x6B79u, 0x6B9Fu, 0x6BAEu, 0x6BBAu, - 0x6BBBu, 0x6C4Eu, 0x6C67u, 0x6C88u, 0x6CBFu, 0x6CCCu, 0x6CCDu, 0x6CE5u, - 0x6D16u, 0x6D1Bu, 0x6D1Eu, 0x6D34u, 0x6D3Eu, 0x6D41u, 0x6D69u, 0x6D6Au, - 0x6D77u, 0x6D78u, 0x6D85u, 0x6DCBu, 0x6DDAu, 0x6DEAu, 0x6DF9u, 0x6E1Au, - 0x6E2Fu, 0x6E6Eu, 0x6E9Cu, 0x6EBAu, 0x6EC7u, 0x6ECBu, 0x6ED1u, 0x6EDBu, - 0x6F0Fu, 0x6F22u, 0x6F23u, 0x6F6Eu, 0x6FC6u, 0x6FEBu, 0x6FFEu, 0x701Bu, - 0x701Eu, 0x7039u, 0x704Au, 0x7070u, 0x7077u, 0x707Du, 0x7099u, 0x70ADu, - 0x70C8u, 0x70D9u, 0x7145u, 0x7149u, 0x716Eu, 0x719Cu, 0x71CEu, 0x71D0u, - 0x7210u, 0x721Bu, 0x7228u, 0x722Bu, 0x7235u, 0x7250u, 0x7262u, 0x7280u, - 0x7295u, 0x72AFu, 0x72C0u, 0x72FCu, 0x732Au, 0x7375u, 0x737Au, 0x7387u, - 0x738Bu, 0x73A5u, 0x73B2u, 0x73DEu, 0x7406u, 0x7409u, 0x7422u, 0x7447u, - 0x745Cu, 0x7469u, 0x7471u, 0x7485u, 0x7489u, 0x7498u, 0x74CAu, 0x7506u, - 0x7524u, 0x753Bu, 0x753Eu, 0x7559u, 0x7565u, 0x7570u, 0x75E2u, 0x7610u, - 0x761Du, 0x761Fu, 0x7642u, 0x7669u, 0x76CAu, 0x76DBu, 0x76E7u, 0x76F4u, - 0x7701u, 0x771Eu, 0x771Fu, 0x7740u, 0x774Au, 0x778Bu, 0x77A7u, 0x784Eu, - 0x786Bu, 0x788Cu, 0x7891u, 0x78CAu, 0x78CCu, 0x78FBu, 0x792Au, 0x793Cu, - 0x793Eu, 0x7948u, 0x7949u, 0x7950u, 0x7956u, 0x795Du, 0x795Eu, 0x7965u, - 0x797Fu, 0x798Du, 0x798Eu, 0x798Fu, 0x79AEu, 0x79CAu, 0x79EBu, 0x7A1Cu, - 0x7A40u, 0x7A4Au, 0x7A4Fu, 0x7A81u, 0x7AB1u, 0x7ACBu, 0x7AEEu, 0x7B20u, - 0x7BC0u, 0x7BC6u, 0x7BC9u, 0x7C3Eu, 0x7C60u, 0x7C7Bu, 0x7C92u, 0x7CBEu, - 0x7CD2u, 0x7CD6u, 0x7CE3u, 0x7CE7u, 0x7CE8u, 0x7D00u, 0x7D10u, 0x7D22u, - 0x7D2Fu, 0x7D5Bu, 0x7D63u, 0x7DA0u, 0x7DBEu, 0x7DC7u, 0x7DF4u, 0x7E02u, - 0x7E09u, 0x7E37u, 0x7E41u, 0x7E45u, 0x7F3Eu, 0x7F72u, 0x7F79u, 0x7F7Au, - 0x7F85u, 0x7F95u, 0x7F9Au, 0x7FBDu, 0x7FFAu, 0x8001u, 0x8005u, 0x8046u, - 0x8060u, 0x806Fu, 0x8070u, 0x807Eu, 0x808Bu, 0x80ADu, 0x80B2u, 0x8103u, - 0x813Eu, 0x81D8u, 0x81E8u, 0x81EDu, 0x8201u, 0x8204u, 0x8218u, 0x826Fu, - 0x8279u, 0x828Bu, 0x8291u, 0x829Du, 0x82B1u, 0x82B3u, 0x82BDu, 0x82E5u, - 0x82E6u, 0x831Du, 0x8323u, 0x8336u, 0x8352u, 0x8353u, 0x8363u, 0x83ADu, - 0x83BDu, 0x83C9u, 0x83CAu, 0x83CCu, 0x83DCu, 0x83E7u, 0x83EFu, 0x83F1u, - 0x843Du, 0x8449u, 0x8457u, 0x84EEu, 0x84F1u, 0x84F3u, 0x84FCu, 0x8516u, - 0x8564u, 0x85CDu, 0x85FAu, 0x8606u, 0x8612u, 0x862Du, 0x863Fu, 0x8650u, - 0x865Cu, 0x8667u, 0x8669u, 0x8688u, 0x86A9u, 0x86E2u, 0x870Eu, 0x8728u, - 0x876Bu, 0x8779u, 0x8786u, 0x87BAu, 0x87E1u, 0x8801u, 0x881Fu, 0x884Cu, - 0x8860u, 0x8863u, 0x88C2u, 0x88CFu, 0x88D7u, 0x88DEu, 0x88E1u, 0x88F8u, - 0x88FAu, 0x8910u, 0x8941u, 0x8964u, 0x8986u, 0x898Bu, 0x8996u, 0x8AA0u, - 0x8AAAu, 0x8ABFu, 0x8ACBu, 0x8AD2u, 0x8AD6u, 0x8AEDu, 0x8AF8u, 0x8AFEu, - 0x8B01u, 0x8B39u, 0x8B58u, 0x8B80u, 0x8B8Au, 0x8C48u, 0x8C55u, 0x8CABu, - 0x8CC1u, 0x8CC2u, 0x8CC8u, 0x8CD3u, 0x8D08u, 0x8D1Bu, 0x8D77u, 0x8DBCu, - 0x8DCBu, 0x8DEFu, 0x8DF0u, 0x8ECAu, 0x8ED4u, 0x8F26u, 0x8F2Au, 0x8F38u, - 0x8F3Bu, 0x8F62u, 0x8F9Eu, 0x8FB0u, 0x8FB6u, 0x9023u, 0x9038u, 0x9072u, - 0x907Cu, 0x908Fu, 0x9094u, 0x90CEu, 0x90DEu, 0x90F1u, 0x90FDu, 0x9111u, - 0x911Bu, 0x916Au, 0x9199u, 0x91B4u, 0x91CCu, 0x91CFu, 0x91D1u, 0x9234u, - 0x9238u, 0x9276u, 0x927Cu, 0x92D7u, 0x92D8u, 0x9304u, 0x934Au, 0x93F9u, - 0x9415u, 0x958Bu, 0x95ADu, 0x95B7u, 0x962Eu, 0x964Bu, 0x964Du, 0x9675u, - 0x9678u, 0x967Cu, 0x9686u, 0x96A3u, 0x96B7u, 0x96B8u, 0x96C3u, 0x96E2u, - 0x96E3u, 0x96F6u, 0x96F7u, 0x9723u, 0x9732u, 0x9748u, 0x9756u, 0x97DBu, - 0x97E0u, 0x97FFu, 0x980Bu, 0x9818u, 0x9829u, 0x983Bu, 0x985Eu, 0x98E2u, - 0x98EFu, 0x98FCu, 0x9928u, 0x9929u, 0x99A7u, 0x99C2u, 0x99F1u, 0x99FEu, - 0x9A6Au, 0x9B12u, 0x9B6Fu, 0x9C40u, 0x9C57u, 0x9CFDu, 0x9D67u, 0x9DB4u, - 0x9DFAu, 0x9E1Eu, 0x9E7Fu, 0x9E97u, 0x9E9Fu, 0x9EBBu, 0x9ECEu, 0x9EF9u, - 0x9EFEu, 0x9F05u, 0x9F0Fu, 0x9F16u, 0x9F3Bu, 0x9F43u, 0x9F8Du, 0x9F8Eu, - 0x9F9Cu, + 0x003B, 0x004B, 0x0060, 0x00B4, 0x00B7, 0x00C5, 0x02B9, 0x0300, + 0x0301, 0x0313, 0x0385, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, + 0x038E, 0x038F, 0x0390, 0x03A9, 0x03AC, 0x03AD, 0x03AE, 0x03AF, + 0x03B0, 0x03B9, 0x03CC, 0x03CD, 0x03CE, 0x2002, 0x2003, 0x3008, + 0x3009, 0x349E, 0x34B9, 0x34BB, 0x34DF, 0x3515, 0x36EE, 0x36FC, + 0x3781, 0x382F, 0x3862, 0x387C, 0x38C7, 0x38E3, 0x391C, 0x393A, + 0x3A2E, 0x3A6C, 0x3AE4, 0x3B08, 0x3B19, 0x3B49, 0x3B9D, 0x3C18, + 0x3C4E, 0x3D33, 0x3D96, 0x3EAC, 0x3EB8, 0x3F1B, 0x3FFC, 0x4008, + 0x4018, 0x4039, 0x4046, 0x4096, 0x40E3, 0x412F, 0x4202, 0x4227, + 0x42A0, 0x4301, 0x4334, 0x4359, 0x43D5, 0x43D9, 0x440B, 0x446B, + 0x452B, 0x455D, 0x4561, 0x456B, 0x45D7, 0x45F9, 0x4635, 0x46BE, + 0x46C7, 0x4995, 0x49E6, 0x4A6E, 0x4A76, 0x4AB2, 0x4B33, 0x4BCE, + 0x4CCE, 0x4CED, 0x4CF8, 0x4D56, 0x4E0D, 0x4E26, 0x4E32, 0x4E38, + 0x4E39, 0x4E3D, 0x4E41, 0x4E82, 0x4E86, 0x4EAE, 0x4EC0, 0x4ECC, + 0x4EE4, 0x4F60, 0x4F80, 0x4F86, 0x4F8B, 0x4FAE, 0x4FBB, 0x4FBF, + 0x5002, 0x502B, 0x507A, 0x5099, 0x50CF, 0x50DA, 0x50E7, 0x5140, + 0x5145, 0x514D, 0x5154, 0x5164, 0x5167, 0x5168, 0x5169, 0x516D, + 0x5177, 0x5180, 0x518D, 0x5192, 0x5195, 0x5197, 0x51A4, 0x51AC, + 0x51B5, 0x51B7, 0x51C9, 0x51CC, 0x51DC, 0x51DE, 0x51F5, 0x5203, + 0x5207, 0x5217, 0x5229, 0x523A, 0x523B, 0x5246, 0x5272, 0x5277, + 0x5289, 0x529B, 0x52A3, 0x52B3, 0x52C7, 0x52C9, 0x52D2, 0x52DE, + 0x52E4, 0x52F5, 0x52FA, 0x5305, 0x5306, 0x5317, 0x533F, 0x5349, + 0x5351, 0x535A, 0x5373, 0x5375, 0x537D, 0x537F, 0x53C3, 0x53CA, + 0x53DF, 0x53E5, 0x53EB, 0x53F1, 0x5406, 0x540F, 0x541D, 0x5438, + 0x5442, 0x5448, 0x5468, 0x549E, 0x54A2, 0x54BD, 0x54F6, 0x5510, + 0x5553, 0x5555, 0x5563, 0x5584, 0x5587, 0x5599, 0x559D, 0x55AB, + 0x55B3, 0x55C0, 0x55C2, 0x55E2, 0x5606, 0x5651, 0x5668, 0x5674, + 0x56F9, 0x5716, 0x5717, 0x578B, 0x57CE, 0x57F4, 0x580D, 0x5831, + 0x5832, 0x5840, 0x585A, 0x585E, 0x58A8, 0x58AC, 0x58B3, 0x58D8, + 0x58DF, 0x58EE, 0x58F2, 0x58F7, 0x5906, 0x591A, 0x5922, 0x5944, + 0x5948, 0x5951, 0x5954, 0x5962, 0x5973, 0x59D8, 0x59EC, 0x5A1B, + 0x5A27, 0x5A62, 0x5A66, 0x5AB5, 0x5B08, 0x5B28, 0x5B3E, 0x5B85, + 0x5BC3, 0x5BD8, 0x5BE7, 0x5BEE, 0x5BF3, 0x5BFF, 0x5C06, 0x5C22, + 0x5C3F, 0x5C60, 0x5C62, 0x5C64, 0x5C65, 0x5C6E, 0x5C8D, 0x5CC0, + 0x5D19, 0x5D43, 0x5D50, 0x5D6B, 0x5D6E, 0x5D7C, 0x5DB2, 0x5DBA, + 0x5DE1, 0x5DE2, 0x5DFD, 0x5E28, 0x5E3D, 0x5E69, 0x5E74, 0x5EA6, + 0x5EB0, 0x5EB3, 0x5EB6, 0x5EC9, 0x5ECA, 0x5ED2, 0x5ED3, 0x5ED9, + 0x5EEC, 0x5EFE, 0x5F04, 0x5F22, 0x5F53, 0x5F62, 0x5F69, 0x5F6B, + 0x5F8B, 0x5F9A, 0x5FA9, 0x5FAD, 0x5FCD, 0x5FD7, 0x5FF5, 0x5FF9, + 0x6012, 0x601C, 0x6075, 0x6081, 0x6094, 0x60C7, 0x60D8, 0x60E1, + 0x6108, 0x6144, 0x6148, 0x614C, 0x614E, 0x6160, 0x6168, 0x617A, + 0x618E, 0x6190, 0x61A4, 0x61AF, 0x61B2, 0x61DE, 0x61F2, 0x61F6, + 0x6200, 0x6210, 0x621B, 0x622E, 0x6234, 0x625D, 0x62B1, 0x62C9, + 0x62CF, 0x62D3, 0x62D4, 0x62FC, 0x62FE, 0x633D, 0x6350, 0x6368, + 0x637B, 0x6383, 0x63A0, 0x63A9, 0x63C4, 0x63C5, 0x63E4, 0x641C, + 0x6422, 0x6452, 0x6469, 0x6477, 0x647E, 0x649A, 0x649D, 0x64C4, + 0x654F, 0x6556, 0x656C, 0x6578, 0x6599, 0x65C5, 0x65E2, 0x65E3, + 0x6613, 0x6649, 0x6674, 0x6688, 0x6691, 0x669C, 0x66B4, 0x66C6, + 0x66F4, 0x66F8, 0x6700, 0x6717, 0x671B, 0x6721, 0x674E, 0x6753, + 0x6756, 0x675E, 0x677B, 0x6785, 0x6797, 0x67F3, 0x67FA, 0x6817, + 0x681F, 0x6852, 0x6881, 0x6885, 0x688E, 0x68A8, 0x6914, 0x6942, + 0x69A3, 0x69EA, 0x6A02, 0x6A13, 0x6AA8, 0x6AD3, 0x6ADB, 0x6B04, + 0x6B21, 0x6B54, 0x6B72, 0x6B77, 0x6B79, 0x6B9F, 0x6BAE, 0x6BBA, + 0x6BBB, 0x6C4E, 0x6C67, 0x6C88, 0x6CBF, 0x6CCC, 0x6CCD, 0x6CE5, + 0x6D16, 0x6D1B, 0x6D1E, 0x6D34, 0x6D3E, 0x6D41, 0x6D69, 0x6D6A, + 0x6D77, 0x6D78, 0x6D85, 0x6DCB, 0x6DDA, 0x6DEA, 0x6DF9, 0x6E1A, + 0x6E2F, 0x6E6E, 0x6E9C, 0x6EBA, 0x6EC7, 0x6ECB, 0x6ED1, 0x6EDB, + 0x6F0F, 0x6F22, 0x6F23, 0x6F6E, 0x6FC6, 0x6FEB, 0x6FFE, 0x701B, + 0x701E, 0x7039, 0x704A, 0x7070, 0x7077, 0x707D, 0x7099, 0x70AD, + 0x70C8, 0x70D9, 0x7145, 0x7149, 0x716E, 0x719C, 0x71CE, 0x71D0, + 0x7210, 0x721B, 0x7228, 0x722B, 0x7235, 0x7250, 0x7262, 0x7280, + 0x7295, 0x72AF, 0x72C0, 0x72FC, 0x732A, 0x7375, 0x737A, 0x7387, + 0x738B, 0x73A5, 0x73B2, 0x73DE, 0x7406, 0x7409, 0x7422, 0x7447, + 0x745C, 0x7469, 0x7471, 0x7485, 0x7489, 0x7498, 0x74CA, 0x7506, + 0x7524, 0x753B, 0x753E, 0x7559, 0x7565, 0x7570, 0x75E2, 0x7610, + 0x761D, 0x761F, 0x7642, 0x7669, 0x76CA, 0x76DB, 0x76E7, 0x76F4, + 0x7701, 0x771E, 0x771F, 0x7740, 0x774A, 0x778B, 0x77A7, 0x784E, + 0x786B, 0x788C, 0x7891, 0x78CA, 0x78CC, 0x78FB, 0x792A, 0x793C, + 0x793E, 0x7948, 0x7949, 0x7950, 0x7956, 0x795D, 0x795E, 0x7965, + 0x797F, 0x798D, 0x798E, 0x798F, 0x79AE, 0x79CA, 0x79EB, 0x7A1C, + 0x7A40, 0x7A4A, 0x7A4F, 0x7A81, 0x7AB1, 0x7ACB, 0x7AEE, 0x7B20, + 0x7BC0, 0x7BC6, 0x7BC9, 0x7C3E, 0x7C60, 0x7C7B, 0x7C92, 0x7CBE, + 0x7CD2, 0x7CD6, 0x7CE3, 0x7CE7, 0x7CE8, 0x7D00, 0x7D10, 0x7D22, + 0x7D2F, 0x7D5B, 0x7D63, 0x7DA0, 0x7DBE, 0x7DC7, 0x7DF4, 0x7E02, + 0x7E09, 0x7E37, 0x7E41, 0x7E45, 0x7F3E, 0x7F72, 0x7F79, 0x7F7A, + 0x7F85, 0x7F95, 0x7F9A, 0x7FBD, 0x7FFA, 0x8001, 0x8005, 0x8046, + 0x8060, 0x806F, 0x8070, 0x807E, 0x808B, 0x80AD, 0x80B2, 0x8103, + 0x813E, 0x81D8, 0x81E8, 0x81ED, 0x8201, 0x8204, 0x8218, 0x826F, + 0x8279, 0x828B, 0x8291, 0x829D, 0x82B1, 0x82B3, 0x82BD, 0x82E5, + 0x82E6, 0x831D, 0x8323, 0x8336, 0x8352, 0x8353, 0x8363, 0x83AD, + 0x83BD, 0x83C9, 0x83CA, 0x83CC, 0x83DC, 0x83E7, 0x83EF, 0x83F1, + 0x843D, 0x8449, 0x8457, 0x84EE, 0x84F1, 0x84F3, 0x84FC, 0x8516, + 0x8564, 0x85CD, 0x85FA, 0x8606, 0x8612, 0x862D, 0x863F, 0x8650, + 0x865C, 0x8667, 0x8669, 0x8688, 0x86A9, 0x86E2, 0x870E, 0x8728, + 0x876B, 0x8779, 0x8786, 0x87BA, 0x87E1, 0x8801, 0x881F, 0x884C, + 0x8860, 0x8863, 0x88C2, 0x88CF, 0x88D7, 0x88DE, 0x88E1, 0x88F8, + 0x88FA, 0x8910, 0x8941, 0x8964, 0x8986, 0x898B, 0x8996, 0x8AA0, + 0x8AAA, 0x8ABF, 0x8ACB, 0x8AD2, 0x8AD6, 0x8AED, 0x8AF8, 0x8AFE, + 0x8B01, 0x8B39, 0x8B58, 0x8B80, 0x8B8A, 0x8C48, 0x8C55, 0x8CAB, + 0x8CC1, 0x8CC2, 0x8CC8, 0x8CD3, 0x8D08, 0x8D1B, 0x8D77, 0x8DBC, + 0x8DCB, 0x8DEF, 0x8DF0, 0x8ECA, 0x8ED4, 0x8F26, 0x8F2A, 0x8F38, + 0x8F3B, 0x8F62, 0x8F9E, 0x8FB0, 0x8FB6, 0x9023, 0x9038, 0x9072, + 0x907C, 0x908F, 0x9094, 0x90CE, 0x90DE, 0x90F1, 0x90FD, 0x9111, + 0x911B, 0x916A, 0x9199, 0x91B4, 0x91CC, 0x91CF, 0x91D1, 0x9234, + 0x9238, 0x9276, 0x927C, 0x92D7, 0x92D8, 0x9304, 0x934A, 0x93F9, + 0x9415, 0x958B, 0x95AD, 0x95B7, 0x962E, 0x964B, 0x964D, 0x9675, + 0x9678, 0x967C, 0x9686, 0x96A3, 0x96B7, 0x96B8, 0x96C3, 0x96E2, + 0x96E3, 0x96F6, 0x96F7, 0x9723, 0x9732, 0x9748, 0x9756, 0x97DB, + 0x97E0, 0x97FF, 0x980B, 0x9818, 0x9829, 0x983B, 0x985E, 0x98E2, + 0x98EF, 0x98FC, 0x9928, 0x9929, 0x99A7, 0x99C2, 0x99F1, 0x99FE, + 0x9A6A, 0x9B12, 0x9B6F, 0x9C40, 0x9C57, 0x9CFD, 0x9D67, 0x9DB4, + 0x9DFA, 0x9E1E, 0x9E7F, 0x9E97, 0x9E9F, 0x9EBB, 0x9ECE, 0x9EF9, + 0x9EFE, 0x9F05, 0x9F0F, 0x9F16, 0x9F3B, 0x9F43, 0x9F8D, 0x9F8E, + 0x9F9C, }; -static const uint16_t -_hb_ucd_dm1_p2_map[110] = +static const uint16_t _hb_ucd_dm1_p2_map[110]= { - 0x0122u, 0x051Cu, 0x0525u, 0x054Bu, 0x063Au, 0x0804u, 0x08DEu, 0x0A2Cu, - 0x0B63u, 0x14E4u, 0x16A8u, 0x16EAu, 0x19C8u, 0x1B18u, 0x1D0Bu, 0x1DE4u, - 0x1DE6u, 0x2183u, 0x219Fu, 0x2331u, 0x26D4u, 0x2844u, 0x284Au, 0x2B0Cu, - 0x2BF1u, 0x300Au, 0x32B8u, 0x335Fu, 0x3393u, 0x339Cu, 0x33C3u, 0x33D5u, - 0x346Du, 0x36A3u, 0x38A7u, 0x3A8Du, 0x3AFAu, 0x3CBCu, 0x3D1Eu, 0x3ED1u, - 0x3F5Eu, 0x3F8Eu, 0x4263u, 0x42EEu, 0x43ABu, 0x4608u, 0x4735u, 0x4814u, - 0x4C36u, 0x4C92u, 0x4FA1u, 0x4FB8u, 0x5044u, 0x50F2u, 0x50F3u, 0x5119u, - 0x5133u, 0x5249u, 0x541Du, 0x5626u, 0x569Au, 0x56C5u, 0x597Cu, 0x5AA7u, - 0x5BABu, 0x5C80u, 0x5CD0u, 0x5F86u, 0x61DAu, 0x6228u, 0x6247u, 0x62D9u, - 0x633Eu, 0x64DAu, 0x6523u, 0x65A8u, 0x67A7u, 0x67B5u, 0x6B3Cu, 0x6C36u, - 0x6CD5u, 0x6D6Bu, 0x6F2Cu, 0x6FB1u, 0x70D2u, 0x73CAu, 0x7667u, 0x78AEu, - 0x7966u, 0x7CA8u, 0x7ED3u, 0x7F2Fu, 0x85D2u, 0x85EDu, 0x872Eu, 0x8BFAu, - 0x8D77u, 0x9145u, 0x91DFu, 0x921Au, 0x940Au, 0x9496u, 0x95B6u, 0x9B30u, - 0xA0CEu, 0xA105u, 0xA20Eu, 0xA291u, 0xA392u, 0xA600u, + 0x0122, 0x051C, 0x0525, 0x054B, 0x063A, 0x0804, 0x08DE, 0x0A2C, + 0x0B63, 0x14E4, 0x16A8, 0x16EA, 0x19C8, 0x1B18, 0x1D0B, 0x1DE4, + 0x1DE6, 0x2183, 0x219F, 0x2331, 0x26D4, 0x2844, 0x284A, 0x2B0C, + 0x2BF1, 0x300A, 0x32B8, 0x335F, 0x3393, 0x339C, 0x33C3, 0x33D5, + 0x346D, 0x36A3, 0x38A7, 0x3A8D, 0x3AFA, 0x3CBC, 0x3D1E, 0x3ED1, + 0x3F5E, 0x3F8E, 0x4263, 0x42EE, 0x43AB, 0x4608, 0x4735, 0x4814, + 0x4C36, 0x4C92, 0x4FA1, 0x4FB8, 0x5044, 0x50F2, 0x50F3, 0x5119, + 0x5133, 0x5249, 0x541D, 0x5626, 0x569A, 0x56C5, 0x597C, 0x5AA7, + 0x5BAB, 0x5C80, 0x5CD0, 0x5F86, 0x61DA, 0x6228, 0x6247, 0x62D9, + 0x633E, 0x64DA, 0x6523, 0x65A8, 0x67A7, 0x67B5, 0x6B3C, 0x6C36, + 0x6CD5, 0x6D6B, 0x6F2C, 0x6FB1, 0x70D2, 0x73CA, 0x7667, 0x78AE, + 0x7966, 0x7CA8, 0x7ED3, 0x7F2F, 0x85D2, 0x85ED, 0x872E, 0x8BFA, + 0x8D77, 0x9145, 0x91DF, 0x921A, 0x940A, 0x9496, 0x95B6, 0x9B30, + 0xA0CE, 0xA105, 0xA20E, 0xA291, 0xA392, 0xA600, }; -static const uint32_t -_hb_ucd_dm2_u32_map[638] = +static const uint32_t _hb_ucd_dm2_u32_map[638]= { - HB_CODEPOINT_ENCODE3_11_7_14 (0x003Cu, 0x0338u, 0x226Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x003Du, 0x0338u, 0x2260u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x003Eu, 0x0338u, 0x226Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0300u, 0x00C0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0301u, 0x00C1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0302u, 0x00C2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0303u, 0x00C3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0304u, 0x0100u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0306u, 0x0102u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0307u, 0x0226u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0308u, 0x00C4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0309u, 0x1EA2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x030Au, 0x00C5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x030Cu, 0x01CDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x030Fu, 0x0200u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0311u, 0x0202u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0323u, 0x1EA0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0325u, 0x1E00u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0328u, 0x0104u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0042u, 0x0307u, 0x1E02u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0042u, 0x0323u, 0x1E04u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0042u, 0x0331u, 0x1E06u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x0301u, 0x0106u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x0302u, 0x0108u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x0307u, 0x010Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x030Cu, 0x010Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x0327u, 0x00C7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x0307u, 0x1E0Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x030Cu, 0x010Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x0323u, 0x1E0Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x0327u, 0x1E10u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x032Du, 0x1E12u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x0331u, 0x1E0Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0300u, 0x00C8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0301u, 0x00C9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0302u, 0x00CAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0303u, 0x1EBCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0304u, 0x0112u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0306u, 0x0114u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0307u, 0x0116u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0308u, 0x00CBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0309u, 0x1EBAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x030Cu, 0x011Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x030Fu, 0x0204u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0311u, 0x0206u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0323u, 0x1EB8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0327u, 0x0228u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0328u, 0x0118u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x032Du, 0x1E18u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0330u, 0x1E1Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0046u, 0x0307u, 0x1E1Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0301u, 0x01F4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0302u, 0x011Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0304u, 0x1E20u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0306u, 0x011Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0307u, 0x0120u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x030Cu, 0x01E6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0327u, 0x0122u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0302u, 0x0124u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0307u, 0x1E22u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0308u, 0x1E26u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x030Cu, 0x021Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0323u, 0x1E24u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0327u, 0x1E28u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x032Eu, 0x1E2Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0300u, 0x00CCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0301u, 0x00CDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0302u, 0x00CEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0303u, 0x0128u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0304u, 0x012Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0306u, 0x012Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0307u, 0x0130u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0308u, 0x00CFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0309u, 0x1EC8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x030Cu, 0x01CFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x030Fu, 0x0208u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0311u, 0x020Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0323u, 0x1ECAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0328u, 0x012Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0330u, 0x1E2Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Au, 0x0302u, 0x0134u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x0301u, 0x1E30u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x030Cu, 0x01E8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x0323u, 0x1E32u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x0327u, 0x0136u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x0331u, 0x1E34u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x0301u, 0x0139u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x030Cu, 0x013Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x0323u, 0x1E36u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x0327u, 0x013Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x032Du, 0x1E3Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x0331u, 0x1E3Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Du, 0x0301u, 0x1E3Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Du, 0x0307u, 0x1E40u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Du, 0x0323u, 0x1E42u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0300u, 0x01F8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0301u, 0x0143u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0303u, 0x00D1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0307u, 0x1E44u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x030Cu, 0x0147u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0323u, 0x1E46u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0327u, 0x0145u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x032Du, 0x1E4Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0331u, 0x1E48u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0300u, 0x00D2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0301u, 0x00D3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0302u, 0x00D4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0303u, 0x00D5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0304u, 0x014Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0306u, 0x014Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0307u, 0x022Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0308u, 0x00D6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0309u, 0x1ECEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x030Bu, 0x0150u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x030Cu, 0x01D1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x030Fu, 0x020Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0311u, 0x020Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x031Bu, 0x01A0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0323u, 0x1ECCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0328u, 0x01EAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0050u, 0x0301u, 0x1E54u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0050u, 0x0307u, 0x1E56u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0301u, 0x0154u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0307u, 0x1E58u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x030Cu, 0x0158u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x030Fu, 0x0210u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0311u, 0x0212u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0323u, 0x1E5Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0327u, 0x0156u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0331u, 0x1E5Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0301u, 0x015Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0302u, 0x015Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0307u, 0x1E60u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x030Cu, 0x0160u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0323u, 0x1E62u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0326u, 0x0218u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0327u, 0x015Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0307u, 0x1E6Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x030Cu, 0x0164u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0323u, 0x1E6Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0326u, 0x021Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0327u, 0x0162u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x032Du, 0x1E70u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0331u, 0x1E6Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0300u, 0x00D9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0301u, 0x00DAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0302u, 0x00DBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0303u, 0x0168u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0304u, 0x016Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0306u, 0x016Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0308u, 0x00DCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0309u, 0x1EE6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x030Au, 0x016Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x030Bu, 0x0170u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x030Cu, 0x01D3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x030Fu, 0x0214u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0311u, 0x0216u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x031Bu, 0x01AFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0323u, 0x1EE4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0324u, 0x1E72u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0328u, 0x0172u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x032Du, 0x1E76u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0330u, 0x1E74u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0056u, 0x0303u, 0x1E7Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0056u, 0x0323u, 0x1E7Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0300u, 0x1E80u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0301u, 0x1E82u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0302u, 0x0174u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0307u, 0x1E86u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0308u, 0x1E84u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0323u, 0x1E88u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0058u, 0x0307u, 0x1E8Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0058u, 0x0308u, 0x1E8Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0300u, 0x1EF2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0301u, 0x00DDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0302u, 0x0176u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0303u, 0x1EF8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0304u, 0x0232u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0307u, 0x1E8Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0308u, 0x0178u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0309u, 0x1EF6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0323u, 0x1EF4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0301u, 0x0179u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0302u, 0x1E90u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0307u, 0x017Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x030Cu, 0x017Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0323u, 0x1E92u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0331u, 0x1E94u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0300u, 0x00E0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0301u, 0x00E1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0302u, 0x00E2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0303u, 0x00E3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0304u, 0x0101u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0306u, 0x0103u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0307u, 0x0227u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0308u, 0x00E4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0309u, 0x1EA3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x030Au, 0x00E5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x030Cu, 0x01CEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x030Fu, 0x0201u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0311u, 0x0203u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0323u, 0x1EA1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0325u, 0x1E01u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0328u, 0x0105u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0062u, 0x0307u, 0x1E03u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0062u, 0x0323u, 0x1E05u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0062u, 0x0331u, 0x1E07u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x0301u, 0x0107u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x0302u, 0x0109u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x0307u, 0x010Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x030Cu, 0x010Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x0327u, 0x00E7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x0307u, 0x1E0Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x030Cu, 0x010Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x0323u, 0x1E0Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x0327u, 0x1E11u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x032Du, 0x1E13u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x0331u, 0x1E0Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0300u, 0x00E8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0301u, 0x00E9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0302u, 0x00EAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0303u, 0x1EBDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0304u, 0x0113u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0306u, 0x0115u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0307u, 0x0117u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0308u, 0x00EBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0309u, 0x1EBBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x030Cu, 0x011Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x030Fu, 0x0205u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0311u, 0x0207u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0323u, 0x1EB9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0327u, 0x0229u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0328u, 0x0119u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x032Du, 0x1E19u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0330u, 0x1E1Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0066u, 0x0307u, 0x1E1Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0301u, 0x01F5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0302u, 0x011Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0304u, 0x1E21u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0306u, 0x011Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0307u, 0x0121u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x030Cu, 0x01E7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0327u, 0x0123u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0302u, 0x0125u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0307u, 0x1E23u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0308u, 0x1E27u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x030Cu, 0x021Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0323u, 0x1E25u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0327u, 0x1E29u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x032Eu, 0x1E2Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0331u, 0x1E96u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0300u, 0x00ECu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0301u, 0x00EDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0302u, 0x00EEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0303u, 0x0129u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0304u, 0x012Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0306u, 0x012Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0308u, 0x00EFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0309u, 0x1EC9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x030Cu, 0x01D0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x030Fu, 0x0209u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0311u, 0x020Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0323u, 0x1ECBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0328u, 0x012Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0330u, 0x1E2Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Au, 0x0302u, 0x0135u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Au, 0x030Cu, 0x01F0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x0301u, 0x1E31u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x030Cu, 0x01E9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x0323u, 0x1E33u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x0327u, 0x0137u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x0331u, 0x1E35u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x0301u, 0x013Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x030Cu, 0x013Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x0323u, 0x1E37u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x0327u, 0x013Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x032Du, 0x1E3Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x0331u, 0x1E3Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Du, 0x0301u, 0x1E3Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Du, 0x0307u, 0x1E41u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Du, 0x0323u, 0x1E43u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0300u, 0x01F9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0301u, 0x0144u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0303u, 0x00F1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0307u, 0x1E45u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x030Cu, 0x0148u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0323u, 0x1E47u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0327u, 0x0146u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x032Du, 0x1E4Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0331u, 0x1E49u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0300u, 0x00F2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0301u, 0x00F3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0302u, 0x00F4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0303u, 0x00F5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0304u, 0x014Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0306u, 0x014Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0307u, 0x022Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0308u, 0x00F6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0309u, 0x1ECFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x030Bu, 0x0151u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x030Cu, 0x01D2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x030Fu, 0x020Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0311u, 0x020Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x031Bu, 0x01A1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0323u, 0x1ECDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0328u, 0x01EBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0070u, 0x0301u, 0x1E55u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0070u, 0x0307u, 0x1E57u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0301u, 0x0155u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0307u, 0x1E59u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x030Cu, 0x0159u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x030Fu, 0x0211u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0311u, 0x0213u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0323u, 0x1E5Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0327u, 0x0157u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0331u, 0x1E5Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0301u, 0x015Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0302u, 0x015Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0307u, 0x1E61u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x030Cu, 0x0161u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0323u, 0x1E63u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0326u, 0x0219u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0327u, 0x015Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0307u, 0x1E6Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0308u, 0x1E97u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x030Cu, 0x0165u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0323u, 0x1E6Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0326u, 0x021Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0327u, 0x0163u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x032Du, 0x1E71u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0331u, 0x1E6Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0300u, 0x00F9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0301u, 0x00FAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0302u, 0x00FBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0303u, 0x0169u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0304u, 0x016Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0306u, 0x016Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0308u, 0x00FCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0309u, 0x1EE7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x030Au, 0x016Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x030Bu, 0x0171u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x030Cu, 0x01D4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x030Fu, 0x0215u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0311u, 0x0217u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x031Bu, 0x01B0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0323u, 0x1EE5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0324u, 0x1E73u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0328u, 0x0173u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x032Du, 0x1E77u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0330u, 0x1E75u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0076u, 0x0303u, 0x1E7Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0076u, 0x0323u, 0x1E7Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0300u, 0x1E81u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0301u, 0x1E83u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0302u, 0x0175u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0307u, 0x1E87u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0308u, 0x1E85u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x030Au, 0x1E98u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0323u, 0x1E89u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0078u, 0x0307u, 0x1E8Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0078u, 0x0308u, 0x1E8Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0300u, 0x1EF3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0301u, 0x00FDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0302u, 0x0177u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0303u, 0x1EF9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0304u, 0x0233u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0307u, 0x1E8Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0308u, 0x00FFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0309u, 0x1EF7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x030Au, 0x1E99u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0323u, 0x1EF5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0301u, 0x017Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0302u, 0x1E91u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0307u, 0x017Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x030Cu, 0x017Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0323u, 0x1E93u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0331u, 0x1E95u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8u, 0x0300u, 0x1FEDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8u, 0x0301u, 0x0385u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8u, 0x0342u, 0x1FC1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2u, 0x0300u, 0x1EA6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2u, 0x0301u, 0x1EA4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2u, 0x0303u, 0x1EAAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2u, 0x0309u, 0x1EA8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00C4u, 0x0304u, 0x01DEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00C5u, 0x0301u, 0x01FAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00C6u, 0x0301u, 0x01FCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00C6u, 0x0304u, 0x01E2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00C7u, 0x0301u, 0x1E08u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00CAu, 0x0300u, 0x1EC0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00CAu, 0x0301u, 0x1EBEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00CAu, 0x0303u, 0x1EC4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00CAu, 0x0309u, 0x1EC2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00CFu, 0x0301u, 0x1E2Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4u, 0x0300u, 0x1ED2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4u, 0x0301u, 0x1ED0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4u, 0x0303u, 0x1ED6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4u, 0x0309u, 0x1ED4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5u, 0x0301u, 0x1E4Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5u, 0x0304u, 0x022Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5u, 0x0308u, 0x1E4Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00D6u, 0x0304u, 0x022Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00D8u, 0x0301u, 0x01FEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00DCu, 0x0300u, 0x01DBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00DCu, 0x0301u, 0x01D7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00DCu, 0x0304u, 0x01D5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00DCu, 0x030Cu, 0x01D9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2u, 0x0300u, 0x1EA7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2u, 0x0301u, 0x1EA5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2u, 0x0303u, 0x1EABu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2u, 0x0309u, 0x1EA9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00E4u, 0x0304u, 0x01DFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00E5u, 0x0301u, 0x01FBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00E6u, 0x0301u, 0x01FDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00E6u, 0x0304u, 0x01E3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00E7u, 0x0301u, 0x1E09u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00EAu, 0x0300u, 0x1EC1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00EAu, 0x0301u, 0x1EBFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00EAu, 0x0303u, 0x1EC5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00EAu, 0x0309u, 0x1EC3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00EFu, 0x0301u, 0x1E2Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4u, 0x0300u, 0x1ED3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4u, 0x0301u, 0x1ED1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4u, 0x0303u, 0x1ED7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4u, 0x0309u, 0x1ED5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5u, 0x0301u, 0x1E4Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5u, 0x0304u, 0x022Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5u, 0x0308u, 0x1E4Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00F6u, 0x0304u, 0x022Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00F8u, 0x0301u, 0x01FFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00FCu, 0x0300u, 0x01DCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00FCu, 0x0301u, 0x01D8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00FCu, 0x0304u, 0x01D6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00FCu, 0x030Cu, 0x01DAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0102u, 0x0300u, 0x1EB0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0102u, 0x0301u, 0x1EAEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0102u, 0x0303u, 0x1EB4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0102u, 0x0309u, 0x1EB2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0103u, 0x0300u, 0x1EB1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0103u, 0x0301u, 0x1EAFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0103u, 0x0303u, 0x1EB5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0103u, 0x0309u, 0x1EB3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0112u, 0x0300u, 0x1E14u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0112u, 0x0301u, 0x1E16u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0113u, 0x0300u, 0x1E15u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0113u, 0x0301u, 0x1E17u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x014Cu, 0x0300u, 0x1E50u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x014Cu, 0x0301u, 0x1E52u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x014Du, 0x0300u, 0x1E51u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x014Du, 0x0301u, 0x1E53u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x015Au, 0x0307u, 0x1E64u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x015Bu, 0x0307u, 0x1E65u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0160u, 0x0307u, 0x1E66u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0161u, 0x0307u, 0x1E67u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0168u, 0x0301u, 0x1E78u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0169u, 0x0301u, 0x1E79u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x016Au, 0x0308u, 0x1E7Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x016Bu, 0x0308u, 0x1E7Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x017Fu, 0x0307u, 0x1E9Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0300u, 0x1EDCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0301u, 0x1EDAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0303u, 0x1EE0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0309u, 0x1EDEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0323u, 0x1EE2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0300u, 0x1EDDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0301u, 0x1EDBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0303u, 0x1EE1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0309u, 0x1EDFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0323u, 0x1EE3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0300u, 0x1EEAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0301u, 0x1EE8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0303u, 0x1EEEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0309u, 0x1EECu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0323u, 0x1EF0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0300u, 0x1EEBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0301u, 0x1EE9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0303u, 0x1EEFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0309u, 0x1EEDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0323u, 0x1EF1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01B7u, 0x030Cu, 0x01EEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01EAu, 0x0304u, 0x01ECu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01EBu, 0x0304u, 0x01EDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0226u, 0x0304u, 0x01E0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0227u, 0x0304u, 0x01E1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0228u, 0x0306u, 0x1E1Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0229u, 0x0306u, 0x1E1Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x022Eu, 0x0304u, 0x0230u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x022Fu, 0x0304u, 0x0231u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0292u, 0x030Cu, 0x01EFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0308u, 0x0301u, 0x0000u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0300u, 0x1FBAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0301u, 0x0386u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0304u, 0x1FB9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0306u, 0x1FB8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0313u, 0x1F08u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0314u, 0x1F09u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0345u, 0x1FBCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0395u, 0x0300u, 0x1FC8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0395u, 0x0301u, 0x0388u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0395u, 0x0313u, 0x1F18u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0395u, 0x0314u, 0x1F19u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0300u, 0x1FCAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0301u, 0x0389u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0313u, 0x1F28u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0314u, 0x1F29u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0345u, 0x1FCCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0300u, 0x1FDAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0301u, 0x038Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0304u, 0x1FD9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0306u, 0x1FD8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0308u, 0x03AAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0313u, 0x1F38u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0314u, 0x1F39u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x039Fu, 0x0300u, 0x1FF8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x039Fu, 0x0301u, 0x038Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x039Fu, 0x0313u, 0x1F48u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x039Fu, 0x0314u, 0x1F49u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A1u, 0x0314u, 0x1FECu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0300u, 0x1FEAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0301u, 0x038Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0304u, 0x1FE9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0306u, 0x1FE8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0308u, 0x03ABu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0314u, 0x1F59u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0300u, 0x1FFAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0301u, 0x038Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0313u, 0x1F68u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0314u, 0x1F69u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0345u, 0x1FFCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03ACu, 0x0345u, 0x1FB4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03AEu, 0x0345u, 0x1FC4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0300u, 0x1F70u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0301u, 0x03ACu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0304u, 0x1FB1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0306u, 0x1FB0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0313u, 0x1F00u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0314u, 0x1F01u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0342u, 0x1FB6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0345u, 0x1FB3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5u, 0x0300u, 0x1F72u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5u, 0x0301u, 0x03ADu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5u, 0x0313u, 0x1F10u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5u, 0x0314u, 0x1F11u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0300u, 0x1F74u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0301u, 0x03AEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0313u, 0x1F20u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0314u, 0x1F21u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0342u, 0x1FC6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0345u, 0x1FC3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0300u, 0x1F76u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0301u, 0x03AFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0304u, 0x1FD1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0306u, 0x1FD0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0308u, 0x03CAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0313u, 0x1F30u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0314u, 0x1F31u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0342u, 0x1FD6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03BFu, 0x0300u, 0x1F78u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03BFu, 0x0301u, 0x03CCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03BFu, 0x0313u, 0x1F40u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03BFu, 0x0314u, 0x1F41u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C1u, 0x0313u, 0x1FE4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C1u, 0x0314u, 0x1FE5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0300u, 0x1F7Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0301u, 0x03CDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0304u, 0x1FE1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0306u, 0x1FE0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0308u, 0x03CBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0313u, 0x1F50u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0314u, 0x1F51u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0342u, 0x1FE6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0300u, 0x1F7Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0301u, 0x03CEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0313u, 0x1F60u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0314u, 0x1F61u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0342u, 0x1FF6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0345u, 0x1FF3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03CAu, 0x0300u, 0x1FD2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03CAu, 0x0301u, 0x0390u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03CAu, 0x0342u, 0x1FD7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03CBu, 0x0300u, 0x1FE2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03CBu, 0x0301u, 0x03B0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03CBu, 0x0342u, 0x1FE7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03CEu, 0x0345u, 0x1FF4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03D2u, 0x0301u, 0x03D3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03D2u, 0x0308u, 0x03D4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0406u, 0x0308u, 0x0407u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0410u, 0x0306u, 0x04D0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0410u, 0x0308u, 0x04D2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0413u, 0x0301u, 0x0403u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0415u, 0x0300u, 0x0400u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0415u, 0x0306u, 0x04D6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0415u, 0x0308u, 0x0401u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0416u, 0x0306u, 0x04C1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0416u, 0x0308u, 0x04DCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0417u, 0x0308u, 0x04DEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0418u, 0x0300u, 0x040Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0418u, 0x0304u, 0x04E2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0418u, 0x0306u, 0x0419u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0418u, 0x0308u, 0x04E4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x041Au, 0x0301u, 0x040Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x041Eu, 0x0308u, 0x04E6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0423u, 0x0304u, 0x04EEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0423u, 0x0306u, 0x040Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0423u, 0x0308u, 0x04F0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0423u, 0x030Bu, 0x04F2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0427u, 0x0308u, 0x04F4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x042Bu, 0x0308u, 0x04F8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x042Du, 0x0308u, 0x04ECu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0430u, 0x0306u, 0x04D1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0430u, 0x0308u, 0x04D3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0433u, 0x0301u, 0x0453u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0435u, 0x0300u, 0x0450u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0435u, 0x0306u, 0x04D7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0435u, 0x0308u, 0x0451u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0436u, 0x0306u, 0x04C2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0436u, 0x0308u, 0x04DDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0437u, 0x0308u, 0x04DFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0438u, 0x0300u, 0x045Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0438u, 0x0304u, 0x04E3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0438u, 0x0306u, 0x0439u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0438u, 0x0308u, 0x04E5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x043Au, 0x0301u, 0x045Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x043Eu, 0x0308u, 0x04E7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0443u, 0x0304u, 0x04EFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0443u, 0x0306u, 0x045Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0443u, 0x0308u, 0x04F1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0443u, 0x030Bu, 0x04F3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0447u, 0x0308u, 0x04F5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x044Bu, 0x0308u, 0x04F9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x044Du, 0x0308u, 0x04EDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0456u, 0x0308u, 0x0457u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0474u, 0x030Fu, 0x0476u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0475u, 0x030Fu, 0x0477u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x04D8u, 0x0308u, 0x04DAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x04D9u, 0x0308u, 0x04DBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x04E8u, 0x0308u, 0x04EAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x04E9u, 0x0308u, 0x04EBu), + HB_CODEPOINT_ENCODE3_11_7_14 (0x003C, 0x0338, 0x226E),HB_CODEPOINT_ENCODE3_11_7_14 (0x003D, 0x0338, 0x2260), + HB_CODEPOINT_ENCODE3_11_7_14 (0x003E, 0x0338, 0x226F),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0300, 0x00C0), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0301, 0x00C1),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0302, 0x00C2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0303, 0x00C3),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0304, 0x0100), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0306, 0x0102),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0307, 0x0226), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0308, 0x00C4),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0309, 0x1EA2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x030A, 0x00C5),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x030C, 0x01CD), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x030F, 0x0200),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0311, 0x0202), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0323, 0x1EA0),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0325, 0x1E00), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0328, 0x0104),HB_CODEPOINT_ENCODE3_11_7_14 (0x0042, 0x0307, 0x1E02), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0042, 0x0323, 0x1E04),HB_CODEPOINT_ENCODE3_11_7_14 (0x0042, 0x0331, 0x1E06), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0043, 0x0301, 0x0106),HB_CODEPOINT_ENCODE3_11_7_14 (0x0043, 0x0302, 0x0108), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0043, 0x0307, 0x010A),HB_CODEPOINT_ENCODE3_11_7_14 (0x0043, 0x030C, 0x010C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0043, 0x0327, 0x00C7),HB_CODEPOINT_ENCODE3_11_7_14 (0x0044, 0x0307, 0x1E0A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0044, 0x030C, 0x010E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0044, 0x0323, 0x1E0C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0044, 0x0327, 0x1E10),HB_CODEPOINT_ENCODE3_11_7_14 (0x0044, 0x032D, 0x1E12), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0044, 0x0331, 0x1E0E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0300, 0x00C8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0301, 0x00C9),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0302, 0x00CA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0303, 0x1EBC),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0304, 0x0112), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0306, 0x0114),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0307, 0x0116), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0308, 0x00CB),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0309, 0x1EBA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x030C, 0x011A),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x030F, 0x0204), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0311, 0x0206),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0323, 0x1EB8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0327, 0x0228),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0328, 0x0118), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x032D, 0x1E18),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0330, 0x1E1A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0046, 0x0307, 0x1E1E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0047, 0x0301, 0x01F4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0047, 0x0302, 0x011C),HB_CODEPOINT_ENCODE3_11_7_14 (0x0047, 0x0304, 0x1E20), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0047, 0x0306, 0x011E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0047, 0x0307, 0x0120), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0047, 0x030C, 0x01E6),HB_CODEPOINT_ENCODE3_11_7_14 (0x0047, 0x0327, 0x0122), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0048, 0x0302, 0x0124),HB_CODEPOINT_ENCODE3_11_7_14 (0x0048, 0x0307, 0x1E22), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0048, 0x0308, 0x1E26),HB_CODEPOINT_ENCODE3_11_7_14 (0x0048, 0x030C, 0x021E), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0048, 0x0323, 0x1E24),HB_CODEPOINT_ENCODE3_11_7_14 (0x0048, 0x0327, 0x1E28), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0048, 0x032E, 0x1E2A),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0300, 0x00CC), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0301, 0x00CD),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0302, 0x00CE), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0303, 0x0128),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0304, 0x012A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0306, 0x012C),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0307, 0x0130), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0308, 0x00CF),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0309, 0x1EC8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x030C, 0x01CF),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x030F, 0x0208), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0311, 0x020A),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0323, 0x1ECA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0328, 0x012E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0330, 0x1E2C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004A, 0x0302, 0x0134),HB_CODEPOINT_ENCODE3_11_7_14 (0x004B, 0x0301, 0x1E30), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004B, 0x030C, 0x01E8),HB_CODEPOINT_ENCODE3_11_7_14 (0x004B, 0x0323, 0x1E32), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004B, 0x0327, 0x0136),HB_CODEPOINT_ENCODE3_11_7_14 (0x004B, 0x0331, 0x1E34), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004C, 0x0301, 0x0139),HB_CODEPOINT_ENCODE3_11_7_14 (0x004C, 0x030C, 0x013D), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004C, 0x0323, 0x1E36),HB_CODEPOINT_ENCODE3_11_7_14 (0x004C, 0x0327, 0x013B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004C, 0x032D, 0x1E3C),HB_CODEPOINT_ENCODE3_11_7_14 (0x004C, 0x0331, 0x1E3A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004D, 0x0301, 0x1E3E),HB_CODEPOINT_ENCODE3_11_7_14 (0x004D, 0x0307, 0x1E40), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004D, 0x0323, 0x1E42),HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x0300, 0x01F8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x0301, 0x0143),HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x0303, 0x00D1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x0307, 0x1E44),HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x030C, 0x0147), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x0323, 0x1E46),HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x0327, 0x0145), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x032D, 0x1E4A),HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x0331, 0x1E48), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0300, 0x00D2),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0301, 0x00D3), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0302, 0x00D4),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0303, 0x00D5), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0304, 0x014C),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0306, 0x014E), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0307, 0x022E),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0308, 0x00D6), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0309, 0x1ECE),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x030B, 0x0150), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x030C, 0x01D1),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x030F, 0x020C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0311, 0x020E),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x031B, 0x01A0), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0323, 0x1ECC),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0328, 0x01EA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0050, 0x0301, 0x1E54),HB_CODEPOINT_ENCODE3_11_7_14 (0x0050, 0x0307, 0x1E56), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x0301, 0x0154),HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x0307, 0x1E58), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x030C, 0x0158),HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x030F, 0x0210), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x0311, 0x0212),HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x0323, 0x1E5A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x0327, 0x0156),HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x0331, 0x1E5E), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0053, 0x0301, 0x015A),HB_CODEPOINT_ENCODE3_11_7_14 (0x0053, 0x0302, 0x015C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0053, 0x0307, 0x1E60),HB_CODEPOINT_ENCODE3_11_7_14 (0x0053, 0x030C, 0x0160), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0053, 0x0323, 0x1E62),HB_CODEPOINT_ENCODE3_11_7_14 (0x0053, 0x0326, 0x0218), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0053, 0x0327, 0x015E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0054, 0x0307, 0x1E6A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0054, 0x030C, 0x0164),HB_CODEPOINT_ENCODE3_11_7_14 (0x0054, 0x0323, 0x1E6C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0054, 0x0326, 0x021A),HB_CODEPOINT_ENCODE3_11_7_14 (0x0054, 0x0327, 0x0162), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0054, 0x032D, 0x1E70),HB_CODEPOINT_ENCODE3_11_7_14 (0x0054, 0x0331, 0x1E6E), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0300, 0x00D9),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0301, 0x00DA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0302, 0x00DB),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0303, 0x0168), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0304, 0x016A),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0306, 0x016C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0308, 0x00DC),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0309, 0x1EE6), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x030A, 0x016E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x030B, 0x0170), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x030C, 0x01D3),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x030F, 0x0214), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0311, 0x0216),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x031B, 0x01AF), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0323, 0x1EE4),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0324, 0x1E72), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0328, 0x0172),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x032D, 0x1E76), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0330, 0x1E74),HB_CODEPOINT_ENCODE3_11_7_14 (0x0056, 0x0303, 0x1E7C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0056, 0x0323, 0x1E7E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0057, 0x0300, 0x1E80), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0057, 0x0301, 0x1E82),HB_CODEPOINT_ENCODE3_11_7_14 (0x0057, 0x0302, 0x0174), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0057, 0x0307, 0x1E86),HB_CODEPOINT_ENCODE3_11_7_14 (0x0057, 0x0308, 0x1E84), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0057, 0x0323, 0x1E88),HB_CODEPOINT_ENCODE3_11_7_14 (0x0058, 0x0307, 0x1E8A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0058, 0x0308, 0x1E8C),HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0300, 0x1EF2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0301, 0x00DD),HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0302, 0x0176), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0303, 0x1EF8),HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0304, 0x0232), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0307, 0x1E8E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0308, 0x0178), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0309, 0x1EF6),HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0323, 0x1EF4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x005A, 0x0301, 0x0179),HB_CODEPOINT_ENCODE3_11_7_14 (0x005A, 0x0302, 0x1E90), + HB_CODEPOINT_ENCODE3_11_7_14 (0x005A, 0x0307, 0x017B),HB_CODEPOINT_ENCODE3_11_7_14 (0x005A, 0x030C, 0x017D), + HB_CODEPOINT_ENCODE3_11_7_14 (0x005A, 0x0323, 0x1E92),HB_CODEPOINT_ENCODE3_11_7_14 (0x005A, 0x0331, 0x1E94), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0300, 0x00E0),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0301, 0x00E1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0302, 0x00E2),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0303, 0x00E3), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0304, 0x0101),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0306, 0x0103), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0307, 0x0227),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0308, 0x00E4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0309, 0x1EA3),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x030A, 0x00E5), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x030C, 0x01CE),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x030F, 0x0201), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0311, 0x0203),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0323, 0x1EA1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0325, 0x1E01),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0328, 0x0105), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0062, 0x0307, 0x1E03),HB_CODEPOINT_ENCODE3_11_7_14 (0x0062, 0x0323, 0x1E05), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0062, 0x0331, 0x1E07),HB_CODEPOINT_ENCODE3_11_7_14 (0x0063, 0x0301, 0x0107), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0063, 0x0302, 0x0109),HB_CODEPOINT_ENCODE3_11_7_14 (0x0063, 0x0307, 0x010B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0063, 0x030C, 0x010D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0063, 0x0327, 0x00E7), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0064, 0x0307, 0x1E0B),HB_CODEPOINT_ENCODE3_11_7_14 (0x0064, 0x030C, 0x010F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0064, 0x0323, 0x1E0D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0064, 0x0327, 0x1E11), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0064, 0x032D, 0x1E13),HB_CODEPOINT_ENCODE3_11_7_14 (0x0064, 0x0331, 0x1E0F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0300, 0x00E8),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0301, 0x00E9), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0302, 0x00EA),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0303, 0x1EBD), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0304, 0x0113),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0306, 0x0115), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0307, 0x0117),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0308, 0x00EB), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0309, 0x1EBB),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x030C, 0x011B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x030F, 0x0205),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0311, 0x0207), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0323, 0x1EB9),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0327, 0x0229), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0328, 0x0119),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x032D, 0x1E19), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0330, 0x1E1B),HB_CODEPOINT_ENCODE3_11_7_14 (0x0066, 0x0307, 0x1E1F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0067, 0x0301, 0x01F5),HB_CODEPOINT_ENCODE3_11_7_14 (0x0067, 0x0302, 0x011D), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0067, 0x0304, 0x1E21),HB_CODEPOINT_ENCODE3_11_7_14 (0x0067, 0x0306, 0x011F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0067, 0x0307, 0x0121),HB_CODEPOINT_ENCODE3_11_7_14 (0x0067, 0x030C, 0x01E7), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0067, 0x0327, 0x0123),HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x0302, 0x0125), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x0307, 0x1E23),HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x0308, 0x1E27), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x030C, 0x021F),HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x0323, 0x1E25), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x0327, 0x1E29),HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x032E, 0x1E2B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x0331, 0x1E96),HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0300, 0x00EC), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0301, 0x00ED),HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0302, 0x00EE), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0303, 0x0129),HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0304, 0x012B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0306, 0x012D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0308, 0x00EF), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0309, 0x1EC9),HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x030C, 0x01D0), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x030F, 0x0209),HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0311, 0x020B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0323, 0x1ECB),HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0328, 0x012F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0330, 0x1E2D),HB_CODEPOINT_ENCODE3_11_7_14 (0x006A, 0x0302, 0x0135), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006A, 0x030C, 0x01F0),HB_CODEPOINT_ENCODE3_11_7_14 (0x006B, 0x0301, 0x1E31), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006B, 0x030C, 0x01E9),HB_CODEPOINT_ENCODE3_11_7_14 (0x006B, 0x0323, 0x1E33), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006B, 0x0327, 0x0137),HB_CODEPOINT_ENCODE3_11_7_14 (0x006B, 0x0331, 0x1E35), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006C, 0x0301, 0x013A),HB_CODEPOINT_ENCODE3_11_7_14 (0x006C, 0x030C, 0x013E), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006C, 0x0323, 0x1E37),HB_CODEPOINT_ENCODE3_11_7_14 (0x006C, 0x0327, 0x013C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006C, 0x032D, 0x1E3D),HB_CODEPOINT_ENCODE3_11_7_14 (0x006C, 0x0331, 0x1E3B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006D, 0x0301, 0x1E3F),HB_CODEPOINT_ENCODE3_11_7_14 (0x006D, 0x0307, 0x1E41), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006D, 0x0323, 0x1E43),HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x0300, 0x01F9), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x0301, 0x0144),HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x0303, 0x00F1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x0307, 0x1E45),HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x030C, 0x0148), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x0323, 0x1E47),HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x0327, 0x0146), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x032D, 0x1E4B),HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x0331, 0x1E49), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0300, 0x00F2),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0301, 0x00F3), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0302, 0x00F4),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0303, 0x00F5), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0304, 0x014D),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0306, 0x014F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0307, 0x022F),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0308, 0x00F6), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0309, 0x1ECF),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x030B, 0x0151), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x030C, 0x01D2),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x030F, 0x020D), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0311, 0x020F),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x031B, 0x01A1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0323, 0x1ECD),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0328, 0x01EB), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0070, 0x0301, 0x1E55),HB_CODEPOINT_ENCODE3_11_7_14 (0x0070, 0x0307, 0x1E57), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x0301, 0x0155),HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x0307, 0x1E59), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x030C, 0x0159),HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x030F, 0x0211), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x0311, 0x0213),HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x0323, 0x1E5B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x0327, 0x0157),HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x0331, 0x1E5F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0073, 0x0301, 0x015B),HB_CODEPOINT_ENCODE3_11_7_14 (0x0073, 0x0302, 0x015D), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0073, 0x0307, 0x1E61),HB_CODEPOINT_ENCODE3_11_7_14 (0x0073, 0x030C, 0x0161), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0073, 0x0323, 0x1E63),HB_CODEPOINT_ENCODE3_11_7_14 (0x0073, 0x0326, 0x0219), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0073, 0x0327, 0x015F),HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x0307, 0x1E6B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x0308, 0x1E97),HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x030C, 0x0165), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x0323, 0x1E6D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x0326, 0x021B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x0327, 0x0163),HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x032D, 0x1E71), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x0331, 0x1E6F),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0300, 0x00F9), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0301, 0x00FA),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0302, 0x00FB), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0303, 0x0169),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0304, 0x016B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0306, 0x016D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0308, 0x00FC), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0309, 0x1EE7),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x030A, 0x016F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x030B, 0x0171),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x030C, 0x01D4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x030F, 0x0215),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0311, 0x0217), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x031B, 0x01B0),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0323, 0x1EE5), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0324, 0x1E73),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0328, 0x0173), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x032D, 0x1E77),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0330, 0x1E75), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0076, 0x0303, 0x1E7D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0076, 0x0323, 0x1E7F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0077, 0x0300, 0x1E81),HB_CODEPOINT_ENCODE3_11_7_14 (0x0077, 0x0301, 0x1E83), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0077, 0x0302, 0x0175),HB_CODEPOINT_ENCODE3_11_7_14 (0x0077, 0x0307, 0x1E87), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0077, 0x0308, 0x1E85),HB_CODEPOINT_ENCODE3_11_7_14 (0x0077, 0x030A, 0x1E98), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0077, 0x0323, 0x1E89),HB_CODEPOINT_ENCODE3_11_7_14 (0x0078, 0x0307, 0x1E8B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0078, 0x0308, 0x1E8D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0300, 0x1EF3), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0301, 0x00FD),HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0302, 0x0177), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0303, 0x1EF9),HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0304, 0x0233), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0307, 0x1E8F),HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0308, 0x00FF), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0309, 0x1EF7),HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x030A, 0x1E99), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0323, 0x1EF5),HB_CODEPOINT_ENCODE3_11_7_14 (0x007A, 0x0301, 0x017A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x007A, 0x0302, 0x1E91),HB_CODEPOINT_ENCODE3_11_7_14 (0x007A, 0x0307, 0x017C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x007A, 0x030C, 0x017E),HB_CODEPOINT_ENCODE3_11_7_14 (0x007A, 0x0323, 0x1E93), + HB_CODEPOINT_ENCODE3_11_7_14 (0x007A, 0x0331, 0x1E95),HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8, 0x0300, 0x1FED), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8, 0x0301, 0x0385),HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8, 0x0342, 0x1FC1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2, 0x0300, 0x1EA6),HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2, 0x0301, 0x1EA4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2, 0x0303, 0x1EAA),HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2, 0x0309, 0x1EA8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00C4, 0x0304, 0x01DE),HB_CODEPOINT_ENCODE3_11_7_14 (0x00C5, 0x0301, 0x01FA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00C6, 0x0301, 0x01FC),HB_CODEPOINT_ENCODE3_11_7_14 (0x00C6, 0x0304, 0x01E2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00C7, 0x0301, 0x1E08),HB_CODEPOINT_ENCODE3_11_7_14 (0x00CA, 0x0300, 0x1EC0), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00CA, 0x0301, 0x1EBE),HB_CODEPOINT_ENCODE3_11_7_14 (0x00CA, 0x0303, 0x1EC4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00CA, 0x0309, 0x1EC2),HB_CODEPOINT_ENCODE3_11_7_14 (0x00CF, 0x0301, 0x1E2E), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4, 0x0300, 0x1ED2),HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4, 0x0301, 0x1ED0), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4, 0x0303, 0x1ED6),HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4, 0x0309, 0x1ED4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5, 0x0301, 0x1E4C),HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5, 0x0304, 0x022C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5, 0x0308, 0x1E4E),HB_CODEPOINT_ENCODE3_11_7_14 (0x00D6, 0x0304, 0x022A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00D8, 0x0301, 0x01FE),HB_CODEPOINT_ENCODE3_11_7_14 (0x00DC, 0x0300, 0x01DB), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00DC, 0x0301, 0x01D7),HB_CODEPOINT_ENCODE3_11_7_14 (0x00DC, 0x0304, 0x01D5), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00DC, 0x030C, 0x01D9),HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2, 0x0300, 0x1EA7), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2, 0x0301, 0x1EA5),HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2, 0x0303, 0x1EAB), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2, 0x0309, 0x1EA9),HB_CODEPOINT_ENCODE3_11_7_14 (0x00E4, 0x0304, 0x01DF), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00E5, 0x0301, 0x01FB),HB_CODEPOINT_ENCODE3_11_7_14 (0x00E6, 0x0301, 0x01FD), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00E6, 0x0304, 0x01E3),HB_CODEPOINT_ENCODE3_11_7_14 (0x00E7, 0x0301, 0x1E09), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00EA, 0x0300, 0x1EC1),HB_CODEPOINT_ENCODE3_11_7_14 (0x00EA, 0x0301, 0x1EBF), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00EA, 0x0303, 0x1EC5),HB_CODEPOINT_ENCODE3_11_7_14 (0x00EA, 0x0309, 0x1EC3), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00EF, 0x0301, 0x1E2F),HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4, 0x0300, 0x1ED3), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4, 0x0301, 0x1ED1),HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4, 0x0303, 0x1ED7), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4, 0x0309, 0x1ED5),HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5, 0x0301, 0x1E4D), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5, 0x0304, 0x022D),HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5, 0x0308, 0x1E4F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00F6, 0x0304, 0x022B),HB_CODEPOINT_ENCODE3_11_7_14 (0x00F8, 0x0301, 0x01FF), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00FC, 0x0300, 0x01DC),HB_CODEPOINT_ENCODE3_11_7_14 (0x00FC, 0x0301, 0x01D8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00FC, 0x0304, 0x01D6),HB_CODEPOINT_ENCODE3_11_7_14 (0x00FC, 0x030C, 0x01DA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0102, 0x0300, 0x1EB0),HB_CODEPOINT_ENCODE3_11_7_14 (0x0102, 0x0301, 0x1EAE), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0102, 0x0303, 0x1EB4),HB_CODEPOINT_ENCODE3_11_7_14 (0x0102, 0x0309, 0x1EB2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0103, 0x0300, 0x1EB1),HB_CODEPOINT_ENCODE3_11_7_14 (0x0103, 0x0301, 0x1EAF), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0103, 0x0303, 0x1EB5),HB_CODEPOINT_ENCODE3_11_7_14 (0x0103, 0x0309, 0x1EB3), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0112, 0x0300, 0x1E14),HB_CODEPOINT_ENCODE3_11_7_14 (0x0112, 0x0301, 0x1E16), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0113, 0x0300, 0x1E15),HB_CODEPOINT_ENCODE3_11_7_14 (0x0113, 0x0301, 0x1E17), + HB_CODEPOINT_ENCODE3_11_7_14 (0x014C, 0x0300, 0x1E50),HB_CODEPOINT_ENCODE3_11_7_14 (0x014C, 0x0301, 0x1E52), + HB_CODEPOINT_ENCODE3_11_7_14 (0x014D, 0x0300, 0x1E51),HB_CODEPOINT_ENCODE3_11_7_14 (0x014D, 0x0301, 0x1E53), + HB_CODEPOINT_ENCODE3_11_7_14 (0x015A, 0x0307, 0x1E64),HB_CODEPOINT_ENCODE3_11_7_14 (0x015B, 0x0307, 0x1E65), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0160, 0x0307, 0x1E66),HB_CODEPOINT_ENCODE3_11_7_14 (0x0161, 0x0307, 0x1E67), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0168, 0x0301, 0x1E78),HB_CODEPOINT_ENCODE3_11_7_14 (0x0169, 0x0301, 0x1E79), + HB_CODEPOINT_ENCODE3_11_7_14 (0x016A, 0x0308, 0x1E7A),HB_CODEPOINT_ENCODE3_11_7_14 (0x016B, 0x0308, 0x1E7B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x017F, 0x0307, 0x1E9B),HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0, 0x0300, 0x1EDC), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0, 0x0301, 0x1EDA),HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0, 0x0303, 0x1EE0), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0, 0x0309, 0x1EDE),HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0, 0x0323, 0x1EE2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1, 0x0300, 0x1EDD),HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1, 0x0301, 0x1EDB), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1, 0x0303, 0x1EE1),HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1, 0x0309, 0x1EDF), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1, 0x0323, 0x1EE3),HB_CODEPOINT_ENCODE3_11_7_14 (0x01AF, 0x0300, 0x1EEA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01AF, 0x0301, 0x1EE8),HB_CODEPOINT_ENCODE3_11_7_14 (0x01AF, 0x0303, 0x1EEE), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01AF, 0x0309, 0x1EEC),HB_CODEPOINT_ENCODE3_11_7_14 (0x01AF, 0x0323, 0x1EF0), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0, 0x0300, 0x1EEB),HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0, 0x0301, 0x1EE9), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0, 0x0303, 0x1EEF),HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0, 0x0309, 0x1EED), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0, 0x0323, 0x1EF1),HB_CODEPOINT_ENCODE3_11_7_14 (0x01B7, 0x030C, 0x01EE), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01EA, 0x0304, 0x01EC),HB_CODEPOINT_ENCODE3_11_7_14 (0x01EB, 0x0304, 0x01ED), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0226, 0x0304, 0x01E0),HB_CODEPOINT_ENCODE3_11_7_14 (0x0227, 0x0304, 0x01E1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0228, 0x0306, 0x1E1C),HB_CODEPOINT_ENCODE3_11_7_14 (0x0229, 0x0306, 0x1E1D), + HB_CODEPOINT_ENCODE3_11_7_14 (0x022E, 0x0304, 0x0230),HB_CODEPOINT_ENCODE3_11_7_14 (0x022F, 0x0304, 0x0231), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0292, 0x030C, 0x01EF),HB_CODEPOINT_ENCODE3_11_7_14 (0x0308, 0x0301, 0x0000), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0391, 0x0300, 0x1FBA),HB_CODEPOINT_ENCODE3_11_7_14 (0x0391, 0x0301, 0x0386), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0391, 0x0304, 0x1FB9),HB_CODEPOINT_ENCODE3_11_7_14 (0x0391, 0x0306, 0x1FB8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0391, 0x0313, 0x1F08),HB_CODEPOINT_ENCODE3_11_7_14 (0x0391, 0x0314, 0x1F09), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0391, 0x0345, 0x1FBC),HB_CODEPOINT_ENCODE3_11_7_14 (0x0395, 0x0300, 0x1FC8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0395, 0x0301, 0x0388),HB_CODEPOINT_ENCODE3_11_7_14 (0x0395, 0x0313, 0x1F18), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0395, 0x0314, 0x1F19),HB_CODEPOINT_ENCODE3_11_7_14 (0x0397, 0x0300, 0x1FCA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0397, 0x0301, 0x0389),HB_CODEPOINT_ENCODE3_11_7_14 (0x0397, 0x0313, 0x1F28), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0397, 0x0314, 0x1F29),HB_CODEPOINT_ENCODE3_11_7_14 (0x0397, 0x0345, 0x1FCC), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0399, 0x0300, 0x1FDA),HB_CODEPOINT_ENCODE3_11_7_14 (0x0399, 0x0301, 0x038A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0399, 0x0304, 0x1FD9),HB_CODEPOINT_ENCODE3_11_7_14 (0x0399, 0x0306, 0x1FD8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0399, 0x0308, 0x03AA),HB_CODEPOINT_ENCODE3_11_7_14 (0x0399, 0x0313, 0x1F38), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0399, 0x0314, 0x1F39),HB_CODEPOINT_ENCODE3_11_7_14 (0x039F, 0x0300, 0x1FF8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x039F, 0x0301, 0x038C),HB_CODEPOINT_ENCODE3_11_7_14 (0x039F, 0x0313, 0x1F48), + HB_CODEPOINT_ENCODE3_11_7_14 (0x039F, 0x0314, 0x1F49),HB_CODEPOINT_ENCODE3_11_7_14 (0x03A1, 0x0314, 0x1FEC), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5, 0x0300, 0x1FEA),HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5, 0x0301, 0x038E), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5, 0x0304, 0x1FE9),HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5, 0x0306, 0x1FE8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5, 0x0308, 0x03AB),HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5, 0x0314, 0x1F59), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9, 0x0300, 0x1FFA),HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9, 0x0301, 0x038F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9, 0x0313, 0x1F68),HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9, 0x0314, 0x1F69), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9, 0x0345, 0x1FFC),HB_CODEPOINT_ENCODE3_11_7_14 (0x03AC, 0x0345, 0x1FB4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03AE, 0x0345, 0x1FC4),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0300, 0x1F70), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0301, 0x03AC),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0304, 0x1FB1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0306, 0x1FB0),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0313, 0x1F00), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0314, 0x1F01),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0342, 0x1FB6), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0345, 0x1FB3),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5, 0x0300, 0x1F72), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5, 0x0301, 0x03AD),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5, 0x0313, 0x1F10), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5, 0x0314, 0x1F11),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7, 0x0300, 0x1F74), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7, 0x0301, 0x03AE),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7, 0x0313, 0x1F20), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7, 0x0314, 0x1F21),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7, 0x0342, 0x1FC6), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7, 0x0345, 0x1FC3),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0300, 0x1F76), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0301, 0x03AF),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0304, 0x1FD1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0306, 0x1FD0),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0308, 0x03CA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0313, 0x1F30),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0314, 0x1F31), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0342, 0x1FD6),HB_CODEPOINT_ENCODE3_11_7_14 (0x03BF, 0x0300, 0x1F78), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03BF, 0x0301, 0x03CC),HB_CODEPOINT_ENCODE3_11_7_14 (0x03BF, 0x0313, 0x1F40), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03BF, 0x0314, 0x1F41),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C1, 0x0313, 0x1FE4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03C1, 0x0314, 0x1FE5),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0300, 0x1F7A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0301, 0x03CD),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0304, 0x1FE1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0306, 0x1FE0),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0308, 0x03CB), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0313, 0x1F50),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0314, 0x1F51), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0342, 0x1FE6),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9, 0x0300, 0x1F7C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9, 0x0301, 0x03CE),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9, 0x0313, 0x1F60), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9, 0x0314, 0x1F61),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9, 0x0342, 0x1FF6), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9, 0x0345, 0x1FF3),HB_CODEPOINT_ENCODE3_11_7_14 (0x03CA, 0x0300, 0x1FD2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03CA, 0x0301, 0x0390),HB_CODEPOINT_ENCODE3_11_7_14 (0x03CA, 0x0342, 0x1FD7), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03CB, 0x0300, 0x1FE2),HB_CODEPOINT_ENCODE3_11_7_14 (0x03CB, 0x0301, 0x03B0), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03CB, 0x0342, 0x1FE7),HB_CODEPOINT_ENCODE3_11_7_14 (0x03CE, 0x0345, 0x1FF4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03D2, 0x0301, 0x03D3),HB_CODEPOINT_ENCODE3_11_7_14 (0x03D2, 0x0308, 0x03D4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0406, 0x0308, 0x0407),HB_CODEPOINT_ENCODE3_11_7_14 (0x0410, 0x0306, 0x04D0), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0410, 0x0308, 0x04D2),HB_CODEPOINT_ENCODE3_11_7_14 (0x0413, 0x0301, 0x0403), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0415, 0x0300, 0x0400),HB_CODEPOINT_ENCODE3_11_7_14 (0x0415, 0x0306, 0x04D6), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0415, 0x0308, 0x0401),HB_CODEPOINT_ENCODE3_11_7_14 (0x0416, 0x0306, 0x04C1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0416, 0x0308, 0x04DC),HB_CODEPOINT_ENCODE3_11_7_14 (0x0417, 0x0308, 0x04DE), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0418, 0x0300, 0x040D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0418, 0x0304, 0x04E2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0418, 0x0306, 0x0419),HB_CODEPOINT_ENCODE3_11_7_14 (0x0418, 0x0308, 0x04E4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x041A, 0x0301, 0x040C),HB_CODEPOINT_ENCODE3_11_7_14 (0x041E, 0x0308, 0x04E6), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0423, 0x0304, 0x04EE),HB_CODEPOINT_ENCODE3_11_7_14 (0x0423, 0x0306, 0x040E), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0423, 0x0308, 0x04F0),HB_CODEPOINT_ENCODE3_11_7_14 (0x0423, 0x030B, 0x04F2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0427, 0x0308, 0x04F4),HB_CODEPOINT_ENCODE3_11_7_14 (0x042B, 0x0308, 0x04F8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x042D, 0x0308, 0x04EC),HB_CODEPOINT_ENCODE3_11_7_14 (0x0430, 0x0306, 0x04D1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0430, 0x0308, 0x04D3),HB_CODEPOINT_ENCODE3_11_7_14 (0x0433, 0x0301, 0x0453), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0435, 0x0300, 0x0450),HB_CODEPOINT_ENCODE3_11_7_14 (0x0435, 0x0306, 0x04D7), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0435, 0x0308, 0x0451),HB_CODEPOINT_ENCODE3_11_7_14 (0x0436, 0x0306, 0x04C2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0436, 0x0308, 0x04DD),HB_CODEPOINT_ENCODE3_11_7_14 (0x0437, 0x0308, 0x04DF), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0438, 0x0300, 0x045D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0438, 0x0304, 0x04E3), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0438, 0x0306, 0x0439),HB_CODEPOINT_ENCODE3_11_7_14 (0x0438, 0x0308, 0x04E5), + HB_CODEPOINT_ENCODE3_11_7_14 (0x043A, 0x0301, 0x045C),HB_CODEPOINT_ENCODE3_11_7_14 (0x043E, 0x0308, 0x04E7), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0443, 0x0304, 0x04EF),HB_CODEPOINT_ENCODE3_11_7_14 (0x0443, 0x0306, 0x045E), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0443, 0x0308, 0x04F1),HB_CODEPOINT_ENCODE3_11_7_14 (0x0443, 0x030B, 0x04F3), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0447, 0x0308, 0x04F5),HB_CODEPOINT_ENCODE3_11_7_14 (0x044B, 0x0308, 0x04F9), + HB_CODEPOINT_ENCODE3_11_7_14 (0x044D, 0x0308, 0x04ED),HB_CODEPOINT_ENCODE3_11_7_14 (0x0456, 0x0308, 0x0457), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0474, 0x030F, 0x0476),HB_CODEPOINT_ENCODE3_11_7_14 (0x0475, 0x030F, 0x0477), + HB_CODEPOINT_ENCODE3_11_7_14 (0x04D8, 0x0308, 0x04DA),HB_CODEPOINT_ENCODE3_11_7_14 (0x04D9, 0x0308, 0x04DB), + HB_CODEPOINT_ENCODE3_11_7_14 (0x04E8, 0x0308, 0x04EA),HB_CODEPOINT_ENCODE3_11_7_14 (0x04E9, 0x0308, 0x04EB), }; -static const uint64_t -_hb_ucd_dm2_u64_map[408] = +static const uint64_t _hb_ucd_dm2_u64_map[408]= { - HB_CODEPOINT_ENCODE3 (0x05D0u, 0x05B7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D0u, 0x05B8u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05D0u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D1u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05D1u, 0x05BFu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D2u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05D3u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D4u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05D5u, 0x05B9u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D5u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05D6u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D8u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05D9u, 0x05B4u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D9u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05DAu, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05DBu, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05DBu, 0x05BFu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05DCu, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05DEu, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E0u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05E1u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E3u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05E4u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E4u, 0x05BFu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05E6u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E7u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05E8u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E9u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05E9u, 0x05C1u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E9u, 0x05C2u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05EAu, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05F2u, 0x05B7u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0627u, 0x0653u, 0x0622u), HB_CODEPOINT_ENCODE3 (0x0627u, 0x0654u, 0x0623u), - HB_CODEPOINT_ENCODE3 (0x0627u, 0x0655u, 0x0625u), HB_CODEPOINT_ENCODE3 (0x0648u, 0x0654u, 0x0624u), - HB_CODEPOINT_ENCODE3 (0x064Au, 0x0654u, 0x0626u), HB_CODEPOINT_ENCODE3 (0x06C1u, 0x0654u, 0x06C2u), - HB_CODEPOINT_ENCODE3 (0x06D2u, 0x0654u, 0x06D3u), HB_CODEPOINT_ENCODE3 (0x06D5u, 0x0654u, 0x06C0u), - HB_CODEPOINT_ENCODE3 (0x0915u, 0x093Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0916u, 0x093Cu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0917u, 0x093Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x091Cu, 0x093Cu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0921u, 0x093Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0922u, 0x093Cu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0928u, 0x093Cu, 0x0929u), HB_CODEPOINT_ENCODE3 (0x092Bu, 0x093Cu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x092Fu, 0x093Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0930u, 0x093Cu, 0x0931u), - HB_CODEPOINT_ENCODE3 (0x0933u, 0x093Cu, 0x0934u), HB_CODEPOINT_ENCODE3 (0x09A1u, 0x09BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x09A2u, 0x09BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x09AFu, 0x09BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x09C7u, 0x09BEu, 0x09CBu), HB_CODEPOINT_ENCODE3 (0x09C7u, 0x09D7u, 0x09CCu), - HB_CODEPOINT_ENCODE3 (0x0A16u, 0x0A3Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0A17u, 0x0A3Cu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0A1Cu, 0x0A3Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0A2Bu, 0x0A3Cu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0A32u, 0x0A3Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0A38u, 0x0A3Cu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0B21u, 0x0B3Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0B22u, 0x0B3Cu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0B47u, 0x0B3Eu, 0x0B4Bu), HB_CODEPOINT_ENCODE3 (0x0B47u, 0x0B56u, 0x0B48u), - HB_CODEPOINT_ENCODE3 (0x0B47u, 0x0B57u, 0x0B4Cu), HB_CODEPOINT_ENCODE3 (0x0B92u, 0x0BD7u, 0x0B94u), - HB_CODEPOINT_ENCODE3 (0x0BC6u, 0x0BBEu, 0x0BCAu), HB_CODEPOINT_ENCODE3 (0x0BC6u, 0x0BD7u, 0x0BCCu), - HB_CODEPOINT_ENCODE3 (0x0BC7u, 0x0BBEu, 0x0BCBu), HB_CODEPOINT_ENCODE3 (0x0C46u, 0x0C56u, 0x0C48u), - HB_CODEPOINT_ENCODE3 (0x0CBFu, 0x0CD5u, 0x0CC0u), HB_CODEPOINT_ENCODE3 (0x0CC6u, 0x0CC2u, 0x0CCAu), - HB_CODEPOINT_ENCODE3 (0x0CC6u, 0x0CD5u, 0x0CC7u), HB_CODEPOINT_ENCODE3 (0x0CC6u, 0x0CD6u, 0x0CC8u), - HB_CODEPOINT_ENCODE3 (0x0CCAu, 0x0CD5u, 0x0CCBu), HB_CODEPOINT_ENCODE3 (0x0D46u, 0x0D3Eu, 0x0D4Au), - HB_CODEPOINT_ENCODE3 (0x0D46u, 0x0D57u, 0x0D4Cu), HB_CODEPOINT_ENCODE3 (0x0D47u, 0x0D3Eu, 0x0D4Bu), - HB_CODEPOINT_ENCODE3 (0x0DD9u, 0x0DCAu, 0x0DDAu), HB_CODEPOINT_ENCODE3 (0x0DD9u, 0x0DCFu, 0x0DDCu), - HB_CODEPOINT_ENCODE3 (0x0DD9u, 0x0DDFu, 0x0DDEu), HB_CODEPOINT_ENCODE3 (0x0DDCu, 0x0DCAu, 0x0DDDu), - HB_CODEPOINT_ENCODE3 (0x0F40u, 0x0FB5u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F42u, 0x0FB7u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0F4Cu, 0x0FB7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F51u, 0x0FB7u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0F56u, 0x0FB7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F5Bu, 0x0FB7u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0F71u, 0x0F72u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F71u, 0x0F74u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0F71u, 0x0F80u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F90u, 0x0FB5u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0F92u, 0x0FB7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F9Cu, 0x0FB7u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0FA1u, 0x0FB7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0FA6u, 0x0FB7u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0FABu, 0x0FB7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0FB2u, 0x0F80u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0FB3u, 0x0F80u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1025u, 0x102Eu, 0x1026u), - HB_CODEPOINT_ENCODE3 (0x1B05u, 0x1B35u, 0x1B06u), HB_CODEPOINT_ENCODE3 (0x1B07u, 0x1B35u, 0x1B08u), - HB_CODEPOINT_ENCODE3 (0x1B09u, 0x1B35u, 0x1B0Au), HB_CODEPOINT_ENCODE3 (0x1B0Bu, 0x1B35u, 0x1B0Cu), - HB_CODEPOINT_ENCODE3 (0x1B0Du, 0x1B35u, 0x1B0Eu), HB_CODEPOINT_ENCODE3 (0x1B11u, 0x1B35u, 0x1B12u), - HB_CODEPOINT_ENCODE3 (0x1B3Au, 0x1B35u, 0x1B3Bu), HB_CODEPOINT_ENCODE3 (0x1B3Cu, 0x1B35u, 0x1B3Du), - HB_CODEPOINT_ENCODE3 (0x1B3Eu, 0x1B35u, 0x1B40u), HB_CODEPOINT_ENCODE3 (0x1B3Fu, 0x1B35u, 0x1B41u), - HB_CODEPOINT_ENCODE3 (0x1B42u, 0x1B35u, 0x1B43u), HB_CODEPOINT_ENCODE3 (0x1E36u, 0x0304u, 0x1E38u), - HB_CODEPOINT_ENCODE3 (0x1E37u, 0x0304u, 0x1E39u), HB_CODEPOINT_ENCODE3 (0x1E5Au, 0x0304u, 0x1E5Cu), - HB_CODEPOINT_ENCODE3 (0x1E5Bu, 0x0304u, 0x1E5Du), HB_CODEPOINT_ENCODE3 (0x1E62u, 0x0307u, 0x1E68u), - HB_CODEPOINT_ENCODE3 (0x1E63u, 0x0307u, 0x1E69u), HB_CODEPOINT_ENCODE3 (0x1EA0u, 0x0302u, 0x1EACu), - HB_CODEPOINT_ENCODE3 (0x1EA0u, 0x0306u, 0x1EB6u), HB_CODEPOINT_ENCODE3 (0x1EA1u, 0x0302u, 0x1EADu), - HB_CODEPOINT_ENCODE3 (0x1EA1u, 0x0306u, 0x1EB7u), HB_CODEPOINT_ENCODE3 (0x1EB8u, 0x0302u, 0x1EC6u), - HB_CODEPOINT_ENCODE3 (0x1EB9u, 0x0302u, 0x1EC7u), HB_CODEPOINT_ENCODE3 (0x1ECCu, 0x0302u, 0x1ED8u), - HB_CODEPOINT_ENCODE3 (0x1ECDu, 0x0302u, 0x1ED9u), HB_CODEPOINT_ENCODE3 (0x1F00u, 0x0300u, 0x1F02u), - HB_CODEPOINT_ENCODE3 (0x1F00u, 0x0301u, 0x1F04u), HB_CODEPOINT_ENCODE3 (0x1F00u, 0x0342u, 0x1F06u), - HB_CODEPOINT_ENCODE3 (0x1F00u, 0x0345u, 0x1F80u), HB_CODEPOINT_ENCODE3 (0x1F01u, 0x0300u, 0x1F03u), - HB_CODEPOINT_ENCODE3 (0x1F01u, 0x0301u, 0x1F05u), HB_CODEPOINT_ENCODE3 (0x1F01u, 0x0342u, 0x1F07u), - HB_CODEPOINT_ENCODE3 (0x1F01u, 0x0345u, 0x1F81u), HB_CODEPOINT_ENCODE3 (0x1F02u, 0x0345u, 0x1F82u), - HB_CODEPOINT_ENCODE3 (0x1F03u, 0x0345u, 0x1F83u), HB_CODEPOINT_ENCODE3 (0x1F04u, 0x0345u, 0x1F84u), - HB_CODEPOINT_ENCODE3 (0x1F05u, 0x0345u, 0x1F85u), HB_CODEPOINT_ENCODE3 (0x1F06u, 0x0345u, 0x1F86u), - HB_CODEPOINT_ENCODE3 (0x1F07u, 0x0345u, 0x1F87u), HB_CODEPOINT_ENCODE3 (0x1F08u, 0x0300u, 0x1F0Au), - HB_CODEPOINT_ENCODE3 (0x1F08u, 0x0301u, 0x1F0Cu), HB_CODEPOINT_ENCODE3 (0x1F08u, 0x0342u, 0x1F0Eu), - HB_CODEPOINT_ENCODE3 (0x1F08u, 0x0345u, 0x1F88u), HB_CODEPOINT_ENCODE3 (0x1F09u, 0x0300u, 0x1F0Bu), - HB_CODEPOINT_ENCODE3 (0x1F09u, 0x0301u, 0x1F0Du), HB_CODEPOINT_ENCODE3 (0x1F09u, 0x0342u, 0x1F0Fu), - HB_CODEPOINT_ENCODE3 (0x1F09u, 0x0345u, 0x1F89u), HB_CODEPOINT_ENCODE3 (0x1F0Au, 0x0345u, 0x1F8Au), - HB_CODEPOINT_ENCODE3 (0x1F0Bu, 0x0345u, 0x1F8Bu), HB_CODEPOINT_ENCODE3 (0x1F0Cu, 0x0345u, 0x1F8Cu), - HB_CODEPOINT_ENCODE3 (0x1F0Du, 0x0345u, 0x1F8Du), HB_CODEPOINT_ENCODE3 (0x1F0Eu, 0x0345u, 0x1F8Eu), - HB_CODEPOINT_ENCODE3 (0x1F0Fu, 0x0345u, 0x1F8Fu), HB_CODEPOINT_ENCODE3 (0x1F10u, 0x0300u, 0x1F12u), - HB_CODEPOINT_ENCODE3 (0x1F10u, 0x0301u, 0x1F14u), HB_CODEPOINT_ENCODE3 (0x1F11u, 0x0300u, 0x1F13u), - HB_CODEPOINT_ENCODE3 (0x1F11u, 0x0301u, 0x1F15u), HB_CODEPOINT_ENCODE3 (0x1F18u, 0x0300u, 0x1F1Au), - HB_CODEPOINT_ENCODE3 (0x1F18u, 0x0301u, 0x1F1Cu), HB_CODEPOINT_ENCODE3 (0x1F19u, 0x0300u, 0x1F1Bu), - HB_CODEPOINT_ENCODE3 (0x1F19u, 0x0301u, 0x1F1Du), HB_CODEPOINT_ENCODE3 (0x1F20u, 0x0300u, 0x1F22u), - HB_CODEPOINT_ENCODE3 (0x1F20u, 0x0301u, 0x1F24u), HB_CODEPOINT_ENCODE3 (0x1F20u, 0x0342u, 0x1F26u), - HB_CODEPOINT_ENCODE3 (0x1F20u, 0x0345u, 0x1F90u), HB_CODEPOINT_ENCODE3 (0x1F21u, 0x0300u, 0x1F23u), - HB_CODEPOINT_ENCODE3 (0x1F21u, 0x0301u, 0x1F25u), HB_CODEPOINT_ENCODE3 (0x1F21u, 0x0342u, 0x1F27u), - HB_CODEPOINT_ENCODE3 (0x1F21u, 0x0345u, 0x1F91u), HB_CODEPOINT_ENCODE3 (0x1F22u, 0x0345u, 0x1F92u), - HB_CODEPOINT_ENCODE3 (0x1F23u, 0x0345u, 0x1F93u), HB_CODEPOINT_ENCODE3 (0x1F24u, 0x0345u, 0x1F94u), - HB_CODEPOINT_ENCODE3 (0x1F25u, 0x0345u, 0x1F95u), HB_CODEPOINT_ENCODE3 (0x1F26u, 0x0345u, 0x1F96u), - HB_CODEPOINT_ENCODE3 (0x1F27u, 0x0345u, 0x1F97u), HB_CODEPOINT_ENCODE3 (0x1F28u, 0x0300u, 0x1F2Au), - HB_CODEPOINT_ENCODE3 (0x1F28u, 0x0301u, 0x1F2Cu), HB_CODEPOINT_ENCODE3 (0x1F28u, 0x0342u, 0x1F2Eu), - HB_CODEPOINT_ENCODE3 (0x1F28u, 0x0345u, 0x1F98u), HB_CODEPOINT_ENCODE3 (0x1F29u, 0x0300u, 0x1F2Bu), - HB_CODEPOINT_ENCODE3 (0x1F29u, 0x0301u, 0x1F2Du), HB_CODEPOINT_ENCODE3 (0x1F29u, 0x0342u, 0x1F2Fu), - HB_CODEPOINT_ENCODE3 (0x1F29u, 0x0345u, 0x1F99u), HB_CODEPOINT_ENCODE3 (0x1F2Au, 0x0345u, 0x1F9Au), - HB_CODEPOINT_ENCODE3 (0x1F2Bu, 0x0345u, 0x1F9Bu), HB_CODEPOINT_ENCODE3 (0x1F2Cu, 0x0345u, 0x1F9Cu), - HB_CODEPOINT_ENCODE3 (0x1F2Du, 0x0345u, 0x1F9Du), HB_CODEPOINT_ENCODE3 (0x1F2Eu, 0x0345u, 0x1F9Eu), - HB_CODEPOINT_ENCODE3 (0x1F2Fu, 0x0345u, 0x1F9Fu), HB_CODEPOINT_ENCODE3 (0x1F30u, 0x0300u, 0x1F32u), - HB_CODEPOINT_ENCODE3 (0x1F30u, 0x0301u, 0x1F34u), HB_CODEPOINT_ENCODE3 (0x1F30u, 0x0342u, 0x1F36u), - HB_CODEPOINT_ENCODE3 (0x1F31u, 0x0300u, 0x1F33u), HB_CODEPOINT_ENCODE3 (0x1F31u, 0x0301u, 0x1F35u), - HB_CODEPOINT_ENCODE3 (0x1F31u, 0x0342u, 0x1F37u), HB_CODEPOINT_ENCODE3 (0x1F38u, 0x0300u, 0x1F3Au), - HB_CODEPOINT_ENCODE3 (0x1F38u, 0x0301u, 0x1F3Cu), HB_CODEPOINT_ENCODE3 (0x1F38u, 0x0342u, 0x1F3Eu), - HB_CODEPOINT_ENCODE3 (0x1F39u, 0x0300u, 0x1F3Bu), HB_CODEPOINT_ENCODE3 (0x1F39u, 0x0301u, 0x1F3Du), - HB_CODEPOINT_ENCODE3 (0x1F39u, 0x0342u, 0x1F3Fu), HB_CODEPOINT_ENCODE3 (0x1F40u, 0x0300u, 0x1F42u), - HB_CODEPOINT_ENCODE3 (0x1F40u, 0x0301u, 0x1F44u), HB_CODEPOINT_ENCODE3 (0x1F41u, 0x0300u, 0x1F43u), - HB_CODEPOINT_ENCODE3 (0x1F41u, 0x0301u, 0x1F45u), HB_CODEPOINT_ENCODE3 (0x1F48u, 0x0300u, 0x1F4Au), - HB_CODEPOINT_ENCODE3 (0x1F48u, 0x0301u, 0x1F4Cu), HB_CODEPOINT_ENCODE3 (0x1F49u, 0x0300u, 0x1F4Bu), - HB_CODEPOINT_ENCODE3 (0x1F49u, 0x0301u, 0x1F4Du), HB_CODEPOINT_ENCODE3 (0x1F50u, 0x0300u, 0x1F52u), - HB_CODEPOINT_ENCODE3 (0x1F50u, 0x0301u, 0x1F54u), HB_CODEPOINT_ENCODE3 (0x1F50u, 0x0342u, 0x1F56u), - HB_CODEPOINT_ENCODE3 (0x1F51u, 0x0300u, 0x1F53u), HB_CODEPOINT_ENCODE3 (0x1F51u, 0x0301u, 0x1F55u), - HB_CODEPOINT_ENCODE3 (0x1F51u, 0x0342u, 0x1F57u), HB_CODEPOINT_ENCODE3 (0x1F59u, 0x0300u, 0x1F5Bu), - HB_CODEPOINT_ENCODE3 (0x1F59u, 0x0301u, 0x1F5Du), HB_CODEPOINT_ENCODE3 (0x1F59u, 0x0342u, 0x1F5Fu), - HB_CODEPOINT_ENCODE3 (0x1F60u, 0x0300u, 0x1F62u), HB_CODEPOINT_ENCODE3 (0x1F60u, 0x0301u, 0x1F64u), - HB_CODEPOINT_ENCODE3 (0x1F60u, 0x0342u, 0x1F66u), HB_CODEPOINT_ENCODE3 (0x1F60u, 0x0345u, 0x1FA0u), - HB_CODEPOINT_ENCODE3 (0x1F61u, 0x0300u, 0x1F63u), HB_CODEPOINT_ENCODE3 (0x1F61u, 0x0301u, 0x1F65u), - HB_CODEPOINT_ENCODE3 (0x1F61u, 0x0342u, 0x1F67u), HB_CODEPOINT_ENCODE3 (0x1F61u, 0x0345u, 0x1FA1u), - HB_CODEPOINT_ENCODE3 (0x1F62u, 0x0345u, 0x1FA2u), HB_CODEPOINT_ENCODE3 (0x1F63u, 0x0345u, 0x1FA3u), - HB_CODEPOINT_ENCODE3 (0x1F64u, 0x0345u, 0x1FA4u), HB_CODEPOINT_ENCODE3 (0x1F65u, 0x0345u, 0x1FA5u), - HB_CODEPOINT_ENCODE3 (0x1F66u, 0x0345u, 0x1FA6u), HB_CODEPOINT_ENCODE3 (0x1F67u, 0x0345u, 0x1FA7u), - HB_CODEPOINT_ENCODE3 (0x1F68u, 0x0300u, 0x1F6Au), HB_CODEPOINT_ENCODE3 (0x1F68u, 0x0301u, 0x1F6Cu), - HB_CODEPOINT_ENCODE3 (0x1F68u, 0x0342u, 0x1F6Eu), HB_CODEPOINT_ENCODE3 (0x1F68u, 0x0345u, 0x1FA8u), - HB_CODEPOINT_ENCODE3 (0x1F69u, 0x0300u, 0x1F6Bu), HB_CODEPOINT_ENCODE3 (0x1F69u, 0x0301u, 0x1F6Du), - HB_CODEPOINT_ENCODE3 (0x1F69u, 0x0342u, 0x1F6Fu), HB_CODEPOINT_ENCODE3 (0x1F69u, 0x0345u, 0x1FA9u), - HB_CODEPOINT_ENCODE3 (0x1F6Au, 0x0345u, 0x1FAAu), HB_CODEPOINT_ENCODE3 (0x1F6Bu, 0x0345u, 0x1FABu), - HB_CODEPOINT_ENCODE3 (0x1F6Cu, 0x0345u, 0x1FACu), HB_CODEPOINT_ENCODE3 (0x1F6Du, 0x0345u, 0x1FADu), - HB_CODEPOINT_ENCODE3 (0x1F6Eu, 0x0345u, 0x1FAEu), HB_CODEPOINT_ENCODE3 (0x1F6Fu, 0x0345u, 0x1FAFu), - HB_CODEPOINT_ENCODE3 (0x1F70u, 0x0345u, 0x1FB2u), HB_CODEPOINT_ENCODE3 (0x1F74u, 0x0345u, 0x1FC2u), - HB_CODEPOINT_ENCODE3 (0x1F7Cu, 0x0345u, 0x1FF2u), HB_CODEPOINT_ENCODE3 (0x1FB6u, 0x0345u, 0x1FB7u), - HB_CODEPOINT_ENCODE3 (0x1FBFu, 0x0300u, 0x1FCDu), HB_CODEPOINT_ENCODE3 (0x1FBFu, 0x0301u, 0x1FCEu), - HB_CODEPOINT_ENCODE3 (0x1FBFu, 0x0342u, 0x1FCFu), HB_CODEPOINT_ENCODE3 (0x1FC6u, 0x0345u, 0x1FC7u), - HB_CODEPOINT_ENCODE3 (0x1FF6u, 0x0345u, 0x1FF7u), HB_CODEPOINT_ENCODE3 (0x1FFEu, 0x0300u, 0x1FDDu), - HB_CODEPOINT_ENCODE3 (0x1FFEu, 0x0301u, 0x1FDEu), HB_CODEPOINT_ENCODE3 (0x1FFEu, 0x0342u, 0x1FDFu), - HB_CODEPOINT_ENCODE3 (0x2190u, 0x0338u, 0x219Au), HB_CODEPOINT_ENCODE3 (0x2192u, 0x0338u, 0x219Bu), - HB_CODEPOINT_ENCODE3 (0x2194u, 0x0338u, 0x21AEu), HB_CODEPOINT_ENCODE3 (0x21D0u, 0x0338u, 0x21CDu), - HB_CODEPOINT_ENCODE3 (0x21D2u, 0x0338u, 0x21CFu), HB_CODEPOINT_ENCODE3 (0x21D4u, 0x0338u, 0x21CEu), - HB_CODEPOINT_ENCODE3 (0x2203u, 0x0338u, 0x2204u), HB_CODEPOINT_ENCODE3 (0x2208u, 0x0338u, 0x2209u), - HB_CODEPOINT_ENCODE3 (0x220Bu, 0x0338u, 0x220Cu), HB_CODEPOINT_ENCODE3 (0x2223u, 0x0338u, 0x2224u), - HB_CODEPOINT_ENCODE3 (0x2225u, 0x0338u, 0x2226u), HB_CODEPOINT_ENCODE3 (0x223Cu, 0x0338u, 0x2241u), - HB_CODEPOINT_ENCODE3 (0x2243u, 0x0338u, 0x2244u), HB_CODEPOINT_ENCODE3 (0x2245u, 0x0338u, 0x2247u), - HB_CODEPOINT_ENCODE3 (0x2248u, 0x0338u, 0x2249u), HB_CODEPOINT_ENCODE3 (0x224Du, 0x0338u, 0x226Du), - HB_CODEPOINT_ENCODE3 (0x2261u, 0x0338u, 0x2262u), HB_CODEPOINT_ENCODE3 (0x2264u, 0x0338u, 0x2270u), - HB_CODEPOINT_ENCODE3 (0x2265u, 0x0338u, 0x2271u), HB_CODEPOINT_ENCODE3 (0x2272u, 0x0338u, 0x2274u), - HB_CODEPOINT_ENCODE3 (0x2273u, 0x0338u, 0x2275u), HB_CODEPOINT_ENCODE3 (0x2276u, 0x0338u, 0x2278u), - HB_CODEPOINT_ENCODE3 (0x2277u, 0x0338u, 0x2279u), HB_CODEPOINT_ENCODE3 (0x227Au, 0x0338u, 0x2280u), - HB_CODEPOINT_ENCODE3 (0x227Bu, 0x0338u, 0x2281u), HB_CODEPOINT_ENCODE3 (0x227Cu, 0x0338u, 0x22E0u), - HB_CODEPOINT_ENCODE3 (0x227Du, 0x0338u, 0x22E1u), HB_CODEPOINT_ENCODE3 (0x2282u, 0x0338u, 0x2284u), - HB_CODEPOINT_ENCODE3 (0x2283u, 0x0338u, 0x2285u), HB_CODEPOINT_ENCODE3 (0x2286u, 0x0338u, 0x2288u), - HB_CODEPOINT_ENCODE3 (0x2287u, 0x0338u, 0x2289u), HB_CODEPOINT_ENCODE3 (0x2291u, 0x0338u, 0x22E2u), - HB_CODEPOINT_ENCODE3 (0x2292u, 0x0338u, 0x22E3u), HB_CODEPOINT_ENCODE3 (0x22A2u, 0x0338u, 0x22ACu), - HB_CODEPOINT_ENCODE3 (0x22A8u, 0x0338u, 0x22ADu), HB_CODEPOINT_ENCODE3 (0x22A9u, 0x0338u, 0x22AEu), - HB_CODEPOINT_ENCODE3 (0x22ABu, 0x0338u, 0x22AFu), HB_CODEPOINT_ENCODE3 (0x22B2u, 0x0338u, 0x22EAu), - HB_CODEPOINT_ENCODE3 (0x22B3u, 0x0338u, 0x22EBu), HB_CODEPOINT_ENCODE3 (0x22B4u, 0x0338u, 0x22ECu), - HB_CODEPOINT_ENCODE3 (0x22B5u, 0x0338u, 0x22EDu), HB_CODEPOINT_ENCODE3 (0x2ADDu, 0x0338u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x3046u, 0x3099u, 0x3094u), HB_CODEPOINT_ENCODE3 (0x304Bu, 0x3099u, 0x304Cu), - HB_CODEPOINT_ENCODE3 (0x304Du, 0x3099u, 0x304Eu), HB_CODEPOINT_ENCODE3 (0x304Fu, 0x3099u, 0x3050u), - HB_CODEPOINT_ENCODE3 (0x3051u, 0x3099u, 0x3052u), HB_CODEPOINT_ENCODE3 (0x3053u, 0x3099u, 0x3054u), - HB_CODEPOINT_ENCODE3 (0x3055u, 0x3099u, 0x3056u), HB_CODEPOINT_ENCODE3 (0x3057u, 0x3099u, 0x3058u), - HB_CODEPOINT_ENCODE3 (0x3059u, 0x3099u, 0x305Au), HB_CODEPOINT_ENCODE3 (0x305Bu, 0x3099u, 0x305Cu), - HB_CODEPOINT_ENCODE3 (0x305Du, 0x3099u, 0x305Eu), HB_CODEPOINT_ENCODE3 (0x305Fu, 0x3099u, 0x3060u), - HB_CODEPOINT_ENCODE3 (0x3061u, 0x3099u, 0x3062u), HB_CODEPOINT_ENCODE3 (0x3064u, 0x3099u, 0x3065u), - HB_CODEPOINT_ENCODE3 (0x3066u, 0x3099u, 0x3067u), HB_CODEPOINT_ENCODE3 (0x3068u, 0x3099u, 0x3069u), - HB_CODEPOINT_ENCODE3 (0x306Fu, 0x3099u, 0x3070u), HB_CODEPOINT_ENCODE3 (0x306Fu, 0x309Au, 0x3071u), - HB_CODEPOINT_ENCODE3 (0x3072u, 0x3099u, 0x3073u), HB_CODEPOINT_ENCODE3 (0x3072u, 0x309Au, 0x3074u), - HB_CODEPOINT_ENCODE3 (0x3075u, 0x3099u, 0x3076u), HB_CODEPOINT_ENCODE3 (0x3075u, 0x309Au, 0x3077u), - HB_CODEPOINT_ENCODE3 (0x3078u, 0x3099u, 0x3079u), HB_CODEPOINT_ENCODE3 (0x3078u, 0x309Au, 0x307Au), - HB_CODEPOINT_ENCODE3 (0x307Bu, 0x3099u, 0x307Cu), HB_CODEPOINT_ENCODE3 (0x307Bu, 0x309Au, 0x307Du), - HB_CODEPOINT_ENCODE3 (0x309Du, 0x3099u, 0x309Eu), HB_CODEPOINT_ENCODE3 (0x30A6u, 0x3099u, 0x30F4u), - HB_CODEPOINT_ENCODE3 (0x30ABu, 0x3099u, 0x30ACu), HB_CODEPOINT_ENCODE3 (0x30ADu, 0x3099u, 0x30AEu), - HB_CODEPOINT_ENCODE3 (0x30AFu, 0x3099u, 0x30B0u), HB_CODEPOINT_ENCODE3 (0x30B1u, 0x3099u, 0x30B2u), - HB_CODEPOINT_ENCODE3 (0x30B3u, 0x3099u, 0x30B4u), HB_CODEPOINT_ENCODE3 (0x30B5u, 0x3099u, 0x30B6u), - HB_CODEPOINT_ENCODE3 (0x30B7u, 0x3099u, 0x30B8u), HB_CODEPOINT_ENCODE3 (0x30B9u, 0x3099u, 0x30BAu), - HB_CODEPOINT_ENCODE3 (0x30BBu, 0x3099u, 0x30BCu), HB_CODEPOINT_ENCODE3 (0x30BDu, 0x3099u, 0x30BEu), - HB_CODEPOINT_ENCODE3 (0x30BFu, 0x3099u, 0x30C0u), HB_CODEPOINT_ENCODE3 (0x30C1u, 0x3099u, 0x30C2u), - HB_CODEPOINT_ENCODE3 (0x30C4u, 0x3099u, 0x30C5u), HB_CODEPOINT_ENCODE3 (0x30C6u, 0x3099u, 0x30C7u), - HB_CODEPOINT_ENCODE3 (0x30C8u, 0x3099u, 0x30C9u), HB_CODEPOINT_ENCODE3 (0x30CFu, 0x3099u, 0x30D0u), - HB_CODEPOINT_ENCODE3 (0x30CFu, 0x309Au, 0x30D1u), HB_CODEPOINT_ENCODE3 (0x30D2u, 0x3099u, 0x30D3u), - HB_CODEPOINT_ENCODE3 (0x30D2u, 0x309Au, 0x30D4u), HB_CODEPOINT_ENCODE3 (0x30D5u, 0x3099u, 0x30D6u), - HB_CODEPOINT_ENCODE3 (0x30D5u, 0x309Au, 0x30D7u), HB_CODEPOINT_ENCODE3 (0x30D8u, 0x3099u, 0x30D9u), - HB_CODEPOINT_ENCODE3 (0x30D8u, 0x309Au, 0x30DAu), HB_CODEPOINT_ENCODE3 (0x30DBu, 0x3099u, 0x30DCu), - HB_CODEPOINT_ENCODE3 (0x30DBu, 0x309Au, 0x30DDu), HB_CODEPOINT_ENCODE3 (0x30EFu, 0x3099u, 0x30F7u), - HB_CODEPOINT_ENCODE3 (0x30F0u, 0x3099u, 0x30F8u), HB_CODEPOINT_ENCODE3 (0x30F1u, 0x3099u, 0x30F9u), - HB_CODEPOINT_ENCODE3 (0x30F2u, 0x3099u, 0x30FAu), HB_CODEPOINT_ENCODE3 (0x30FDu, 0x3099u, 0x30FEu), - HB_CODEPOINT_ENCODE3 (0xFB49u, 0x05C1u, 0x0000u), HB_CODEPOINT_ENCODE3 (0xFB49u, 0x05C2u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x105D2u, 0x0307u, 0x105C9u), HB_CODEPOINT_ENCODE3 (0x105DAu, 0x0307u, 0x105E4u), - HB_CODEPOINT_ENCODE3 (0x11099u, 0x110BAu, 0x1109Au),HB_CODEPOINT_ENCODE3 (0x1109Bu, 0x110BAu, 0x1109Cu), - HB_CODEPOINT_ENCODE3 (0x110A5u, 0x110BAu, 0x110ABu),HB_CODEPOINT_ENCODE3 (0x11131u, 0x11127u, 0x1112Eu), - HB_CODEPOINT_ENCODE3 (0x11132u, 0x11127u, 0x1112Fu),HB_CODEPOINT_ENCODE3 (0x11347u, 0x1133Eu, 0x1134Bu), - HB_CODEPOINT_ENCODE3 (0x11347u, 0x11357u, 0x1134Cu),HB_CODEPOINT_ENCODE3 (0x11382u, 0x113C9u, 0x11383u), - HB_CODEPOINT_ENCODE3 (0x11384u, 0x113BBu, 0x11385u),HB_CODEPOINT_ENCODE3 (0x1138Bu, 0x113C2u, 0x1138Eu), - HB_CODEPOINT_ENCODE3 (0x11390u, 0x113C9u, 0x11391u),HB_CODEPOINT_ENCODE3 (0x113C2u, 0x113B8u, 0x113C7u), - HB_CODEPOINT_ENCODE3 (0x113C2u, 0x113C2u, 0x113C5u),HB_CODEPOINT_ENCODE3 (0x113C2u, 0x113C9u, 0x113C8u), - HB_CODEPOINT_ENCODE3 (0x114B9u, 0x114B0u, 0x114BCu),HB_CODEPOINT_ENCODE3 (0x114B9u, 0x114BAu, 0x114BBu), - HB_CODEPOINT_ENCODE3 (0x114B9u, 0x114BDu, 0x114BEu),HB_CODEPOINT_ENCODE3 (0x115B8u, 0x115AFu, 0x115BAu), - HB_CODEPOINT_ENCODE3 (0x115B9u, 0x115AFu, 0x115BBu),HB_CODEPOINT_ENCODE3 (0x11935u, 0x11930u, 0x11938u), - HB_CODEPOINT_ENCODE3 (0x1611Eu, 0x1611Eu, 0x16121u),HB_CODEPOINT_ENCODE3 (0x1611Eu, 0x1611Fu, 0x16123u), - HB_CODEPOINT_ENCODE3 (0x1611Eu, 0x16120u, 0x16125u),HB_CODEPOINT_ENCODE3 (0x1611Eu, 0x16129u, 0x16122u), - HB_CODEPOINT_ENCODE3 (0x16121u, 0x1611Fu, 0x16126u),HB_CODEPOINT_ENCODE3 (0x16121u, 0x16120u, 0x16128u), - HB_CODEPOINT_ENCODE3 (0x16122u, 0x1611Fu, 0x16127u),HB_CODEPOINT_ENCODE3 (0x16129u, 0x1611Fu, 0x16124u), - HB_CODEPOINT_ENCODE3 (0x16D63u, 0x16D67u, 0x16D69u),HB_CODEPOINT_ENCODE3 (0x16D67u, 0x16D67u, 0x16D68u), - HB_CODEPOINT_ENCODE3 (0x16D69u, 0x16D67u, 0x16D6Au), HB_CODEPOINT_ENCODE3 (0x1D157u, 0x1D165u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x1D158u, 0x1D165u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D16Eu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D16Fu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D170u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D171u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D172u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x1D1B9u, 0x1D165u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D1BAu, 0x1D165u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x1D1BBu, 0x1D16Eu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D1BBu, 0x1D16Fu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x1D1BCu, 0x1D16Eu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D1BCu, 0x1D16Fu, 0x0000u), + HB_CODEPOINT_ENCODE3 (0x05D0, 0x05B7, 0x0000), HB_CODEPOINT_ENCODE3 (0x05D0, 0x05B8, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05D0, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05D1, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05D1, 0x05BF, 0x0000), HB_CODEPOINT_ENCODE3 (0x05D2, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05D3, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05D4, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05D5, 0x05B9, 0x0000), HB_CODEPOINT_ENCODE3 (0x05D5, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05D6, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05D8, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05D9, 0x05B4, 0x0000), HB_CODEPOINT_ENCODE3 (0x05D9, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05DA, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05DB, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05DB, 0x05BF, 0x0000), HB_CODEPOINT_ENCODE3 (0x05DC, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05DE, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05E0, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05E1, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05E3, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05E4, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05E4, 0x05BF, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05E6, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05E7, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05E8, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05E9, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05E9, 0x05C1, 0x0000), HB_CODEPOINT_ENCODE3 (0x05E9, 0x05C2, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05EA, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05F2, 0x05B7, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0627, 0x0653, 0x0622), HB_CODEPOINT_ENCODE3 (0x0627, 0x0654, 0x0623), + HB_CODEPOINT_ENCODE3 (0x0627, 0x0655, 0x0625), HB_CODEPOINT_ENCODE3 (0x0648, 0x0654, 0x0624), + HB_CODEPOINT_ENCODE3 (0x064A, 0x0654, 0x0626), HB_CODEPOINT_ENCODE3 (0x06C1, 0x0654, 0x06C2), + HB_CODEPOINT_ENCODE3 (0x06D2, 0x0654, 0x06D3), HB_CODEPOINT_ENCODE3 (0x06D5, 0x0654, 0x06C0), + HB_CODEPOINT_ENCODE3 (0x0915, 0x093C, 0x0000), HB_CODEPOINT_ENCODE3 (0x0916, 0x093C, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0917, 0x093C, 0x0000), HB_CODEPOINT_ENCODE3 (0x091C, 0x093C, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0921, 0x093C, 0x0000), HB_CODEPOINT_ENCODE3 (0x0922, 0x093C, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0928, 0x093C, 0x0929), HB_CODEPOINT_ENCODE3 (0x092B, 0x093C, 0x0000), + HB_CODEPOINT_ENCODE3 (0x092F, 0x093C, 0x0000), HB_CODEPOINT_ENCODE3 (0x0930, 0x093C, 0x0931), + HB_CODEPOINT_ENCODE3 (0x0933, 0x093C, 0x0934), HB_CODEPOINT_ENCODE3 (0x09A1, 0x09BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x09A2, 0x09BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x09AF, 0x09BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x09C7, 0x09BE, 0x09CB), HB_CODEPOINT_ENCODE3 (0x09C7, 0x09D7, 0x09CC), + HB_CODEPOINT_ENCODE3 (0x0A16, 0x0A3C, 0x0000), HB_CODEPOINT_ENCODE3 (0x0A17, 0x0A3C, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0A1C, 0x0A3C, 0x0000), HB_CODEPOINT_ENCODE3 (0x0A2B, 0x0A3C, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0A32, 0x0A3C, 0x0000), HB_CODEPOINT_ENCODE3 (0x0A38, 0x0A3C, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0B21, 0x0B3C, 0x0000), HB_CODEPOINT_ENCODE3 (0x0B22, 0x0B3C, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0B47, 0x0B3E, 0x0B4B), HB_CODEPOINT_ENCODE3 (0x0B47, 0x0B56, 0x0B48), + HB_CODEPOINT_ENCODE3 (0x0B47, 0x0B57, 0x0B4C), HB_CODEPOINT_ENCODE3 (0x0B92, 0x0BD7, 0x0B94), + HB_CODEPOINT_ENCODE3 (0x0BC6, 0x0BBE, 0x0BCA), HB_CODEPOINT_ENCODE3 (0x0BC6, 0x0BD7, 0x0BCC), + HB_CODEPOINT_ENCODE3 (0x0BC7, 0x0BBE, 0x0BCB), HB_CODEPOINT_ENCODE3 (0x0C46, 0x0C56, 0x0C48), + HB_CODEPOINT_ENCODE3 (0x0CBF, 0x0CD5, 0x0CC0), HB_CODEPOINT_ENCODE3 (0x0CC6, 0x0CC2, 0x0CCA), + HB_CODEPOINT_ENCODE3 (0x0CC6, 0x0CD5, 0x0CC7), HB_CODEPOINT_ENCODE3 (0x0CC6, 0x0CD6, 0x0CC8), + HB_CODEPOINT_ENCODE3 (0x0CCA, 0x0CD5, 0x0CCB), HB_CODEPOINT_ENCODE3 (0x0D46, 0x0D3E, 0x0D4A), + HB_CODEPOINT_ENCODE3 (0x0D46, 0x0D57, 0x0D4C), HB_CODEPOINT_ENCODE3 (0x0D47, 0x0D3E, 0x0D4B), + HB_CODEPOINT_ENCODE3 (0x0DD9, 0x0DCA, 0x0DDA), HB_CODEPOINT_ENCODE3 (0x0DD9, 0x0DCF, 0x0DDC), + HB_CODEPOINT_ENCODE3 (0x0DD9, 0x0DDF, 0x0DDE), HB_CODEPOINT_ENCODE3 (0x0DDC, 0x0DCA, 0x0DDD), + HB_CODEPOINT_ENCODE3 (0x0F40, 0x0FB5, 0x0000), HB_CODEPOINT_ENCODE3 (0x0F42, 0x0FB7, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0F4C, 0x0FB7, 0x0000), HB_CODEPOINT_ENCODE3 (0x0F51, 0x0FB7, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0F56, 0x0FB7, 0x0000), HB_CODEPOINT_ENCODE3 (0x0F5B, 0x0FB7, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0F71, 0x0F72, 0x0000), HB_CODEPOINT_ENCODE3 (0x0F71, 0x0F74, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0F71, 0x0F80, 0x0000), HB_CODEPOINT_ENCODE3 (0x0F90, 0x0FB5, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0F92, 0x0FB7, 0x0000), HB_CODEPOINT_ENCODE3 (0x0F9C, 0x0FB7, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0FA1, 0x0FB7, 0x0000), HB_CODEPOINT_ENCODE3 (0x0FA6, 0x0FB7, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0FAB, 0x0FB7, 0x0000), HB_CODEPOINT_ENCODE3 (0x0FB2, 0x0F80, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0FB3, 0x0F80, 0x0000), HB_CODEPOINT_ENCODE3 (0x1025, 0x102E, 0x1026), + HB_CODEPOINT_ENCODE3 (0x1B05, 0x1B35, 0x1B06), HB_CODEPOINT_ENCODE3 (0x1B07, 0x1B35, 0x1B08), + HB_CODEPOINT_ENCODE3 (0x1B09, 0x1B35, 0x1B0A), HB_CODEPOINT_ENCODE3 (0x1B0B, 0x1B35, 0x1B0C), + HB_CODEPOINT_ENCODE3 (0x1B0D, 0x1B35, 0x1B0E), HB_CODEPOINT_ENCODE3 (0x1B11, 0x1B35, 0x1B12), + HB_CODEPOINT_ENCODE3 (0x1B3A, 0x1B35, 0x1B3B), HB_CODEPOINT_ENCODE3 (0x1B3C, 0x1B35, 0x1B3D), + HB_CODEPOINT_ENCODE3 (0x1B3E, 0x1B35, 0x1B40), HB_CODEPOINT_ENCODE3 (0x1B3F, 0x1B35, 0x1B41), + HB_CODEPOINT_ENCODE3 (0x1B42, 0x1B35, 0x1B43), HB_CODEPOINT_ENCODE3 (0x1E36, 0x0304, 0x1E38), + HB_CODEPOINT_ENCODE3 (0x1E37, 0x0304, 0x1E39), HB_CODEPOINT_ENCODE3 (0x1E5A, 0x0304, 0x1E5C), + HB_CODEPOINT_ENCODE3 (0x1E5B, 0x0304, 0x1E5D), HB_CODEPOINT_ENCODE3 (0x1E62, 0x0307, 0x1E68), + HB_CODEPOINT_ENCODE3 (0x1E63, 0x0307, 0x1E69), HB_CODEPOINT_ENCODE3 (0x1EA0, 0x0302, 0x1EAC), + HB_CODEPOINT_ENCODE3 (0x1EA0, 0x0306, 0x1EB6), HB_CODEPOINT_ENCODE3 (0x1EA1, 0x0302, 0x1EAD), + HB_CODEPOINT_ENCODE3 (0x1EA1, 0x0306, 0x1EB7), HB_CODEPOINT_ENCODE3 (0x1EB8, 0x0302, 0x1EC6), + HB_CODEPOINT_ENCODE3 (0x1EB9, 0x0302, 0x1EC7), HB_CODEPOINT_ENCODE3 (0x1ECC, 0x0302, 0x1ED8), + HB_CODEPOINT_ENCODE3 (0x1ECD, 0x0302, 0x1ED9), HB_CODEPOINT_ENCODE3 (0x1F00, 0x0300, 0x1F02), + HB_CODEPOINT_ENCODE3 (0x1F00, 0x0301, 0x1F04), HB_CODEPOINT_ENCODE3 (0x1F00, 0x0342, 0x1F06), + HB_CODEPOINT_ENCODE3 (0x1F00, 0x0345, 0x1F80), HB_CODEPOINT_ENCODE3 (0x1F01, 0x0300, 0x1F03), + HB_CODEPOINT_ENCODE3 (0x1F01, 0x0301, 0x1F05), HB_CODEPOINT_ENCODE3 (0x1F01, 0x0342, 0x1F07), + HB_CODEPOINT_ENCODE3 (0x1F01, 0x0345, 0x1F81), HB_CODEPOINT_ENCODE3 (0x1F02, 0x0345, 0x1F82), + HB_CODEPOINT_ENCODE3 (0x1F03, 0x0345, 0x1F83), HB_CODEPOINT_ENCODE3 (0x1F04, 0x0345, 0x1F84), + HB_CODEPOINT_ENCODE3 (0x1F05, 0x0345, 0x1F85), HB_CODEPOINT_ENCODE3 (0x1F06, 0x0345, 0x1F86), + HB_CODEPOINT_ENCODE3 (0x1F07, 0x0345, 0x1F87), HB_CODEPOINT_ENCODE3 (0x1F08, 0x0300, 0x1F0A), + HB_CODEPOINT_ENCODE3 (0x1F08, 0x0301, 0x1F0C), HB_CODEPOINT_ENCODE3 (0x1F08, 0x0342, 0x1F0E), + HB_CODEPOINT_ENCODE3 (0x1F08, 0x0345, 0x1F88), HB_CODEPOINT_ENCODE3 (0x1F09, 0x0300, 0x1F0B), + HB_CODEPOINT_ENCODE3 (0x1F09, 0x0301, 0x1F0D), HB_CODEPOINT_ENCODE3 (0x1F09, 0x0342, 0x1F0F), + HB_CODEPOINT_ENCODE3 (0x1F09, 0x0345, 0x1F89), HB_CODEPOINT_ENCODE3 (0x1F0A, 0x0345, 0x1F8A), + HB_CODEPOINT_ENCODE3 (0x1F0B, 0x0345, 0x1F8B), HB_CODEPOINT_ENCODE3 (0x1F0C, 0x0345, 0x1F8C), + HB_CODEPOINT_ENCODE3 (0x1F0D, 0x0345, 0x1F8D), HB_CODEPOINT_ENCODE3 (0x1F0E, 0x0345, 0x1F8E), + HB_CODEPOINT_ENCODE3 (0x1F0F, 0x0345, 0x1F8F), HB_CODEPOINT_ENCODE3 (0x1F10, 0x0300, 0x1F12), + HB_CODEPOINT_ENCODE3 (0x1F10, 0x0301, 0x1F14), HB_CODEPOINT_ENCODE3 (0x1F11, 0x0300, 0x1F13), + HB_CODEPOINT_ENCODE3 (0x1F11, 0x0301, 0x1F15), HB_CODEPOINT_ENCODE3 (0x1F18, 0x0300, 0x1F1A), + HB_CODEPOINT_ENCODE3 (0x1F18, 0x0301, 0x1F1C), HB_CODEPOINT_ENCODE3 (0x1F19, 0x0300, 0x1F1B), + HB_CODEPOINT_ENCODE3 (0x1F19, 0x0301, 0x1F1D), HB_CODEPOINT_ENCODE3 (0x1F20, 0x0300, 0x1F22), + HB_CODEPOINT_ENCODE3 (0x1F20, 0x0301, 0x1F24), HB_CODEPOINT_ENCODE3 (0x1F20, 0x0342, 0x1F26), + HB_CODEPOINT_ENCODE3 (0x1F20, 0x0345, 0x1F90), HB_CODEPOINT_ENCODE3 (0x1F21, 0x0300, 0x1F23), + HB_CODEPOINT_ENCODE3 (0x1F21, 0x0301, 0x1F25), HB_CODEPOINT_ENCODE3 (0x1F21, 0x0342, 0x1F27), + HB_CODEPOINT_ENCODE3 (0x1F21, 0x0345, 0x1F91), HB_CODEPOINT_ENCODE3 (0x1F22, 0x0345, 0x1F92), + HB_CODEPOINT_ENCODE3 (0x1F23, 0x0345, 0x1F93), HB_CODEPOINT_ENCODE3 (0x1F24, 0x0345, 0x1F94), + HB_CODEPOINT_ENCODE3 (0x1F25, 0x0345, 0x1F95), HB_CODEPOINT_ENCODE3 (0x1F26, 0x0345, 0x1F96), + HB_CODEPOINT_ENCODE3 (0x1F27, 0x0345, 0x1F97), HB_CODEPOINT_ENCODE3 (0x1F28, 0x0300, 0x1F2A), + HB_CODEPOINT_ENCODE3 (0x1F28, 0x0301, 0x1F2C), HB_CODEPOINT_ENCODE3 (0x1F28, 0x0342, 0x1F2E), + HB_CODEPOINT_ENCODE3 (0x1F28, 0x0345, 0x1F98), HB_CODEPOINT_ENCODE3 (0x1F29, 0x0300, 0x1F2B), + HB_CODEPOINT_ENCODE3 (0x1F29, 0x0301, 0x1F2D), HB_CODEPOINT_ENCODE3 (0x1F29, 0x0342, 0x1F2F), + HB_CODEPOINT_ENCODE3 (0x1F29, 0x0345, 0x1F99), HB_CODEPOINT_ENCODE3 (0x1F2A, 0x0345, 0x1F9A), + HB_CODEPOINT_ENCODE3 (0x1F2B, 0x0345, 0x1F9B), HB_CODEPOINT_ENCODE3 (0x1F2C, 0x0345, 0x1F9C), + HB_CODEPOINT_ENCODE3 (0x1F2D, 0x0345, 0x1F9D), HB_CODEPOINT_ENCODE3 (0x1F2E, 0x0345, 0x1F9E), + HB_CODEPOINT_ENCODE3 (0x1F2F, 0x0345, 0x1F9F), HB_CODEPOINT_ENCODE3 (0x1F30, 0x0300, 0x1F32), + HB_CODEPOINT_ENCODE3 (0x1F30, 0x0301, 0x1F34), HB_CODEPOINT_ENCODE3 (0x1F30, 0x0342, 0x1F36), + HB_CODEPOINT_ENCODE3 (0x1F31, 0x0300, 0x1F33), HB_CODEPOINT_ENCODE3 (0x1F31, 0x0301, 0x1F35), + HB_CODEPOINT_ENCODE3 (0x1F31, 0x0342, 0x1F37), HB_CODEPOINT_ENCODE3 (0x1F38, 0x0300, 0x1F3A), + HB_CODEPOINT_ENCODE3 (0x1F38, 0x0301, 0x1F3C), HB_CODEPOINT_ENCODE3 (0x1F38, 0x0342, 0x1F3E), + HB_CODEPOINT_ENCODE3 (0x1F39, 0x0300, 0x1F3B), HB_CODEPOINT_ENCODE3 (0x1F39, 0x0301, 0x1F3D), + HB_CODEPOINT_ENCODE3 (0x1F39, 0x0342, 0x1F3F), HB_CODEPOINT_ENCODE3 (0x1F40, 0x0300, 0x1F42), + HB_CODEPOINT_ENCODE3 (0x1F40, 0x0301, 0x1F44), HB_CODEPOINT_ENCODE3 (0x1F41, 0x0300, 0x1F43), + HB_CODEPOINT_ENCODE3 (0x1F41, 0x0301, 0x1F45), HB_CODEPOINT_ENCODE3 (0x1F48, 0x0300, 0x1F4A), + HB_CODEPOINT_ENCODE3 (0x1F48, 0x0301, 0x1F4C), HB_CODEPOINT_ENCODE3 (0x1F49, 0x0300, 0x1F4B), + HB_CODEPOINT_ENCODE3 (0x1F49, 0x0301, 0x1F4D), HB_CODEPOINT_ENCODE3 (0x1F50, 0x0300, 0x1F52), + HB_CODEPOINT_ENCODE3 (0x1F50, 0x0301, 0x1F54), HB_CODEPOINT_ENCODE3 (0x1F50, 0x0342, 0x1F56), + HB_CODEPOINT_ENCODE3 (0x1F51, 0x0300, 0x1F53), HB_CODEPOINT_ENCODE3 (0x1F51, 0x0301, 0x1F55), + HB_CODEPOINT_ENCODE3 (0x1F51, 0x0342, 0x1F57), HB_CODEPOINT_ENCODE3 (0x1F59, 0x0300, 0x1F5B), + HB_CODEPOINT_ENCODE3 (0x1F59, 0x0301, 0x1F5D), HB_CODEPOINT_ENCODE3 (0x1F59, 0x0342, 0x1F5F), + HB_CODEPOINT_ENCODE3 (0x1F60, 0x0300, 0x1F62), HB_CODEPOINT_ENCODE3 (0x1F60, 0x0301, 0x1F64), + HB_CODEPOINT_ENCODE3 (0x1F60, 0x0342, 0x1F66), HB_CODEPOINT_ENCODE3 (0x1F60, 0x0345, 0x1FA0), + HB_CODEPOINT_ENCODE3 (0x1F61, 0x0300, 0x1F63), HB_CODEPOINT_ENCODE3 (0x1F61, 0x0301, 0x1F65), + HB_CODEPOINT_ENCODE3 (0x1F61, 0x0342, 0x1F67), HB_CODEPOINT_ENCODE3 (0x1F61, 0x0345, 0x1FA1), + HB_CODEPOINT_ENCODE3 (0x1F62, 0x0345, 0x1FA2), HB_CODEPOINT_ENCODE3 (0x1F63, 0x0345, 0x1FA3), + HB_CODEPOINT_ENCODE3 (0x1F64, 0x0345, 0x1FA4), HB_CODEPOINT_ENCODE3 (0x1F65, 0x0345, 0x1FA5), + HB_CODEPOINT_ENCODE3 (0x1F66, 0x0345, 0x1FA6), HB_CODEPOINT_ENCODE3 (0x1F67, 0x0345, 0x1FA7), + HB_CODEPOINT_ENCODE3 (0x1F68, 0x0300, 0x1F6A), HB_CODEPOINT_ENCODE3 (0x1F68, 0x0301, 0x1F6C), + HB_CODEPOINT_ENCODE3 (0x1F68, 0x0342, 0x1F6E), HB_CODEPOINT_ENCODE3 (0x1F68, 0x0345, 0x1FA8), + HB_CODEPOINT_ENCODE3 (0x1F69, 0x0300, 0x1F6B), HB_CODEPOINT_ENCODE3 (0x1F69, 0x0301, 0x1F6D), + HB_CODEPOINT_ENCODE3 (0x1F69, 0x0342, 0x1F6F), HB_CODEPOINT_ENCODE3 (0x1F69, 0x0345, 0x1FA9), + HB_CODEPOINT_ENCODE3 (0x1F6A, 0x0345, 0x1FAA), HB_CODEPOINT_ENCODE3 (0x1F6B, 0x0345, 0x1FAB), + HB_CODEPOINT_ENCODE3 (0x1F6C, 0x0345, 0x1FAC), HB_CODEPOINT_ENCODE3 (0x1F6D, 0x0345, 0x1FAD), + HB_CODEPOINT_ENCODE3 (0x1F6E, 0x0345, 0x1FAE), HB_CODEPOINT_ENCODE3 (0x1F6F, 0x0345, 0x1FAF), + HB_CODEPOINT_ENCODE3 (0x1F70, 0x0345, 0x1FB2), HB_CODEPOINT_ENCODE3 (0x1F74, 0x0345, 0x1FC2), + HB_CODEPOINT_ENCODE3 (0x1F7C, 0x0345, 0x1FF2), HB_CODEPOINT_ENCODE3 (0x1FB6, 0x0345, 0x1FB7), + HB_CODEPOINT_ENCODE3 (0x1FBF, 0x0300, 0x1FCD), HB_CODEPOINT_ENCODE3 (0x1FBF, 0x0301, 0x1FCE), + HB_CODEPOINT_ENCODE3 (0x1FBF, 0x0342, 0x1FCF), HB_CODEPOINT_ENCODE3 (0x1FC6, 0x0345, 0x1FC7), + HB_CODEPOINT_ENCODE3 (0x1FF6, 0x0345, 0x1FF7), HB_CODEPOINT_ENCODE3 (0x1FFE, 0x0300, 0x1FDD), + HB_CODEPOINT_ENCODE3 (0x1FFE, 0x0301, 0x1FDE), HB_CODEPOINT_ENCODE3 (0x1FFE, 0x0342, 0x1FDF), + HB_CODEPOINT_ENCODE3 (0x2190, 0x0338, 0x219A), HB_CODEPOINT_ENCODE3 (0x2192, 0x0338, 0x219B), + HB_CODEPOINT_ENCODE3 (0x2194, 0x0338, 0x21AE), HB_CODEPOINT_ENCODE3 (0x21D0, 0x0338, 0x21CD), + HB_CODEPOINT_ENCODE3 (0x21D2, 0x0338, 0x21CF), HB_CODEPOINT_ENCODE3 (0x21D4, 0x0338, 0x21CE), + HB_CODEPOINT_ENCODE3 (0x2203, 0x0338, 0x2204), HB_CODEPOINT_ENCODE3 (0x2208, 0x0338, 0x2209), + HB_CODEPOINT_ENCODE3 (0x220B, 0x0338, 0x220C), HB_CODEPOINT_ENCODE3 (0x2223, 0x0338, 0x2224), + HB_CODEPOINT_ENCODE3 (0x2225, 0x0338, 0x2226), HB_CODEPOINT_ENCODE3 (0x223C, 0x0338, 0x2241), + HB_CODEPOINT_ENCODE3 (0x2243, 0x0338, 0x2244), HB_CODEPOINT_ENCODE3 (0x2245, 0x0338, 0x2247), + HB_CODEPOINT_ENCODE3 (0x2248, 0x0338, 0x2249), HB_CODEPOINT_ENCODE3 (0x224D, 0x0338, 0x226D), + HB_CODEPOINT_ENCODE3 (0x2261, 0x0338, 0x2262), HB_CODEPOINT_ENCODE3 (0x2264, 0x0338, 0x2270), + HB_CODEPOINT_ENCODE3 (0x2265, 0x0338, 0x2271), HB_CODEPOINT_ENCODE3 (0x2272, 0x0338, 0x2274), + HB_CODEPOINT_ENCODE3 (0x2273, 0x0338, 0x2275), HB_CODEPOINT_ENCODE3 (0x2276, 0x0338, 0x2278), + HB_CODEPOINT_ENCODE3 (0x2277, 0x0338, 0x2279), HB_CODEPOINT_ENCODE3 (0x227A, 0x0338, 0x2280), + HB_CODEPOINT_ENCODE3 (0x227B, 0x0338, 0x2281), HB_CODEPOINT_ENCODE3 (0x227C, 0x0338, 0x22E0), + HB_CODEPOINT_ENCODE3 (0x227D, 0x0338, 0x22E1), HB_CODEPOINT_ENCODE3 (0x2282, 0x0338, 0x2284), + HB_CODEPOINT_ENCODE3 (0x2283, 0x0338, 0x2285), HB_CODEPOINT_ENCODE3 (0x2286, 0x0338, 0x2288), + HB_CODEPOINT_ENCODE3 (0x2287, 0x0338, 0x2289), HB_CODEPOINT_ENCODE3 (0x2291, 0x0338, 0x22E2), + HB_CODEPOINT_ENCODE3 (0x2292, 0x0338, 0x22E3), HB_CODEPOINT_ENCODE3 (0x22A2, 0x0338, 0x22AC), + HB_CODEPOINT_ENCODE3 (0x22A8, 0x0338, 0x22AD), HB_CODEPOINT_ENCODE3 (0x22A9, 0x0338, 0x22AE), + HB_CODEPOINT_ENCODE3 (0x22AB, 0x0338, 0x22AF), HB_CODEPOINT_ENCODE3 (0x22B2, 0x0338, 0x22EA), + HB_CODEPOINT_ENCODE3 (0x22B3, 0x0338, 0x22EB), HB_CODEPOINT_ENCODE3 (0x22B4, 0x0338, 0x22EC), + HB_CODEPOINT_ENCODE3 (0x22B5, 0x0338, 0x22ED), HB_CODEPOINT_ENCODE3 (0x2ADD, 0x0338, 0x0000), + HB_CODEPOINT_ENCODE3 (0x3046, 0x3099, 0x3094), HB_CODEPOINT_ENCODE3 (0x304B, 0x3099, 0x304C), + HB_CODEPOINT_ENCODE3 (0x304D, 0x3099, 0x304E), HB_CODEPOINT_ENCODE3 (0x304F, 0x3099, 0x3050), + HB_CODEPOINT_ENCODE3 (0x3051, 0x3099, 0x3052), HB_CODEPOINT_ENCODE3 (0x3053, 0x3099, 0x3054), + HB_CODEPOINT_ENCODE3 (0x3055, 0x3099, 0x3056), HB_CODEPOINT_ENCODE3 (0x3057, 0x3099, 0x3058), + HB_CODEPOINT_ENCODE3 (0x3059, 0x3099, 0x305A), HB_CODEPOINT_ENCODE3 (0x305B, 0x3099, 0x305C), + HB_CODEPOINT_ENCODE3 (0x305D, 0x3099, 0x305E), HB_CODEPOINT_ENCODE3 (0x305F, 0x3099, 0x3060), + HB_CODEPOINT_ENCODE3 (0x3061, 0x3099, 0x3062), HB_CODEPOINT_ENCODE3 (0x3064, 0x3099, 0x3065), + HB_CODEPOINT_ENCODE3 (0x3066, 0x3099, 0x3067), HB_CODEPOINT_ENCODE3 (0x3068, 0x3099, 0x3069), + HB_CODEPOINT_ENCODE3 (0x306F, 0x3099, 0x3070), HB_CODEPOINT_ENCODE3 (0x306F, 0x309A, 0x3071), + HB_CODEPOINT_ENCODE3 (0x3072, 0x3099, 0x3073), HB_CODEPOINT_ENCODE3 (0x3072, 0x309A, 0x3074), + HB_CODEPOINT_ENCODE3 (0x3075, 0x3099, 0x3076), HB_CODEPOINT_ENCODE3 (0x3075, 0x309A, 0x3077), + HB_CODEPOINT_ENCODE3 (0x3078, 0x3099, 0x3079), HB_CODEPOINT_ENCODE3 (0x3078, 0x309A, 0x307A), + HB_CODEPOINT_ENCODE3 (0x307B, 0x3099, 0x307C), HB_CODEPOINT_ENCODE3 (0x307B, 0x309A, 0x307D), + HB_CODEPOINT_ENCODE3 (0x309D, 0x3099, 0x309E), HB_CODEPOINT_ENCODE3 (0x30A6, 0x3099, 0x30F4), + HB_CODEPOINT_ENCODE3 (0x30AB, 0x3099, 0x30AC), HB_CODEPOINT_ENCODE3 (0x30AD, 0x3099, 0x30AE), + HB_CODEPOINT_ENCODE3 (0x30AF, 0x3099, 0x30B0), HB_CODEPOINT_ENCODE3 (0x30B1, 0x3099, 0x30B2), + HB_CODEPOINT_ENCODE3 (0x30B3, 0x3099, 0x30B4), HB_CODEPOINT_ENCODE3 (0x30B5, 0x3099, 0x30B6), + HB_CODEPOINT_ENCODE3 (0x30B7, 0x3099, 0x30B8), HB_CODEPOINT_ENCODE3 (0x30B9, 0x3099, 0x30BA), + HB_CODEPOINT_ENCODE3 (0x30BB, 0x3099, 0x30BC), HB_CODEPOINT_ENCODE3 (0x30BD, 0x3099, 0x30BE), + HB_CODEPOINT_ENCODE3 (0x30BF, 0x3099, 0x30C0), HB_CODEPOINT_ENCODE3 (0x30C1, 0x3099, 0x30C2), + HB_CODEPOINT_ENCODE3 (0x30C4, 0x3099, 0x30C5), HB_CODEPOINT_ENCODE3 (0x30C6, 0x3099, 0x30C7), + HB_CODEPOINT_ENCODE3 (0x30C8, 0x3099, 0x30C9), HB_CODEPOINT_ENCODE3 (0x30CF, 0x3099, 0x30D0), + HB_CODEPOINT_ENCODE3 (0x30CF, 0x309A, 0x30D1), HB_CODEPOINT_ENCODE3 (0x30D2, 0x3099, 0x30D3), + HB_CODEPOINT_ENCODE3 (0x30D2, 0x309A, 0x30D4), HB_CODEPOINT_ENCODE3 (0x30D5, 0x3099, 0x30D6), + HB_CODEPOINT_ENCODE3 (0x30D5, 0x309A, 0x30D7), HB_CODEPOINT_ENCODE3 (0x30D8, 0x3099, 0x30D9), + HB_CODEPOINT_ENCODE3 (0x30D8, 0x309A, 0x30DA), HB_CODEPOINT_ENCODE3 (0x30DB, 0x3099, 0x30DC), + HB_CODEPOINT_ENCODE3 (0x30DB, 0x309A, 0x30DD), HB_CODEPOINT_ENCODE3 (0x30EF, 0x3099, 0x30F7), + HB_CODEPOINT_ENCODE3 (0x30F0, 0x3099, 0x30F8), HB_CODEPOINT_ENCODE3 (0x30F1, 0x3099, 0x30F9), + HB_CODEPOINT_ENCODE3 (0x30F2, 0x3099, 0x30FA), HB_CODEPOINT_ENCODE3 (0x30FD, 0x3099, 0x30FE), + HB_CODEPOINT_ENCODE3 (0xFB49, 0x05C1, 0x0000), HB_CODEPOINT_ENCODE3 (0xFB49, 0x05C2, 0x0000), + HB_CODEPOINT_ENCODE3 (0x105D2, 0x0307, 0x105C9), HB_CODEPOINT_ENCODE3 (0x105DA, 0x0307, 0x105E4), + HB_CODEPOINT_ENCODE3 (0x11099, 0x110BA, 0x1109A),HB_CODEPOINT_ENCODE3 (0x1109B, 0x110BA, 0x1109C), + HB_CODEPOINT_ENCODE3 (0x110A5, 0x110BA, 0x110AB),HB_CODEPOINT_ENCODE3 (0x11131, 0x11127, 0x1112E), + HB_CODEPOINT_ENCODE3 (0x11132, 0x11127, 0x1112F),HB_CODEPOINT_ENCODE3 (0x11347, 0x1133E, 0x1134B), + HB_CODEPOINT_ENCODE3 (0x11347, 0x11357, 0x1134C),HB_CODEPOINT_ENCODE3 (0x11382, 0x113C9, 0x11383), + HB_CODEPOINT_ENCODE3 (0x11384, 0x113BB, 0x11385),HB_CODEPOINT_ENCODE3 (0x1138B, 0x113C2, 0x1138E), + HB_CODEPOINT_ENCODE3 (0x11390, 0x113C9, 0x11391),HB_CODEPOINT_ENCODE3 (0x113C2, 0x113B8, 0x113C7), + HB_CODEPOINT_ENCODE3 (0x113C2, 0x113C2, 0x113C5),HB_CODEPOINT_ENCODE3 (0x113C2, 0x113C9, 0x113C8), + HB_CODEPOINT_ENCODE3 (0x114B9, 0x114B0, 0x114BC),HB_CODEPOINT_ENCODE3 (0x114B9, 0x114BA, 0x114BB), + HB_CODEPOINT_ENCODE3 (0x114B9, 0x114BD, 0x114BE),HB_CODEPOINT_ENCODE3 (0x115B8, 0x115AF, 0x115BA), + HB_CODEPOINT_ENCODE3 (0x115B9, 0x115AF, 0x115BB),HB_CODEPOINT_ENCODE3 (0x11935, 0x11930, 0x11938), + HB_CODEPOINT_ENCODE3 (0x1611E, 0x1611E, 0x16121),HB_CODEPOINT_ENCODE3 (0x1611E, 0x1611F, 0x16123), + HB_CODEPOINT_ENCODE3 (0x1611E, 0x16120, 0x16125),HB_CODEPOINT_ENCODE3 (0x1611E, 0x16129, 0x16122), + HB_CODEPOINT_ENCODE3 (0x16121, 0x1611F, 0x16126),HB_CODEPOINT_ENCODE3 (0x16121, 0x16120, 0x16128), + HB_CODEPOINT_ENCODE3 (0x16122, 0x1611F, 0x16127),HB_CODEPOINT_ENCODE3 (0x16129, 0x1611F, 0x16124), + HB_CODEPOINT_ENCODE3 (0x16D63, 0x16D67, 0x16D69),HB_CODEPOINT_ENCODE3 (0x16D67, 0x16D67, 0x16D68), + HB_CODEPOINT_ENCODE3 (0x16D69, 0x16D67, 0x16D6A), HB_CODEPOINT_ENCODE3 (0x1D157, 0x1D165, 0x0000), + HB_CODEPOINT_ENCODE3 (0x1D158, 0x1D165, 0x0000), HB_CODEPOINT_ENCODE3 (0x1D15F, 0x1D16E, 0x0000), + HB_CODEPOINT_ENCODE3 (0x1D15F, 0x1D16F, 0x0000), HB_CODEPOINT_ENCODE3 (0x1D15F, 0x1D170, 0x0000), + HB_CODEPOINT_ENCODE3 (0x1D15F, 0x1D171, 0x0000), HB_CODEPOINT_ENCODE3 (0x1D15F, 0x1D172, 0x0000), + HB_CODEPOINT_ENCODE3 (0x1D1B9, 0x1D165, 0x0000), HB_CODEPOINT_ENCODE3 (0x1D1BA, 0x1D165, 0x0000), + HB_CODEPOINT_ENCODE3 (0x1D1BB, 0x1D16E, 0x0000), HB_CODEPOINT_ENCODE3 (0x1D1BB, 0x1D16F, 0x0000), + HB_CODEPOINT_ENCODE3 (0x1D1BC, 0x1D16E, 0x0000), HB_CODEPOINT_ENCODE3 (0x1D1BC, 0x1D16F, 0x0000), }; #ifndef HB_OPTIMIZE_SIZE -static const uint8_t -_hb_ucd_u8[17612] = +#include + +static const uint8_t _hb_ucd_u8[19868]= { - 0, 1, 2, 3, 4, 5, 5, 5, 5, 5, 6, 5, 5, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 5, 17, 15, 18, 19, 20, 21, 22, 23, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 25, 26, 5, 27, 28, - 5, 29, 30, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 31, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 32, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 33, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 17, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 33, 41, 42, 43, 44, 45, - 46, 47, 48, 39, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 49, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 50, 17, 17, 17, 51, 17, 52, 53, 54, 55, 56, 57, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 58, 59, 59, 59, 59, 59, 59, 59, 59, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 17, 61, 62, 17, 63, 64, 65, - 66, 67, 68, 69, 70, 71, 17, 72, 73, 74, 75, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 17, 17, 17, 97, 98, 99,100,100,100,100,100,100,100,100,100,101, - 17, 17, 17, 17,102, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17,103, 17, 17,104,100,100,100,100,100,100,100,100,100, - 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, - 100,105,100,100,100,100,100,100, 17, 17,106,107,100,108,109,110, - 17, 17, 17, 17, 17, 17, 17,111, 17, 17, 17, 17,112,113,100,100, - 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,114, - 17,115,116,100,100,100,100,100,100,100,100,100,117,100,100,100, - 100,100,100,100,100,100,100,100,100,100,100,100,118, 39,119,120, - 121,122,123,124,125,126,127,128, 39, 39,129,100,100,100,100,130, - 131,132,133,100,134,135,100,136,137,138,100,100,139,140,141,100, - 142,143,144,145, 39, 39,146,147,148, 39,149,150,100,100,100,100, - 17, 17, 17, 17, 17, 17,151, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17,152,153, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,154, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,155, 17, 17,156,100, - 100,100,100,100,100,100,100,100, 17, 17,157,100,100,100,100,100, - 17, 17, 17,158, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17,159,100,100,100,100,100,100,100,100,100,100,100,100, - 160,161,100,100,100,100,100,100,100,100,100,100,100,100,100,100, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,162, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,163, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 27, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 28, 26, 29, 30, 31, 32, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 33, 34, 34, 34, 34, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 26, 56, 57, 58, 58, 58, 58, 59, 26, 26, 60, 26, 26, 26, 26, 26, + 26, 61, 26, 62, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 63, 58, 58, 58, 26, 64, 65, 66, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 67, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 68, 69, 70, 58, 58, 58, 58, 71, 58, + 58, 58, 58, 58, 58, 58, 72, 73, 74, 75, 76, 77, 78, 79, 58, 80, + 81, 82, 83, 84, 85, 58, 86, 87, 88, 89, 78, 90, 91, 92, 58, 58, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 93, 26, 26, 26, 26, 26, 26, 26, 26, 94, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 95, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 96, 26, 97, 58, 58, 58, 58, 26, 98, 58, 58, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 99, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,100, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 101, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,102, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,103, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2, 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, @@ -1148,496 +914,529 @@ _hb_ucd_u8[17612] = 34, 11, 34, 34, 32, 35, 32, 16, 36, 36, 37, 34, 38, 37, 34, 34, 34, 34, 34, 34, 34, 34, 16, 32, 34, 38, 32, 11, 32, 32, 32, 32, 32, 32, 16, 16, 16, 11, 34, 32, 34, 34, 11, 32, 32, 32, 32, 32, - 16, 16, 39, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 41, 41, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, - 40, 40, 42, 41, 41, 41, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, - 43, 43, 43, 43, 43, 43, 43, 43, 32, 32, 42, 32, 44, 45, 16, 10, - 44, 44, 41, 46, 11, 47, 47, 11, 34, 11, 11, 11, 11, 11, 11, 11, - 11, 48, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34, - 16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 49, 34, 32, 34, 11, - 32, 50, 43, 43, 51, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16, - 48, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 47, 52, 2, 2, 2, - 16, 16, 16, 16, 53, 54, 55, 56, 57, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 58, 59, 60, 43, 59, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 62, - 36, 63, 64, 44, 44, 44, 44, 44, 65, 65, 65, 8, 9, 66, 2, 67, - 43, 43, 43, 43, 43, 60, 68, 2, 69, 36, 36, 36, 36, 70, 43, 43, - 7, 7, 7, 7, 7, 2, 2, 36, 71, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 72, 43, 43, 43, 73, 50, 43, 43, 74, 75, 76, 43, 43, 36, - 7, 7, 7, 7, 7, 36, 77, 78, 2, 2, 2, 2, 2, 2, 2, 79, - 70, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 80, 62, 36, - 36, 36, 36, 43, 43, 43, 43, 43, 71, 44, 44, 44, 44, 44, 44, 44, - 7, 7, 7, 7, 7, 36, 36, 36, 36, 36, 36, 36, 36, 70, 43, 43, - 43, 43, 40, 21, 2, 81, 57, 20, 36, 36, 36, 43, 43, 75, 43, 43, - 43, 43, 75, 43, 75, 43, 43, 44, 2, 2, 2, 2, 2, 2, 2, 64, - 36, 36, 36, 36, 70, 43, 44, 64, 36, 36, 36, 36, 36, 61, 44, 44, - 36, 36, 36, 36, 82, 36, 36, 61, 65, 44, 44, 57, 43, 43, 43, 43, - 36, 36, 36, 36, 83, 43, 43, 43, 43, 84, 43, 43, 43, 43, 43, 43, - 43, 85, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 85, 71, 86, - 87, 43, 43, 43, 85, 86, 87, 86, 70, 43, 43, 43, 36, 36, 36, 36, - 36, 43, 2, 7, 7, 7, 7, 7, 88, 36, 36, 36, 36, 36, 36, 36, - 70, 86, 62, 36, 36, 36, 61, 62, 61, 62, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 61, 36, 36, 36, 61, 61, 44, 36, 36, 44, 71, 86, - 87, 43, 80, 89, 90, 89, 87, 61, 44, 44, 44, 89, 44, 44, 36, 62, - 36, 43, 44, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 56, 63, 80, - 57, 85, 62, 36, 36, 61, 44, 62, 61, 36, 62, 61, 36, 44, 80, 86, - 87, 80, 44, 57, 80, 57, 43, 44, 57, 44, 44, 44, 62, 36, 61, 61, - 44, 44, 44, 7, 7, 7, 7, 7, 43, 36, 70, 64, 44, 44, 44, 44, - 57, 85, 62, 36, 36, 36, 36, 62, 36, 62, 36, 36, 36, 36, 36, 36, - 61, 36, 62, 36, 36, 44, 71, 86, 87, 43, 43, 57, 85, 89, 87, 44, - 61, 44, 44, 44, 44, 44, 44, 44, 66, 44, 44, 44, 62, 43, 43, 43, - 57, 86, 62, 36, 36, 36, 61, 62, 61, 36, 62, 36, 36, 44, 71, 87, - 87, 43, 80, 89, 90, 89, 87, 44, 44, 44, 57, 85, 44, 44, 36, 62, - 78, 27, 27, 27, 44, 44, 44, 44, 44, 71, 62, 36, 36, 61, 44, 36, - 61, 36, 36, 44, 62, 61, 61, 36, 44, 62, 61, 44, 36, 61, 44, 36, - 36, 36, 36, 36, 36, 44, 44, 86, 85, 90, 44, 86, 90, 86, 87, 44, - 61, 44, 44, 89, 44, 44, 44, 44, 27, 91, 67, 67, 56, 92, 44, 44, - 85, 86, 71, 36, 36, 36, 61, 36, 61, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 44, 71, 43, 85, 86, 90, 43, 80, 43, 43, 44, - 44, 44, 57, 80, 36, 61, 62, 44, 44, 44, 44, 93, 27, 27, 27, 91, - 70, 86, 72, 36, 36, 36, 61, 36, 36, 36, 62, 36, 36, 44, 71, 87, - 86, 86, 90, 85, 90, 86, 43, 44, 44, 44, 89, 90, 44, 44, 62, 61, - 62, 94, 44, 44, 44, 44, 44, 44, 43, 86, 36, 36, 36, 36, 61, 36, - 36, 36, 36, 36, 36, 70, 71, 86, 87, 43, 80, 86, 90, 86, 87, 77, - 44, 44, 36, 94, 27, 27, 27, 95, 27, 27, 27, 27, 91, 36, 36, 36, - 57, 86, 62, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 36, 36, 36, - 36, 62, 36, 36, 36, 36, 62, 44, 36, 36, 36, 61, 44, 80, 44, 89, - 86, 43, 80, 80, 86, 86, 86, 86, 44, 86, 64, 44, 44, 44, 44, 44, - 62, 36, 36, 36, 36, 36, 36, 36, 70, 36, 43, 43, 43, 80, 44, 96, - 36, 36, 36, 75, 43, 43, 43, 60, 7, 7, 7, 7, 7, 2, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 62, 61, 61, 36, 36, 61, 36, 36, - 36, 36, 62, 62, 36, 36, 36, 36, 70, 36, 43, 43, 43, 43, 71, 44, - 36, 36, 61, 81, 43, 43, 43, 80, 7, 7, 7, 7, 7, 44, 36, 36, - 77, 67, 2, 2, 2, 2, 2, 2, 2, 97, 97, 67, 43, 67, 67, 67, - 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 50, 50, 50, 4, 4, 86, - 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, - 57, 43, 43, 43, 43, 43, 43, 85, 43, 43, 60, 43, 36, 36, 70, 43, - 43, 43, 43, 43, 57, 43, 43, 43, 43, 43, 43, 43, 43, 43, 80, 67, - 67, 67, 67, 76, 67, 67, 92, 67, 2, 2, 97, 67, 21, 64, 44, 44, - 36, 36, 36, 36, 36, 94, 87, 43, 85, 43, 43, 43, 87, 85, 87, 71, - 7, 7, 7, 7, 7, 2, 2, 2, 36, 36, 36, 86, 43, 36, 36, 43, - 71, 86, 98, 94, 86, 86, 86, 36, 70, 43, 71, 36, 36, 36, 36, 36, - 36, 85, 87, 85, 86, 86, 87, 94, 7, 7, 7, 7, 7, 86, 87, 67, - 11, 11, 11, 48, 44, 44, 48, 44, 16, 16, 16, 16, 16, 53, 45, 16, - 36, 36, 36, 36, 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44, - 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44, 36, 36, 36, 36, - 36, 36, 36, 61, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 57, 43, - 2, 2, 2, 2, 99, 27, 27, 27, 27, 27, 27, 27, 27, 27,100, 44, - 67, 67, 67, 67, 67, 44, 44, 44, 11, 11, 11, 44, 16, 16, 16, 44, - 101, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 77, 72, - 102, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,103,104, 44, - 36, 36, 36, 36, 36, 63, 2,105,106, 36, 36, 36, 61, 44, 44, 44, - 36, 43, 85, 44, 44, 44, 44, 62, 36, 43,107, 64, 44, 44, 44, 44, - 36, 43, 44, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 61, 36, - 61, 43, 44, 44, 44, 44, 44, 44, 36, 36, 43, 87, 43, 43, 43, 86, - 86, 86, 86, 85, 87, 43, 43, 43, 43, 43, 2, 88, 2, 66, 70, 44, - 7, 7, 7, 7, 7, 44, 44, 44, 27, 27, 27, 27, 27, 44, 44, 44, - 2, 2, 2,108, 2, 59, 43, 84, 36, 83, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 61, 44, 44, 44, 36, 36, 70, 71, 36, 36, 36, 36, - 36, 36, 36, 36, 70, 61, 44, 44, 36, 36, 36, 44, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 36, 36, 61, 43, 85, 86, 87, 85, 86, 44, 44, - 86, 85, 86, 86, 87, 43, 44, 44, 92, 44, 2, 7, 7, 7, 7, 7, - 36, 36, 36, 36, 36, 36, 36, 44, 36, 36, 61, 44, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 36, 44, 44, 36, 36, 36, 36, 36, 44, 44, 44, - 7, 7, 7, 7, 7,100, 44, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 36, 36, 36, 70, 85, 87, 44, 2, 36, 36, 94, 85, 43, 43, 43, 80, - 85, 85, 87, 43, 43, 43, 85, 86, 86, 87, 43, 43, 43, 43, 80, 57, - 2, 2, 2, 88, 2, 2, 2, 44, 43, 43, 43, 43, 43, 43, 43,109, - 43, 43, 43, 43, 43, 43, 43, 80, 43, 43, 98, 36, 36, 36, 36, 36, - 36, 36, 85, 43, 43, 85, 85, 86, 86, 85, 98, 36, 36, 36, 61, 2, - 97, 67, 67, 67, 67, 50, 43, 43, 43, 43, 67, 67, 67, 67, 21, 2, - 43, 98, 36, 36, 36, 36, 36, 36, 94, 43, 43, 86, 43, 87, 43, 36, - 36, 36, 36, 85, 43, 86, 87, 87, 43, 86, 44, 44, 44, 44, 2, 2, - 36, 36, 86, 86, 86, 86, 43, 43, 43, 43, 86, 43, 44, 93, 2, 2, - 7, 7, 7, 7, 7, 44, 62, 36, 36, 36, 36, 36, 40, 40, 40, 2, - 16, 16, 16, 16, 34,110, 44, 44, 11, 11, 11, 11, 11, 47, 48, 11, - 2, 2, 2, 2, 44, 44, 44, 44, 43, 60, 43, 43, 43, 43, 43, 43, - 85, 43, 43, 43, 71, 36, 70, 36, 36, 36, 71, 94, 43, 61, 44, 44, - 16, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 45, 16, 16, - 16, 16, 16, 16, 45, 16, 16, 16, 16, 16, 16, 16, 16,111, 40, 40, - 32, 32, 32, 16, 16, 16, 16, 32, 16, 16, 16, 16, 11, 11, 11, 11, - 16, 16, 16, 44, 11, 11, 11, 44, 16, 16, 16, 16, 48, 48, 48, 48, - 16, 16, 16, 16, 16, 16, 16, 44, 16, 16, 16, 16,112,112,112,112, - 16, 16,110, 16, 11, 11,113,114, 41, 16,110, 16, 11, 11,113, 41, - 16, 16, 44, 16, 11, 11,115, 41, 16, 16, 16, 16, 11, 11,116, 41, - 44, 16,110, 16, 11, 11,113,117,118,118,118,118,118,119, 65, 65, - 120,120,120, 2,121,122,121,122, 2, 2, 2, 2,123, 65, 65,124, - 2, 2, 2, 2,125,126, 2,127,128, 2,129,130, 2, 2, 2, 2, - 2, 9,128, 2, 2, 2, 2,131, 65, 65,132, 65, 65, 65, 65, 65, - 133, 44, 27, 27, 27, 8,129,134, 27, 27, 27, 27, 27, 8,129,104, - 40, 40, 40, 40, 40, 40, 81, 44, 20, 20, 20, 20, 20, 20, 20, 20, - 135, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43,136, 51, - 109, 51,109, 43, 43, 43, 43, 43, 80, 44, 44, 44, 44, 44, 44, 44, - 67,137, 67,138, 67, 34, 11, 16, 11, 32,138, 67, 49, 11, 11, 67, - 67, 67,137,137,137, 11, 11,139, 11, 11, 35, 36, 39, 67, 16, 11, - 8, 8, 49, 16, 16, 26, 67,140, 27, 27, 27, 27, 27, 27, 27, 27, - 105,105,105,105,105,105,105,105,105,141,142,105,143, 67, 44, 44, - 8, 8,144, 67, 67, 8, 67, 67,144, 26, 67,144, 67, 67, 67,144, - 67, 67, 67, 67, 67, 67, 67, 8, 67,144,144, 67, 67, 67, 67, 67, - 67, 67, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 67, 67, 67, 67, 4, 4, 67, 67, 8, 67, 67, 67,145,146, 67, 67, - 67, 67, 67, 67, 67, 67,144, 67, 67, 67, 67, 67, 67, 26, 8, 8, - 8, 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8, - 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 92, 44, 44, - 27, 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, - 67, 67, 67, 26, 67, 67, 67, 67, 26, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 8, 8, 8, 8, 67, 67, 67, 67, 67, 67, 67, 26, - 67, 67, 67, 67, 4, 4, 4, 4, 4, 4, 4, 27, 27, 27, 27, 27, - 27, 27, 67, 67, 67, 67, 67, 67, 8, 8,129,147, 8, 8, 8, 8, - 8, 8, 8, 4, 4, 4, 4, 4, 8,129,148,148,148,148,148,148, - 148,148,148,148,147, 8, 8, 8, 8, 8, 8, 8, 4, 4, 8, 8, - 8, 8, 8, 8, 8, 8, 4, 8, 8, 8,144, 26, 8, 8,144, 67, - 67, 67, 44, 67, 67, 67, 67, 67, 67, 67, 67, 55, 67, 67, 67, 67, - 32, 11, 32, 34, 34, 34, 34, 11, 32, 32, 34, 16, 16, 16, 40, 11, - 32, 32,140, 67, 67,138, 34,149, 43, 32, 44, 44, 93, 2, 99, 2, - 16, 16, 16,150, 44, 44,150, 44, 36, 36, 36, 36, 44, 44, 44, 52, - 64, 44, 44, 44, 44, 44, 44, 57, 36, 36, 36, 61, 44, 44, 44, 44, - 36, 36, 36, 61, 36, 36, 36, 61, 2,121,121, 2,125,126,121, 2, - 2, 2, 2, 6, 2,108,121, 2,121, 4, 4, 4, 4, 2, 2, 88, - 2, 2, 2, 2, 2,120, 2, 2,108,151, 2, 2, 2, 2, 2, 2, - 67, 2,152,148,148,148,153, 44, 67, 67, 67, 67, 67, 55, 67, 67, - 67, 67, 44, 44, 44, 44, 44, 44, 67, 67, 67, 44, 44, 44, 44, 44, - 1, 2,154,155, 4, 4, 4, 4, 4, 67, 4, 4, 4, 4,156,157, - 158,105,105,105,105, 43, 43, 86,159, 40, 40, 67,105,160, 63, 67, - 36, 36, 36, 61, 57,161,162, 69, 36, 36, 36, 36, 36, 63, 40, 69, - 44, 44, 62, 36, 36, 36, 36, 36, 67, 27, 27, 67, 67, 67, 67, 67, - 67, 67, 67, 44, 44, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, 92, - 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, 27, - 163, 27, 27, 27, 27, 27, 27, 27, 36, 36, 83, 36, 36, 36, 36, 36, - 67, 67, 67, 92, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36,164, 2, - 7, 7, 7, 7, 7, 36, 44, 44, 32, 32, 32, 32, 32, 32, 32, 70, - 51,165, 43, 43, 43, 43, 43, 88, 32, 32, 32, 32, 32, 32, 40, 43, - 36, 36, 36,105,105,105,105,105, 43, 2, 2, 2, 44, 44, 44, 44, - 41, 41, 41,162, 40, 40, 40, 40, 41, 32, 32, 32, 32, 32, 32, 32, - 16, 32, 32, 32, 32, 32, 32, 32, 45, 16, 16, 16, 34, 34, 34, 32, - 32, 32, 32, 32, 42,166, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, + 16, 16, 36, 16, 16, 16, 16, 16, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 40, 40, 39, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, 40, + 39, 39, 41, 40, 40, 40, 41, 41, 40, 40, 40, 40, 40, 40, 40, 40, + 42, 42, 42, 42, 42, 42, 42, 42, 32, 32, 41, 32, 43, 44, 16, 10, + 43, 43, 40, 45, 11, 46, 46, 11, 34, 11, 11, 11, 11, 11, 11, 11, + 11, 47, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34, + 16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 48, 34, 32, 34, 11, + 32, 49, 42, 42, 50, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16, + 47, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 46, 51, 2, 2, 2, + 16, 16, 16, 16, 52, 53, 54, 55, 56, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 57, 58, 59, 42, 58, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 60, 43, 61, + 36, 62, 63, 43, 43, 43, 43, 43, 64, 64, 64, 8, 9, 65, 2, 66, + 42, 42, 42, 42, 42, 59, 67, 2, 68, 36, 36, 36, 36, 69, 42, 42, + 7, 7, 7, 7, 7, 2, 2, 36, 70, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 71, 42, 42, 42, 72, 49, 42, 42, 73, 74, 75, 42, 42, 36, + 7, 7, 7, 7, 7, 36, 76, 77, 2, 2, 2, 2, 2, 2, 2, 78, + 69, 36, 36, 36, 36, 36, 36, 36, 42, 42, 42, 42, 42, 79, 61, 36, + 36, 36, 36, 42, 42, 42, 42, 42, 70, 43, 43, 43, 43, 43, 43, 43, + 7, 7, 7, 7, 7, 36, 36, 36, 36, 36, 36, 36, 36, 69, 42, 42, + 42, 42, 39, 21, 2, 80, 56, 20, 36, 36, 36, 42, 42, 74, 42, 42, + 42, 42, 74, 42, 74, 42, 42, 43, 2, 2, 2, 2, 2, 2, 2, 63, + 36, 36, 36, 36, 69, 42, 43, 63, 36, 36, 36, 36, 36, 60, 43, 43, + 36, 36, 36, 36, 81, 36, 36, 36, 64, 43, 43, 56, 42, 42, 42, 42, + 36, 36, 36, 36, 82, 42, 42, 42, 42, 83, 42, 42, 42, 42, 42, 42, + 42, 84, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 84, 70, 85, + 86, 42, 42, 42, 84, 85, 86, 85, 69, 42, 42, 42, 36, 36, 36, 36, + 36, 42, 2, 7, 7, 7, 7, 7, 87, 36, 36, 36, 36, 36, 36, 36, + 69, 85, 61, 36, 36, 36, 60, 61, 60, 61, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 60, 36, 36, 36, 60, 60, 43, 36, 36, 43, 70, 85, + 86, 42, 79, 88, 89, 88, 86, 60, 43, 43, 43, 88, 43, 43, 36, 61, + 36, 42, 43, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 55, 62, 79, + 56, 84, 61, 36, 36, 60, 43, 61, 60, 36, 61, 60, 36, 43, 79, 85, + 86, 79, 43, 56, 79, 56, 42, 43, 56, 43, 43, 43, 61, 36, 60, 60, + 43, 43, 43, 7, 7, 7, 7, 7, 42, 36, 69, 63, 43, 43, 43, 43, + 56, 84, 61, 36, 36, 36, 36, 61, 36, 61, 36, 36, 36, 36, 36, 36, + 60, 36, 61, 36, 36, 43, 70, 85, 86, 42, 42, 56, 84, 88, 86, 43, + 60, 43, 43, 43, 43, 43, 43, 43, 65, 43, 43, 43, 61, 42, 42, 42, + 56, 85, 61, 36, 36, 36, 60, 61, 60, 36, 61, 36, 36, 43, 70, 86, + 86, 42, 79, 88, 89, 88, 86, 43, 43, 43, 56, 84, 43, 43, 36, 61, + 77, 27, 27, 27, 43, 43, 43, 43, 43, 70, 61, 36, 36, 60, 43, 36, + 60, 36, 36, 43, 61, 60, 60, 36, 43, 61, 60, 43, 36, 60, 43, 36, + 36, 36, 36, 36, 36, 43, 43, 85, 84, 89, 43, 85, 89, 85, 86, 43, + 60, 43, 43, 88, 43, 43, 43, 43, 27, 90, 66, 66, 55, 91, 43, 43, + 84, 85, 70, 36, 36, 36, 60, 36, 60, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 43, 70, 42, 84, 85, 89, 42, 79, 42, 42, 43, + 43, 43, 56, 79, 36, 60, 36, 43, 43, 43, 43, 92, 27, 27, 27, 90, + 69, 85, 71, 36, 36, 36, 60, 36, 36, 36, 61, 36, 36, 43, 70, 86, + 85, 85, 89, 84, 89, 85, 42, 43, 43, 43, 88, 89, 43, 43, 36, 60, + 61, 93, 43, 43, 43, 43, 43, 43, 42, 85, 36, 36, 36, 36, 60, 36, + 36, 36, 36, 36, 36, 69, 70, 85, 86, 42, 79, 85, 89, 85, 86, 76, + 43, 43, 36, 93, 27, 27, 27, 94, 27, 27, 27, 27, 90, 36, 36, 36, + 56, 85, 61, 36, 36, 36, 36, 36, 36, 36, 36, 60, 43, 36, 36, 36, + 36, 61, 36, 36, 36, 36, 61, 43, 36, 36, 36, 60, 43, 79, 43, 88, + 85, 42, 79, 79, 85, 85, 85, 85, 43, 85, 63, 43, 43, 43, 43, 43, + 61, 36, 36, 36, 36, 36, 36, 36, 69, 36, 42, 42, 42, 79, 43, 95, + 36, 36, 36, 74, 42, 42, 42, 59, 7, 7, 7, 7, 7, 2, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 61, 60, 60, 36, 36, 60, 36, 36, + 36, 36, 61, 61, 36, 36, 36, 36, 69, 36, 42, 42, 42, 42, 70, 43, + 36, 36, 60, 80, 42, 42, 42, 79, 7, 7, 7, 7, 7, 43, 36, 36, + 76, 66, 2, 2, 2, 2, 2, 2, 2, 96, 96, 66, 42, 66, 66, 66, + 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 49, 49, 49, 4, 4, 85, + 36, 36, 36, 36, 61, 36, 36, 36, 36, 36, 36, 36, 36, 36, 60, 43, + 56, 42, 42, 42, 42, 42, 42, 84, 42, 42, 59, 42, 36, 36, 69, 42, + 42, 42, 42, 42, 56, 42, 42, 42, 42, 42, 42, 42, 42, 42, 79, 66, + 66, 66, 66, 75, 66, 66, 91, 66, 2, 2, 96, 66, 21, 63, 43, 43, + 36, 36, 36, 36, 36, 93, 86, 42, 84, 42, 42, 42, 86, 84, 86, 70, + 7, 7, 7, 7, 7, 2, 2, 2, 36, 36, 36, 85, 42, 36, 36, 42, + 70, 85, 97, 93, 85, 85, 85, 36, 69, 42, 70, 36, 36, 36, 36, 36, + 36, 84, 86, 84, 85, 85, 86, 93, 7, 7, 7, 7, 7, 85, 86, 66, + 11, 11, 11, 47, 43, 43, 47, 43, 16, 16, 16, 16, 16, 52, 44, 16, + 36, 36, 36, 36, 60, 36, 36, 43, 36, 36, 36, 60, 60, 36, 36, 43, + 60, 36, 36, 43, 36, 36, 36, 60, 60, 36, 36, 43, 36, 36, 36, 36, + 36, 36, 36, 60, 36, 36, 36, 36, 36, 36, 36, 36, 36, 60, 56, 42, + 2, 2, 2, 2, 98, 27, 27, 27, 27, 27, 27, 27, 27, 27, 99, 43, + 66, 66, 66, 66, 66, 43, 43, 43, 11, 11, 11, 43, 16, 16, 16, 43, + 100, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 76, 71, + 101, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,102,103, 43, + 36, 36, 36, 36, 36, 62, 2,104,105, 36, 36, 36, 60, 43, 43, 43, + 36, 42, 84, 43, 43, 43, 43, 61, 36, 42,106, 63, 43, 43, 43, 43, + 36, 42, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36, 60, 36, + 60, 42, 43, 43, 43, 43, 43, 43, 36, 36, 42, 86, 42, 42, 42, 85, + 85, 85, 85, 84, 86, 42, 42, 42, 42, 42, 2, 87, 2, 65, 69, 43, + 7, 7, 7, 7, 7, 43, 43, 43, 27, 27, 27, 27, 27, 43, 43, 43, + 2, 2, 2,107, 2, 58, 42, 83, 36, 82, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 60, 43, 43, 43, 36, 36, 69, 70, 36, 36, 36, 36, + 36, 36, 36, 36, 69, 60, 43, 43, 36, 36, 36, 43, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 36, 60, 42, 84, 85, 86, 84, 85, 43, 43, + 85, 84, 85, 85, 86, 42, 43, 43, 91, 43, 2, 7, 7, 7, 7, 7, + 36, 36, 36, 36, 36, 36, 36, 43, 36, 36, 60, 43, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 43, 43, 36, 36, 36, 36, 36, 43, 43, 43, + 7, 7, 7, 7, 7, 99, 43, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 36, 36, 36, 69, 84, 86, 43, 2, 36, 36, 93, 84, 42, 42, 42, 79, + 84, 84, 86, 42, 42, 42, 84, 85, 85, 86, 42, 42, 42, 42, 79, 56, + 2, 2, 2, 87, 2, 2, 2, 43, 42, 42, 42, 42, 42, 42, 42,108, + 42, 42, 42, 42, 42, 42, 42, 43, 42, 42, 42, 42, 42, 42, 43, 43, + 42, 42, 97, 36, 36, 36, 36, 36, 36, 36, 84, 42, 42, 84, 84, 85, + 85, 84, 97, 36, 36, 36, 60, 2, 96, 66, 66, 66, 66, 49, 42, 42, + 42, 42, 66, 66, 66, 66, 21, 2, 42, 97, 36, 36, 36, 36, 36, 36, + 93, 42, 42, 85, 42, 86, 42, 36, 36, 36, 36, 84, 42, 85, 86, 86, + 42, 85, 43, 43, 43, 43, 2, 2, 36, 36, 85, 85, 85, 85, 42, 42, + 42, 42, 85, 42, 43, 92, 2, 2, 7, 7, 7, 7, 7, 43, 61, 36, + 36, 36, 36, 36, 39, 39, 39, 2, 16, 16, 16, 16, 34,109, 43, 43, + 11, 11, 11, 11, 11, 46, 47, 11, 2, 2, 2, 2, 43, 43, 43, 43, + 42, 59, 42, 42, 42, 42, 42, 42, 84, 42, 42, 42, 70, 36, 69, 36, + 36, 36, 70, 93, 42, 60, 43, 43, 16, 16, 16, 16, 16, 16, 39, 39, + 39, 39, 39, 39, 39, 44, 16, 16, 16, 16, 16, 16, 44, 16, 16, 16, + 16, 16, 16, 16, 16,110, 39, 39, 32, 32, 32, 16, 16, 16, 16, 32, + 16, 16, 16, 16, 11, 11, 11, 11, 16, 16, 16, 43, 11, 11, 11, 43, + 16, 16, 16, 16, 47, 47, 47, 47, 16, 16, 16, 16, 16, 16, 16, 43, + 16, 16, 16, 16,111,111,111,111, 16, 16,109, 16, 11, 11,112,113, + 40, 16,109, 16, 11, 11,112, 40, 16, 16, 43, 16, 11, 11,114, 40, + 16, 16, 16, 16, 11, 11,115, 40, 43, 16,109, 16, 11, 11,112,116, + 117,117,117,117,117,118, 64, 64,119,119,119, 2,120,121,120,121, + 2, 2, 2, 2,122, 64, 64,123, 2, 2, 2, 2,124,125, 2,126, + 127, 2,128,129, 2, 2, 2, 2, 2, 9,127, 2, 2, 2, 2,130, + 64, 64,131, 64, 64, 64, 64, 64,132, 43, 27, 27, 27, 8,128,133, + 27, 27, 27, 27, 27, 8,128,103, 39, 39, 39, 39, 39, 39, 80, 43, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 43, 43, 43, 43, 43, 43, 43, + 42, 42, 42, 42, 42, 42,134, 50,108, 50,108, 42, 42, 42, 42, 42, + 79, 43, 43, 43, 43, 43, 43, 43, 66,135, 66,136, 66, 34, 11, 16, + 11, 32,136, 66, 48, 11, 11, 66, 66, 66,135,135,135, 11, 11,137, + 11, 11, 35, 36,138, 66, 16, 11, 8, 8, 48, 16, 16, 26, 66,139, + 27, 27, 27, 27, 27, 27, 27, 27,104,104,104,104,104,104,104,104, + 104,140,141,104,142, 66, 43, 43, 8, 8,143, 66, 66, 8, 66, 66, + 143, 26, 66,143, 66, 66, 66,143, 66, 66, 66, 66, 66, 66, 66, 8, + 66,143,143, 66, 66, 66, 66, 66, 66, 66, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 66, 66, 66, 66, 4, 4, 66, 66, + 8, 66, 66, 66,144,145, 66, 66, 66, 66, 66, 66, 66, 66,143, 66, + 66, 66, 66, 66, 66, 26, 8, 8, 8, 8, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 8, 8, 8, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 91, 43, 43, 27, 27, 27, 27, 27, 27, 66, 66, + 66, 66, 66, 66, 66, 27, 27, 27, 66, 66, 66, 26, 66, 66, 66, 66, + 26, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 8, 8, 8, 8, + 66, 66, 66, 66, 66, 66, 66, 26, 66, 66, 66, 66, 4, 4, 4, 4, + 4, 4, 4, 27, 27, 27, 27, 27, 27, 27, 66, 66, 66, 66, 66, 66, + 8, 8,128,146, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, + 8,128,147,147,147,147,147,147,147,147,147,147,146, 8, 8, 8, + 8, 8, 8, 8, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, + 8, 8,143, 26, 8, 8,143, 66, 66, 66, 43, 66, 66, 66, 66, 66, + 32, 11, 32, 34, 34, 34, 34, 11, 32, 32, 34, 16, 16, 16, 39, 11, + 32, 32,139, 66, 66,136, 34,148, 42, 32, 43, 43, 92, 2, 98, 2, + 16, 16, 16,149, 43, 43,149, 43, 36, 36, 36, 36, 43, 43, 43, 51, + 63, 43, 43, 43, 43, 43, 43, 56, 36, 36, 36, 60, 43, 43, 43, 43, + 36, 36, 36, 60, 36, 36, 36, 60, 2,120,120, 2,124,125,120, 2, + 2, 2, 2, 6, 2,107,120, 2,120, 4, 4, 4, 4, 2, 2, 87, + 2, 2, 2, 2, 2,119, 2, 2,107,150, 2, 2, 2, 2, 2, 2, + 66, 2,151,147,147,147,152, 43, 66, 66, 66, 66, 66, 54, 66, 66, + 66, 66, 43, 43, 43, 43, 43, 43, 66, 66, 66, 43, 43, 43, 43, 43, + 1, 2,153,154, 4, 4, 4, 4, 4, 66, 4, 4, 4, 4,155,156, + 157,104,104,104,104, 42, 42, 85,158, 39, 39, 66,104,159, 62, 66, + 36, 36, 36, 60, 56,160,161, 68, 36, 36, 36, 36, 36, 62, 39, 68, + 43, 43, 61, 36, 36, 36, 36, 36, 66, 27, 27, 66, 66, 66, 66, 66, + 66, 66, 66, 43, 43, 43, 43, 54, 66, 66, 66, 66, 66, 66, 66, 91, + 27, 27, 27, 27, 27, 66, 66, 66, 66, 66, 66, 66, 27, 27, 27, 27, + 162, 27, 27, 27, 27, 27, 27, 27, 36, 36, 82, 36, 36, 36, 36, 36, + 66, 66, 66, 91, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36,163, 2, + 7, 7, 7, 7, 7, 36, 43, 43, 32, 32, 32, 32, 32, 32, 32, 69, + 50,164, 42, 42, 42, 42, 42, 87, 32, 32, 32, 32, 32, 32, 39, 42, + 36, 36, 36,104,104,104,104,104, 42, 2, 2, 2, 43, 43, 43, 43, + 40, 40, 40,161, 39, 39, 39, 39, 40, 32, 32, 32, 32, 32, 32, 32, + 16, 32, 32, 32, 32, 32, 32, 32, 44, 16, 16, 16, 34, 34, 34, 32, + 32, 32, 32, 32, 41,165, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 11, 11, 32, 11, 11, 32, 32, 32, 32, 32, 32, - 32, 32, 11, 11, 34, 34, 32, 44, 32,150,150, 32, 32, 32, 47, 44, - 44, 40,167, 35, 40, 35, 36, 36, 36, 71, 36, 71, 36, 70, 36, 36, - 36, 94, 87, 85, 67, 67, 80, 44, 27, 27, 27, 67,168, 44, 44, 44, - 36, 36, 2, 2, 44, 44, 44, 44, 86, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 86, 86, 86, 86, 86, 86, 86, 86, 43, 44, 44, 44, 44, 2, - 43, 36, 36, 36, 2, 72, 72, 70, 36, 36, 36, 43, 43, 43, 43, 2, - 36, 36, 36, 70, 43, 43, 43, 43, 43, 86, 44, 44, 44, 44, 44, 93, - 36, 70, 86, 43, 43, 86, 43, 86,107, 2, 2, 2, 2, 2, 2, 52, - 7, 7, 7, 7, 7, 44, 44, 2, 36, 36, 70, 69, 36, 36, 36, 36, - 7, 7, 7, 7, 7, 36, 36, 61, 36, 36, 36, 36, 70, 43, 43, 85, - 87, 85, 87, 80, 44, 44, 44, 44, 36, 70, 36, 36, 36, 36, 85, 44, - 7, 7, 7, 7, 7, 44, 2, 2, 69, 36, 36, 77, 67, 94, 85, 36, - 71, 43, 71, 70, 71, 36, 36, 43, 70, 61, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 62, 83, 2, 36, 36, 36, 36, 36, 94, 43, 86, - 2, 83,169, 80, 44, 44, 44, 44, 62, 36, 36, 61, 62, 36, 36, 61, - 62, 36, 36, 61, 44, 44, 44, 44, 16, 16, 16, 16, 16,114, 40, 40, - 16, 16, 16, 16,111, 41, 44, 44, 36, 94, 87, 86, 85,107, 87, 44, - 36, 36, 44, 44, 44, 44, 44, 44, 36, 36, 36, 61, 44, 62, 36, 36, - 170,170,170,170,170,170,170,170,171,171,171,171,171,171,171,171, - 16, 16, 16,110, 44, 44, 44, 44, 44,150, 16, 16, 44, 44, 62, 71, - 36, 36, 36, 36,172, 36, 36, 36, 36, 36, 36, 61, 36, 36, 61, 61, - 36, 62, 61, 36, 36, 36, 36, 36, 36, 41, 41, 41, 41, 41, 41, 41, - 41,117, 44, 44, 44, 44, 44, 44, 44, 62, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36,148, 44, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 44, 44, 44, 55, 36, 36, 36, 36, 36, 36,168, 67, - 2, 2, 2,152,130, 44, 44, 44, 6,173,174,148,148,148,148,148, - 148,148,130,152,130, 2,127,175, 2, 64, 2, 2,156,148,148,130, - 2,176, 8,177, 66, 2, 44, 44, 36, 36, 61, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 61, 79, 93, 2, 3, 2, 4, 5, 6, 2, - 16, 16, 16, 16, 16, 17, 18,129,130, 4, 2, 36, 36, 36, 36, 36, - 69, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 40, - 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 61, 44, - 20,178, 56,135, 26, 8,144, 92, 44, 44, 44, 44, 79, 65, 67, 44, - 36, 36, 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 61, 36, 62, - 2, 64, 44,179, 27, 27, 27, 27, 27, 27, 44, 55, 67, 67, 67, 67, - 105,105,143, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 27, 67, 92, - 67, 67, 67, 67, 67, 67, 92, 44, 92, 44, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 67, 50, 44,180, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 44, 44, 27, 27, 44, 44, 44, 44, 62, 36, - 155, 36, 36, 36, 36,181, 44, 44, 36, 36, 36, 43, 43, 80, 44, 44, - 36, 36, 36, 36, 36, 36, 36, 93, 36, 36, 44, 44, 36, 36, 36, 36, - 182,105,105, 44, 44, 44, 44, 44, 11, 11, 11, 11, 16, 16, 16, 16, - 11, 11, 44, 44, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 44, 44, - 36, 36, 36, 36, 44, 44, 44, 44, 36, 36, 44, 44, 44, 44, 44, 93, - 11, 11, 11, 11, 11, 47, 11, 11, 11, 47, 11,150, 16, 16, 16, 16, - 16,150, 16, 16, 16, 16, 16, 16, 16,150, 16, 16, 16,150,110, 44, - 40, 40, 40, 52, 40, 40, 40, 40, 81, 40, 40, 40, 40, 81, 44, 44, - 36, 36, 36, 44, 61, 36, 36, 36, 36, 36, 36, 62, 61, 44, 61, 62, - 36, 36, 36, 93, 27, 27, 27, 27, 36, 36, 36, 77,163, 27, 27, 27, - 44, 44, 44,179, 27, 27, 27, 27, 36, 61, 36, 44, 44,179, 27, 27, - 36, 36, 36, 27, 27, 27, 44, 93, 36, 36, 36, 36, 36, 44, 44, 93, - 36, 36, 36, 36, 44, 44, 27, 36, 44, 27, 27, 27, 27, 27, 27, 27, - 70, 43, 57, 80, 44, 44, 43, 43, 36, 36, 62, 36, 62, 36, 36, 36, - 36, 36, 36, 44, 43, 80, 44, 57, 27, 27, 27, 27,100, 44, 44, 44, - 2, 2, 2, 2, 64, 44, 44, 44, 36, 36, 36, 36, 36, 36,183, 30, - 36, 36, 36, 36, 36, 36,183, 27, 36, 36, 36, 36, 78, 36, 36, 36, - 36, 36, 70, 80, 44,179, 27, 27, 2, 2, 2, 64, 44, 44, 44, 44, - 36, 36, 36, 44, 93, 2, 2, 2, 36, 36, 36, 44, 27, 27, 27, 27, - 36, 61, 44, 44, 27, 27, 27, 27, 36, 44, 44, 44, 93, 2, 64, 44, - 44, 44, 44, 44,179, 27, 27, 27, 11, 47, 44, 44, 44, 44, 44, 44, - 16,110, 44, 44, 44, 27, 27, 27, 36, 36, 43, 43, 44, 44, 44, 44, - 7, 7, 7, 7, 7, 36, 36, 69, 11, 11, 11, 44, 57, 43, 43,159, - 16, 16, 16, 44, 44, 44, 44, 8, 27, 27, 27, 27, 27, 27, 27,100, - 36, 36, 36, 36, 36, 57,184, 44, 36, 44, 44, 44, 44, 44, 44, 44, - 44, 36, 61, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 43, 43, - 27, 27, 27, 95, 44, 44, 44, 44,180, 27, 30, 2, 2, 44, 44, 44, - 36, 43, 43, 2, 2, 44, 44, 44, 36, 36,183, 27, 27, 27, 44, 44, - 87, 98, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, - 43, 43, 43, 60, 2, 2, 2, 44, 27, 27, 27, 7, 7, 7, 7, 7, - 71, 70, 71, 44, 44, 44, 44, 57, 86, 87, 43, 85, 87, 60,185, 2, - 2, 80, 44, 44, 44, 44, 79, 44, 43, 71, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 70, 43, 43, 87, 43, 43, 43, 80, 7, 7, 7, 7, 7, - 2, 2, 94, 98, 44, 44, 44, 44, 36, 70, 2, 61, 44, 44, 44, 44, - 36, 94, 86, 43, 43, 43, 43, 85, 98, 36, 63, 2, 59, 43, 60, 87, - 7, 7, 7, 7, 7, 63, 63, 2,179, 27, 27, 27, 27, 27, 27, 27, - 27, 27,100, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 86, 87, - 43, 86, 85, 43, 2, 2, 2, 71, 70, 44, 44, 44, 44, 44, 44, 44, - 36, 36, 36, 61, 61, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 62, - 36, 36, 36, 36, 63, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 70, - 86, 87, 43, 43, 43, 80, 44, 44, 43, 86, 62, 36, 36, 36, 61, 62, - 61, 36, 62, 36, 36, 57, 71, 86, 85, 86, 90, 89, 90, 89, 86, 44, - 61, 44, 44, 89, 44, 44, 62, 36, 36, 86, 44, 43, 43, 43, 80, 44, - 43, 43, 80, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 62, 44, 61, - 36, 36, 36, 62, 86, 87, 43, 43, 80, 90, 89, 89, 86, 90, 86, 85, - 71, 71, 2, 93, 64, 44, 44, 44, 57, 80, 44, 44, 44, 44, 44, 44, - 36, 36, 94, 86, 43, 43, 43, 43, 86, 43, 85, 71, 36, 63, 2, 2, - 7, 7, 7, 7, 7, 2, 93, 71, 86, 87, 43, 43, 85, 85, 86, 87, - 85, 43, 36, 72, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 94, - 86, 43, 43, 44, 86, 86, 43, 87, 60, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 36, 36, 43, 44, 86, 87, 43, 43, 43, 85, 87, 87, - 60, 2, 61, 44, 44, 44, 44, 44, 2, 2, 2, 2, 2, 2, 64, 44, - 36, 36, 36, 36, 36, 70, 87, 86, 43, 43, 43, 87, 63, 44, 44, 44, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 44, 44, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 61, 57, 87, 86, 43, 43, 87, 43, 43, 44, 44, - 7, 7, 7, 7, 7, 27, 2, 97, 43, 43, 43, 43, 87, 60, 44, 44, - 27,100, 44, 44, 44, 44, 44, 62, 36, 36, 36, 61, 62, 44, 36, 36, - 36, 36, 62, 61, 36, 36, 36, 36, 86, 86, 86, 89, 90, 57, 85, 71, - 98, 87, 2, 64, 44, 44, 44, 44, 36, 36, 36, 36, 44, 36, 36, 36, - 94, 86, 43, 43, 44, 43, 86, 86, 71, 72, 90, 44, 44, 44, 44, 44, - 70, 43, 43, 43, 43, 71, 36, 36, 36, 70, 43, 43, 85, 70, 43, 60, - 2, 2, 2, 59, 44, 44, 44, 44, 70, 43, 43, 85, 87, 43, 36, 36, - 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 85, 43, 2, 72, 2, - 2, 64, 44, 44, 44, 44, 44, 44, 2, 2, 2, 2, 2, 44, 44, 44, - 63, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 80, 43, 43, 43, 87, - 63, 2, 2, 44, 44, 44, 44, 44, 2, 36, 36, 36, 36, 36, 36, 36, - 44, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 89, 43, 43, 43, - 85, 43, 87, 80, 44, 44, 44, 44, 36, 36, 36, 61, 36, 62, 36, 36, - 70, 43, 43, 80, 44, 80, 43, 57, 43, 43, 43, 70, 44, 44, 44, 44, - 36, 36, 36, 62, 61, 36, 36, 36, 36, 36, 36, 36, 36, 86, 86, 90, - 43, 89, 87, 87, 61, 44, 44, 44, 36, 70, 85,107, 64, 44, 44, 44, - 43, 94, 36, 36, 36, 36, 36, 36, 36, 36, 86, 43, 43, 80, 44, 86, - 85, 60, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 80, 44, 44, - 27, 27, 91, 67, 67, 67, 56, 20,168, 67, 67, 67, 67, 67, 67, 67, - 67, 44, 44, 44, 44, 44, 44, 93,105,105,105,105,105,105,105,181, - 2, 2, 64, 44, 44, 44, 44, 44, 63, 64, 44, 44, 44, 44, 44, 44, - 65, 65, 65, 65, 65, 65, 65, 65, 71, 36, 36, 70, 43, 43, 43, 43, - 43, 43, 43, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 43, - 43, 43, 43, 43, 43, 86, 87, 43, 43, 43, 60, 44, 44, 44, 44, 44, - 43, 43, 43, 60, 2, 2, 67, 67, 40, 40, 97, 44, 44, 44, 44, 44, - 7, 7, 7, 7, 7,179, 27, 27, 27, 62, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 44, 44, 62, 36, 40, 69, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 83,164, 2, 27, 27, 27, 30, 2, 64, 44, 44, - 36, 36, 36, 36, 36, 61, 44, 57, 94, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 44, 44, 44, 57, - 43, 74, 40, 40, 40, 40, 40, 40, 40, 88, 80, 44, 44, 44, 44, 44, - 86, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 62, - 40, 40, 52, 40, 40, 40, 52, 81, 36, 61, 44, 44, 44, 44, 44, 44, - 44, 61, 44, 44, 44, 44, 44, 44, 36, 61, 62, 44, 44, 44, 44, 44, - 44, 44, 36, 36, 44, 44, 44, 44, 36, 36, 36, 36, 36, 44, 50, 60, - 65, 65, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43, 43, 44, - 43, 43, 43, 80, 44, 44, 44, 44, 67, 67, 67, 92, 55, 67, 67, 67, - 67, 67,186, 87, 43, 67,186, 86, 86,187, 65, 65, 65, 84, 43, 43, - 43, 76, 50, 43, 43, 43, 67, 67, 67, 67, 67, 67, 67, 43, 43, 67, - 67, 43, 76, 44, 44, 44, 44, 44, 27, 27, 44, 44, 44, 44, 44, 44, - 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 16, 16, 16,110, 16, 16, 16, 16, 16, - 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 47, 11, - 44, 47, 48, 47, 48, 11, 47, 11, 11, 11, 11, 16, 16,150,150, 16, - 16, 16,150, 16, 16, 16, 16, 16, 16, 16, 11, 48, 11, 47, 48, 11, - 11, 11, 47, 11, 11, 11, 47, 16, 16, 16, 16, 16, 11, 48, 11, 47, - 11, 11, 47, 47, 44, 11, 11, 11, 47, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, - 16, 16, 16, 44, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, - 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, - 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, - 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, - 16, 33, 16, 16, 16, 32, 44, 7, 43, 43, 43, 76, 67, 50, 43, 43, - 43, 43, 43, 43, 43, 43, 76, 67, 67, 67, 50, 67, 67, 67, 67, 67, - 67, 67, 76, 21, 2, 2, 44, 44, 44, 44, 44, 44, 44, 57, 43, 43, - 16, 16, 16, 16, 16, 39, 16, 16, 16, 16, 16, 16, 16, 16, 16,110, - 44, 44,150, 16, 16,110, 44, 44, 43, 43, 43, 80, 43, 43, 43, 43, - 43, 43, 43, 43, 80, 57, 43, 43, 43, 57, 80, 43, 43, 80, 44, 44, - 40, 40, 40, 40, 40, 40, 40, 44, 44, 44, 44, 44, 44, 44, 44, 57, - 43, 43, 43, 74, 40, 40, 40, 44, 7, 7, 7, 7, 7, 44, 44, 77, - 36, 36, 36, 36, 36, 36, 36, 80, 36, 36, 36, 36, 36, 36, 43, 43, - 7, 7, 7, 7, 7, 44, 44, 96, 36, 36, 36, 36, 36, 83, 43, 43, - 188, 7, 7, 7, 7,189, 44, 93, 36, 36, 36, 61, 36, 36, 62, 61, - 36, 36, 61,179, 27, 27, 27, 27, 16, 16, 43, 43, 43, 74, 44, 44, - 27, 27, 27, 27, 27, 27,163, 27,190, 27,100, 44, 44, 44, 44, 44, - 27, 27, 27, 27, 27, 27, 27,163, 27, 27, 27, 27, 27, 27, 27, 44, - 36, 36, 62, 36, 36, 36, 36, 36, 62, 61, 61, 62, 62, 36, 36, 36, - 36, 61, 36, 36, 62, 62, 44, 44, 44, 61, 44, 62, 62, 62, 62, 36, - 62, 61, 61, 62, 62, 62, 62, 62, 62, 61, 61, 62, 36, 61, 36, 36, - 36, 61, 36, 36, 62, 36, 61, 61, 36, 36, 36, 36, 36, 62, 36, 36, - 62, 36, 62, 36, 36, 62, 36, 36, 8, 44, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 67, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, - 27, 27, 27, 27, 27, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 44, - 44, 44, 44, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 92, 44, 44, 44, 67, 44, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 25, 41, 41, 67, 67, 67, 67, 44, 44, 67, 67, - 67, 67, 67, 92, 44, 55, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 44, 44, 55, 67, 67, 67, 92, 44, 44, 44, 67, - 67, 67, 67, 67, 67, 67, 92, 55, 67, 92, 67, 67, 67, 67, 67, 67, - 79, 44, 44, 44, 44, 44, 44, 44,171,171,171,171,171,171,171, 44, - 171,171,171,171,171,171,171, 0, 0, 0, 29, 21, 21, 21, 23, 21, - 22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21, 9, 9, 9, - 9, 22, 21, 18, 24, 16, 24, 5, 5, 5, 5, 22, 25, 18, 25, 0, - 23, 23, 26, 21, 24, 26, 7, 20, 25, 1, 26, 24, 26, 25, 15, 15, - 24, 15, 7, 19, 15, 21, 9, 25, 9, 5, 5, 25, 5, 9, 5, 7, - 7, 7, 9, 8, 8, 5, 7, 5, 6, 6, 24, 24, 6, 24, 12, 12, - 2, 2, 6, 5, 9, 21, 9, 2, 2, 9, 25, 9, 26, 12, 11, 11, - 2, 6, 5, 21, 17, 2, 2, 26, 26, 23, 2, 12, 17, 12, 21, 12, - 12, 21, 7, 2, 2, 7, 7, 21, 21, 2, 1, 1, 21, 23, 26, 26, - 1, 21, 6, 7, 7, 12, 12, 7, 21, 7, 12, 1, 12, 6, 6, 12, - 12, 26, 7, 26, 26, 7, 2, 1, 12, 2, 6, 2, 24, 7, 7, 6, - 1, 12, 12, 10, 10, 10, 10, 12, 21, 6, 2, 10, 10, 2, 15, 26, - 26, 2, 2, 21, 7, 10, 15, 7, 2, 23, 21, 26, 10, 7, 21, 15, - 15, 2, 17, 7, 29, 7, 7, 22, 18, 2, 14, 14, 14, 7, 10, 21, - 17, 21, 11, 12, 5, 2, 5, 6, 8, 8, 8, 24, 5, 24, 2, 24, - 9, 24, 24, 2, 29, 29, 29, 1, 17, 17, 20, 19, 22, 20, 27, 28, - 1, 29, 21, 20, 19, 21, 21, 16, 16, 21, 25, 22, 18, 21, 21, 29, - 1, 2, 15, 6, 18, 6, 23, 2, 12, 11, 9, 26, 26, 9, 26, 5, - 5, 26, 14, 9, 5, 14, 14, 15, 25, 26, 26, 22, 18, 26, 18, 25, - 18, 22, 5, 12, 2, 5, 22, 21, 21, 22, 18, 17, 26, 6, 7, 14, - 17, 22, 18, 18, 26, 14, 17, 6, 14, 6, 12, 24, 24, 6, 26, 15, - 6, 21, 11, 21, 24, 9, 6, 9, 23, 26, 6, 10, 4, 4, 3, 3, - 7, 25, 17, 16, 16, 22, 16, 16, 25, 17, 25, 2, 25, 24, 2, 15, - 12, 15, 14, 2, 21, 14, 7, 15, 12, 17, 21, 1, 26, 10, 10, 1, - 7, 13, 13, 2, 23, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 0, 10, 11, 12, 13, 0, 14, 0, 0, 0, 0, 0, 15, 0, 16, 0, + 32, 32, 11, 11, 34, 34, 32, 32, 32, 32, 32, 32, 32, 32, 46, 43, + 51, 39,166, 35, 39, 35, 36, 36, 36, 70, 36, 70, 36, 69, 36, 36, + 36, 93, 86, 84, 66, 66, 79, 43, 27, 27, 27, 66,167, 43, 43, 43, + 36, 36, 2, 2, 43, 43, 43, 43, 85, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 85, 85, 85, 85, 85, 85, 85, 85, 42, 43, 43, 43, 43, 2, + 42, 36, 36, 36, 2, 71, 71, 69, 36, 36, 36, 42, 42, 42, 42, 2, + 36, 36, 36, 69, 42, 42, 42, 42, 42, 85, 43, 43, 43, 43, 43, 92, + 36, 69, 85, 42, 42, 85, 42, 85,106, 2, 2, 2, 2, 2, 2, 51, + 7, 7, 7, 7, 7, 43, 43, 2, 36, 36, 69, 68, 36, 36, 36, 36, + 7, 7, 7, 7, 7, 36, 36, 60, 36, 36, 36, 36, 69, 42, 42, 84, + 86, 84, 86, 79, 43, 43, 43, 43, 36, 69, 36, 36, 36, 36, 84, 43, + 7, 7, 7, 7, 7, 43, 2, 2, 68, 36, 36, 76, 66, 93, 84, 36, + 70, 42, 70, 69, 70, 36, 36, 42, 69, 60, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 61, 82, 2, 36, 36, 36, 36, 36, 93, 42, 85, + 2, 82,168, 79, 43, 43, 43, 43, 61, 36, 36, 60, 61, 36, 36, 60, + 61, 36, 36, 60, 43, 43, 43, 43, 16, 16, 16, 16, 16,113, 39, 39, + 16, 16, 16, 16,110, 40, 43, 43, 36, 93, 86, 85, 84,106, 86, 43, + 36, 36, 43, 43, 43, 43, 43, 43, 36, 36, 36, 60, 43, 61, 36, 36, + 169,169,169,169,169,169,169,169,170,170,170,170,170,170,170,170, + 16, 16, 16,109, 43, 43, 43, 43, 43,149, 16, 16, 43, 43, 61, 70, + 36, 36, 36, 36,171, 36, 36, 36, 36, 36, 36, 60, 36, 36, 60, 60, + 36, 61, 60, 36, 36, 36, 36, 36, 36, 40, 40, 40, 40, 40, 40, 40, + 40, 22, 66, 66, 66, 66, 66, 66, 66, 77, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36,147, 66, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 66, 66, 66, 66, 36, 36, 36, 36, 36, 36,167, 66, + 2, 2, 2,151,129, 43, 43, 43, 6,172,173,147,147,147,147,147, + 147,147,129,151,129, 2,126,174, 2, 63, 2, 2,155,147,147,129, + 2,175, 8,176, 65, 2, 43, 43, 36, 36, 60, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 60, 78, 92, 2, 3, 2, 4, 5, 6, 2, + 16, 16, 16, 16, 16, 17, 18,128,129, 4, 2, 36, 36, 36, 36, 36, + 68, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 39, + 43, 36, 36, 36, 43, 36, 36, 36, 43, 36, 36, 36, 43, 36, 60, 43, + 20,177, 55,178, 26, 8,143, 91, 43, 43, 43, 43, 78, 64, 66, 43, + 36, 36, 36, 36, 36, 36, 61, 36, 36, 36, 36, 36, 36, 60, 36, 61, + 2, 63, 43,179, 27, 27, 27, 27, 27, 27, 43, 54, 66, 66, 66, 66, + 104,104,142, 27, 90, 66, 66, 66, 66, 66, 66, 66, 66, 27, 66, 91, + 66, 66, 66, 66, 66, 66, 91, 43, 91, 43, 43, 43, 43, 43, 43, 43, + 66, 66, 66, 66, 66, 66, 49, 43,180, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 43, 43, 27, 27, 43, 43, 43, 43, 61, 36, + 154, 36, 36, 36, 36,181, 43, 43, 36, 36, 36, 42, 42, 79, 43, 43, + 36, 36, 36, 36, 36, 36, 36, 92, 36, 36, 43, 43, 36, 36, 36, 36, + 182,104,104, 43, 43, 43, 43, 43, 11, 11, 11, 11, 16, 16, 16, 16, + 11, 11, 43, 43, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 43, 43, + 36, 36, 36, 36, 43, 43, 43, 43, 36, 36, 43, 43, 43, 43, 43, 92, + 11, 11, 11, 11, 11, 46, 11, 11, 11, 46, 11,149, 16, 16, 16, 16, + 16,149, 16, 16, 16, 16, 16, 16, 16,149, 16, 16, 16,149,109, 43, + 39, 39, 39, 51, 39, 39, 39, 39, 80, 39, 39, 39, 39, 80, 43, 43, + 36, 36, 36, 43, 60, 36, 36, 36, 36, 36, 36, 61, 60, 43, 60, 61, + 36, 36, 36, 92, 27, 27, 27, 27, 36, 36, 36, 76,162, 27, 27, 27, + 43, 43, 43,179, 27, 27, 27, 27, 36, 60, 36, 43, 43,179, 27, 27, + 36, 36, 36, 27, 27, 27, 43, 92, 36, 36, 36, 36, 36, 43, 43, 92, + 36, 36, 36, 36, 43, 43, 27, 36, 43, 27, 27, 27, 27, 27, 27, 27, + 69, 42, 56, 79, 43, 43, 42, 42, 36, 36, 61, 36, 61, 36, 36, 36, + 36, 36, 36, 43, 42, 79, 43, 56, 27, 27, 27, 27, 99, 43, 43, 43, + 2, 2, 2, 2, 63, 43, 43, 43, 36, 36, 36, 36, 36, 36,183, 30, + 36, 36, 36, 36, 36, 36,183, 27, 36, 36, 36, 36, 77, 36, 36, 36, + 36, 36, 69, 79, 43,179, 27, 27, 2, 2, 2, 63, 43, 43, 43, 43, + 36, 36, 36, 43, 92, 2, 2, 2, 36, 36, 36, 43, 27, 27, 27, 27, + 36, 60, 43, 43, 27, 27, 27, 27, 36, 43, 43, 43, 92, 2, 63, 43, + 43, 43, 43, 43,179, 27, 27, 27, 11, 46, 43, 43, 43, 43, 43, 43, + 16,109, 43, 43, 43, 27, 27, 27, 36, 36, 42, 42, 43, 43, 43, 43, + 7, 7, 7, 7, 7, 36, 36, 68, 11, 11, 11, 43, 56, 42, 42,158, + 16, 16, 16, 43, 43, 43, 43, 8, 27, 27, 27, 27, 27, 27, 27, 99, + 36, 36, 36, 36, 36, 56,184, 43, 36, 43, 43, 43, 43, 43, 43, 43, + 43, 36, 82, 36, 43, 43, 43, 43, 96, 66, 66, 66, 91, 43, 43, 43, + 43, 43, 43, 43, 43, 42, 42, 42, 27, 27, 27, 94, 43, 43, 43, 43, + 180, 27, 30, 2, 2, 43, 43, 43, 36, 42, 42, 2, 2, 43, 43, 43, + 36, 36,183, 27, 27, 27, 43, 43, 86, 97, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 42, 42, 42, 42, 42, 42, 42, 59, 2, 2, 2, 43, + 27, 27, 27, 7, 7, 7, 7, 7, 70, 69, 70, 43, 43, 43, 43, 56, + 85, 86, 42, 84, 86, 59,185, 2, 2, 79, 43, 43, 43, 43, 78, 43, + 42, 70, 36, 36, 36, 36, 36, 36, 36, 36, 36, 69, 42, 42, 86, 42, + 42, 42, 79, 7, 7, 7, 7, 7, 2, 2, 93, 97, 43, 43, 43, 43, + 36, 69, 2, 60, 43, 43, 43, 43, 36, 93, 85, 42, 42, 42, 42, 84, + 97, 36, 62, 2, 58, 42, 59, 86, 7, 7, 7, 7, 7, 62, 62, 2, + 179, 27, 27, 27, 27, 27, 27, 27, 27, 27, 99, 43, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 85, 86, 42, 85, 84, 42, 2, 2, 2, 70, + 69, 43, 43, 43, 43, 43, 43, 43, 36, 36, 36, 60, 60, 36, 36, 61, + 36, 36, 36, 36, 36, 36, 36, 61, 36, 36, 36, 36, 62, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 36, 69, 85, 86, 42, 42, 42, 79, 43, 43, + 42, 85, 61, 36, 36, 36, 60, 61, 60, 36, 61, 36, 36, 56, 70, 85, + 84, 85, 89, 88, 89, 88, 85, 43, 60, 43, 43, 88, 43, 43, 61, 36, + 36, 85, 43, 42, 42, 42, 79, 43, 42, 42, 79, 43, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 61, 43, 60, 36, 36, 36, 61, 85, 86, 42, 42, + 79, 89, 88, 88, 85, 89, 85, 84, 70, 70, 2, 92, 63, 43, 43, 43, + 56, 79, 43, 43, 43, 43, 43, 43, 36, 36, 93, 85, 42, 42, 42, 42, + 85, 42, 84, 70, 36, 62, 2, 2, 7, 7, 7, 7, 7, 2, 92, 70, + 85, 86, 42, 42, 84, 84, 85, 86, 84, 42, 36, 71, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 36, 93, 85, 42, 42, 43, 85, 85, 42, 86, + 59, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 42, 43, + 85, 86, 42, 42, 42, 84, 86, 86, 59, 2, 60, 43, 43, 43, 43, 43, + 2, 2, 2, 2, 2, 2, 63, 43, 36, 36, 36, 36, 36, 69, 86, 85, + 42, 42, 42, 86, 62, 43, 43, 43, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 36, 60, 56, 86, + 85, 42, 42, 86, 42, 42, 43, 43, 7, 7, 7, 7, 7, 27, 2, 96, + 42, 42, 42, 42, 86, 59, 43, 43, 27, 99, 43, 43, 43, 43, 43, 61, + 36, 36, 36, 60, 61, 43, 36, 36, 36, 36, 61, 60, 36, 36, 36, 36, + 85, 85, 85, 88, 89, 56, 84, 70, 97, 86, 2, 63, 43, 43, 43, 43, + 36, 36, 36, 36, 43, 36, 36, 36, 93, 85, 42, 42, 43, 42, 85, 85, + 70, 71, 89, 43, 43, 43, 43, 43, 69, 42, 42, 42, 42, 70, 36, 36, + 36, 69, 42, 42, 84, 69, 42, 59, 2, 2, 2, 58, 43, 43, 43, 43, + 69, 42, 42, 84, 86, 42, 36, 36, 36, 36, 36, 36, 36, 42, 42, 42, + 42, 42, 42, 84, 42, 2, 71, 2, 2, 63, 43, 43, 43, 43, 43, 43, + 2, 2, 2, 2, 2, 43, 43, 43, 84, 42, 84, 84, 43, 43, 43, 43, + 62, 43, 43, 43, 43, 43, 43, 43, 42, 42, 42, 79, 42, 42, 42, 86, + 62, 2, 2, 43, 43, 43, 43, 43, 2, 36, 36, 36, 36, 36, 36, 36, + 43, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 88, 42, 42, 42, + 84, 42, 86, 79, 43, 43, 43, 43, 36, 36, 36, 60, 36, 61, 36, 36, + 69, 42, 42, 79, 43, 79, 42, 56, 42, 42, 42, 69, 43, 43, 43, 43, + 36, 36, 36, 61, 60, 36, 36, 36, 36, 36, 36, 36, 36, 85, 85, 89, + 42, 88, 86, 86, 60, 43, 43, 43, 36, 36, 36, 36, 82, 36, 43, 43, + 36, 69, 84,106, 63, 43, 43, 43, 42, 93, 36, 36, 36, 36, 36, 36, + 36, 36, 85, 42, 42, 79, 43, 85, 84, 59, 2, 2, 2, 2, 2, 2, + 7, 7, 7, 7, 7, 79, 43, 43, 27, 27, 90, 66, 66, 66, 55, 20, + 167, 66, 66, 66, 66, 66, 66, 66, 66, 43, 43, 43, 43, 43, 43, 92, + 104,104,104,104,104,104,104,181, 2, 2, 63, 43, 43, 43, 43, 43, + 62, 63, 43, 43, 43, 43, 43, 43, 64, 64, 64, 64, 64, 64, 64, 64, + 70, 36, 36, 69, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 36, 42, 42, 42, 42, 42, 42, 85, 86, 42, + 42, 42, 59, 43, 43, 43, 43, 43, 42, 42, 42, 59, 2, 2, 66, 66, + 39, 39, 96, 43, 43, 43, 43, 43, 7, 7, 7, 7, 7,179, 27, 27, + 27, 61, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 61, 36, + 39, 68, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 82,163, 2, + 27, 27, 27, 30, 2, 63, 43, 43, 11, 11, 11, 11, 46,149, 16, 16, + 16, 16, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 36, 60, 43, 56, + 93, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 43, 43, 43, 56, 42, 73, 39, 39, 39, 39, 39, 39, + 39, 87, 79, 43, 43, 43, 43, 43, 85, 39,104,181, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 61, 36, 60, 43, 43, 43, 43, 43, 43, + 39, 39, 51, 39, 39, 39, 51, 80, 43, 60, 43, 43, 43, 43, 43, 43, + 36, 60, 61, 43, 43, 43, 43, 43, 43, 43, 36, 36, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 43, 49, 59, 64, 64, 43, 43, 43, 43, 43, 43, + 7, 7, 7, 7, 7, 66, 91, 43, 66, 66, 43, 43, 43, 66, 66, 66, + 176, 43, 43, 43, 43, 43, 43, 43, 42, 42, 42, 79, 43, 43, 43, 43, + 66, 66, 66, 91, 54, 66, 66, 66, 66, 66,186, 86, 42, 66,186, 85, + 85,187, 64, 64, 64, 83, 42, 42, 42, 75, 49, 42, 42, 42, 66, 66, + 66, 66, 66, 66, 66, 42, 42, 66, 66, 42, 75, 43, 43, 43, 43, 43, + 27, 27, 43, 43, 43, 43, 43, 43, 11, 11, 11, 11, 11, 16, 16, 16, + 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 16, + 16, 16,109, 16, 16, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 46, 11, 43, 46, 47, 46, 47, 11, 46, 11, + 11, 11, 11, 16, 16,149,149, 16, 16, 16,149, 16, 16, 16, 16, 16, + 16, 16, 11, 47, 11, 46, 47, 11, 11, 11, 46, 11, 11, 11, 46, 16, + 16, 16, 16, 16, 11, 47, 11, 46, 11, 11, 46, 46, 43, 11, 11, 11, + 46, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 11, 11, + 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 43, 11, 11, 11, 11, + 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, + 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, + 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, + 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 32, 43, 7, + 42, 42, 42, 75, 66, 49, 42, 42, 42, 42, 42, 42, 42, 42, 75, 66, + 66, 66, 49, 66, 66, 66, 66, 66, 66, 66, 75, 21, 2, 2, 43, 43, + 43, 43, 43, 43, 43, 56, 42, 42, 16, 16, 16, 16, 16,138, 16, 16, + 16, 16, 16, 16, 16, 16, 16,109, 43, 43,149, 16, 16,109, 43, 43, + 42, 42, 42, 79, 42, 42, 42, 42, 42, 42, 42, 42, 79, 56, 42, 42, + 42, 56, 79, 42, 42, 79, 43, 43, 39, 39, 39, 39, 39, 39, 39, 43, + 43, 43, 43, 43, 43, 43, 43, 56, 42, 42, 42, 73, 39, 39, 39, 43, + 7, 7, 7, 7, 7, 43, 43, 76, 36, 36, 36, 36, 36, 36, 36, 79, + 36, 36, 36, 36, 36, 36, 42, 42, 7, 7, 7, 7, 7, 43, 43, 95, + 36, 36, 36, 36, 36, 82, 42, 42,188, 7, 7, 7, 7,189, 43, 92, + 36, 69, 36, 70, 36, 36, 36, 42, 36, 36, 69, 43, 43, 43, 43, 82, + 36, 36, 36, 60, 36, 36, 61, 60, 36, 36, 60,179, 27, 27, 27, 27, + 16, 16, 42, 42, 42, 73, 43, 43, 27, 27, 27, 27, 27, 27,162, 27, + 190, 27, 99, 43, 43, 43, 43, 43, 27, 27, 27, 27, 27, 27, 27,162, + 27, 27, 27, 27, 27, 27, 27, 43, 36, 36, 61, 36, 36, 36, 36, 36, + 61, 60, 60, 61, 61, 36, 36, 36, 36, 60, 36, 36, 61, 61, 43, 43, + 43, 60, 43, 61, 61, 61, 61, 36, 61, 60, 60, 61, 61, 61, 61, 61, + 61, 60, 60, 61, 36, 60, 36, 36, 36, 60, 36, 36, 61, 36, 60, 60, + 36, 36, 36, 36, 36, 61, 36, 36, 61, 36, 61, 36, 36, 61, 36, 36, + 8, 43, 43, 43, 43, 43, 43, 43, 66, 66, 66, 66, 66, 66, 43, 43, + 54, 66, 66, 66, 66, 66, 66, 66, 27, 27, 27, 27, 27, 27, 90, 66, + 66, 66, 66, 66, 66, 66, 66, 43, 43, 43, 43, 66, 66, 66, 66, 66, + 66, 91, 43, 43, 43, 43, 43, 43, 66, 66, 66, 66, 91, 43, 43, 43, + 66, 43, 43, 43, 43, 43, 43, 43, 66, 66, 66, 66, 66, 25, 40, 40, + 66, 66, 66, 66, 91, 43, 66, 66, 66, 66, 66, 66, 43, 43, 43, 43, + 8, 8, 8, 8,176, 43, 43, 43, 66, 66, 66, 66, 66, 91, 43, 66, + 66, 66, 66, 91, 91, 43, 54, 66, 66, 66, 66, 66, 66, 66, 91, 54, + 66, 66, 66, 66, 66, 91, 43, 54, 66, 91, 66, 66, 66, 66, 66, 66, + 7, 7, 7, 7, 7, 91, 43, 43, 78, 43, 43, 43, 43, 43, 43, 43, + 170,170,170,170,170,170,170, 43,170,170,170,170,170,170,170, 0, + 0, 0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13, + 25, 25, 25, 21, 21, 9, 9, 9, 9, 22, 21, 18, 24, 16, 24, 5, + 5, 5, 5, 22, 25, 18, 25, 0, 23, 23, 26, 21, 24, 26, 7, 20, + 25, 1, 26, 24, 26, 25, 15, 15, 24, 15, 7, 19, 15, 21, 9, 25, + 9, 5, 5, 25, 5, 9, 5, 7, 7, 7, 9, 8, 8, 5, 6, 6, + 24, 24, 6, 24, 12, 12, 2, 2, 6, 5, 9, 21, 9, 2, 2, 9, + 25, 9, 26, 12, 11, 11, 2, 6, 5, 21, 17, 2, 2, 26, 26, 23, + 2, 12, 17, 12, 21, 12, 12, 21, 7, 2, 2, 7, 7, 21, 21, 2, + 1, 1, 21, 23, 26, 26, 1, 21, 6, 7, 7, 12, 12, 7, 21, 7, + 12, 1, 12, 6, 6, 12, 12, 26, 7, 26, 26, 7, 2, 1, 12, 2, + 6, 2, 24, 7, 7, 6, 1, 12, 12, 10, 10, 10, 10, 12, 21, 6, + 2, 10, 10, 2, 15, 26, 26, 2, 2, 21, 7, 10, 15, 7, 2, 23, + 21, 26, 10, 7, 21, 15, 15, 2, 17, 7, 29, 7, 7, 22, 18, 2, + 14, 14, 14, 7, 10, 21, 17, 21, 11, 12, 5, 2, 5, 6, 8, 8, + 8, 24, 5, 24, 2, 24, 9, 24, 24, 2, 29, 29, 29, 1, 17, 17, + 20, 19, 22, 20, 27, 28, 1, 29, 21, 20, 19, 21, 21, 16, 16, 21, + 25, 22, 18, 21, 21, 29, 1, 2, 15, 6, 18, 6, 12, 11, 9, 26, + 26, 9, 26, 5, 7, 5, 5, 26, 14, 9, 5, 14, 14, 15, 25, 26, + 26, 22, 18, 26, 18, 25, 18, 22, 5, 12, 2, 5, 22, 21, 21, 22, + 18, 17, 26, 6, 7, 14, 17, 22, 18, 18, 26, 14, 17, 6, 14, 6, + 12, 24, 24, 6, 26, 15, 6, 21, 11, 21, 24, 9, 6, 9, 23, 26, + 6, 10, 4, 4, 3, 3, 7, 25, 17, 16, 16, 22, 16, 16, 25, 17, + 25, 2, 25, 24, 23, 2, 2, 15, 12, 15, 14, 2, 21, 14, 7, 15, + 12, 17, 21, 1, 26, 10, 10, 1, 7, 13, 13, 2, 23, 15, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, 13, 0, 14, 0, + 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, 0, 0, 0, 0, + 0, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 21, 22, 23, + 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 20, 0, 21, 22, 23, 0, 0, 0, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, + 0, 0, 0, 36, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 36, 0, 37, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, 42, + 43, 44, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, + 6, 7, 8, 0, 9, 0, 10, 11, 0, 0, 12, 13, 14, 15, 16, 0, + 0, 0, 0, 17, 18, 19, 20, 0, 21, 0, 22, 23, 0, 24, 25, 0, + 0, 24, 26, 27, 0, 24, 26, 0, 0, 24, 26, 0, 0, 24, 26, 0, + 0, 0, 26, 0, 0, 24, 28, 0, 0, 24, 26, 0, 0, 29, 26, 0, + 0, 0, 30, 0, 0, 31, 32, 0, 0, 33, 34, 0, 35, 36, 0, 37, + 38, 0, 39, 0, 0, 40, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 0, 0, + 0, 0, 45, 0, 0, 0, 0, 0, 0, 46, 0, 0, 0, 47, 0, 0, + 0, 0, 0, 0, 48, 0, 0, 49, 0, 50, 51, 52, 0, 53, 54, 55, + 0, 56, 0, 57, 0, 58, 0, 0, 0, 0, 59, 60, 0, 0, 0, 0, + 0, 0, 61, 62, 0, 0, 0, 0, 0, 0, 63, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 66, + 0, 0, 0, 67, 0, 68, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 70, 71, 0, 0, 72, 0, 0, 0, 0, + 0, 0, 0, 0, 73, 74, 0, 0, 0, 0, 54, 75, 0, 76, 77, 0, + 0, 78, 79, 0, 0, 0, 0, 0, 0, 80, 81, 82, 0, 0, 0, 0, + 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, + 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 87, + 0, 0, 0, 0, 88, 89, 0, 0, 0, 0, 0, 90, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91, 0, 92, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 0, 94, 0, 0, 95, 0, + 96, 0, 0, 0, 0, 0, 73, 97, 0, 98, 0, 0, 99,100, 0, 78, + 0, 0,101, 0, 0,102, 0, 0, 0, 0, 0,103, 0,104, 26,105, + 0, 0,106, 0, 0, 0,107, 0, 0, 0,108, 0, 0, 0, 0, 0, + 0, 66,109, 0, 0, 66, 0, 0, 0,110, 0, 0, 0,111, 0, 0, + 0, 0, 0, 0, 0, 98, 0, 0, 0, 0, 0, 0, 0,112,113, 0, + 0, 0, 0, 79, 0, 44,114, 0,115, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0,116, 0, + 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,118, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,119, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120, 0,121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 40, - 0, 0, 0, 0, 0, 0, 41, 42, 43, 0, 44, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 3, 0, - 0, 0, 4, 5, 6, 7, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, - 16, 17, 16, 18, 16, 19, 16, 19, 16, 19, 0, 19, 16, 20, 16, 19, - 21, 19, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 32, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, - 34, 0, 0, 35, 0, 0, 36, 0, 37, 0, 0, 0, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 49, - 0, 0, 0, 0, 0, 0, 0, 50, 0, 51, 0, 52, 53, 0, 54, 0, - 0, 0, 0, 0, 0, 55, 56, 57, 0, 0, 0, 0, 58, 0, 0, 59, - 60, 61, 62, 63, 0, 0, 64, 65, 0, 0, 0, 66, 0, 0, 0, 0, - 67, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 69, 0, 0, 0, 70, 0, 71, 0, 0, 72, 0, 0, 73, - 0, 0, 0, 0, 0, 0, 0, 0, 74, 75, 0, 0, 0, 0, 76, 77, - 0, 78, 79, 0, 0, 80, 81, 0, 82, 62, 0, 83, 84, 0, 0, 85, - 86, 87, 0, 88, 0, 89, 0, 90, 0, 0, 51, 91, 51, 0, 92, 0, - 93, 0, 0, 0, 81, 0, 0, 0, 94, 95, 0, 96, 97, 98, 99, 0, - 0, 0, 0, 0, 51, 0, 0, 0, 0,100,101, 0, 0, 0, 0, 0, - 0,102, 0, 0, 0, 0, 0, 0,103, 0, 0, 0, 0, 0, 0,104, - 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,106, 0, 0,107, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,108,109, 0, 0,110, 0, 0, - 0, 0, 0, 0,111, 0,112, 0,105, 0, 0, 0, 0, 0,113,114, - 0, 0, 0, 0, 0, 0, 0,115, 0, 0, 0,116, 0, 0, 0,117, - 0,118, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, - 8, 0, 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, 0, 13, 0, 0, - 14, 15, 0, 16, 0, 17, 18, 0, 0, 19, 0, 20, 21, 0, 0, 0, - 0, 0, 22, 23, 0, 24, 25, 0, 0, 26, 0, 0, 0, 27, 0, 0, - 28, 29, 30, 31, 0, 0, 0, 32, 33, 34, 0, 0, 33, 0, 0, 35, - 33, 0, 0, 0, 33, 36, 0, 0, 0, 0, 0, 37, 38, 0, 0, 0, - 0, 0, 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, - 0, 43, 0, 44, 0, 0, 0, 45, 46, 0, 0, 0, 47, 0, 0, 0, - 0, 0, 0, 48, 49, 0, 0, 0, 0, 50, 0, 0, 0, 51, 0, 52, - 0, 53, 0, 0, 0, 0, 54, 0, 0, 0, 0, 55, 0, 56, 0, 0, - 0, 0, 57, 58, 0, 0, 0, 59, 60, 0, 0, 0, 0, 0, 0, 61, - 52, 0, 62, 63, 0, 0, 64, 0, 0, 0, 65, 66, 0, 0, 0, 67, - 0, 68, 69, 70, 71, 72, 1, 73, 0, 74, 75, 76, 0, 0, 77, 78, - 0, 0, 0, 79, 0, 0, 1, 1, 0, 0, 80, 0, 0, 81, 0, 0, - 0, 0, 77, 82, 0, 83, 0, 0, 0, 0, 0, 78, 84, 0, 85, 0, - 52, 0, 1, 78, 0, 0, 86, 0, 0, 87, 0, 0, 0, 0, 0, 88, - 57, 0, 0, 0, 0, 0, 0, 89, 90, 0, 0, 84, 0, 0, 33, 0, - 0, 91, 0, 0, 0, 0, 92, 0, 0, 0, 0, 49, 0, 0, 93, 0, - 0, 0, 0, 94, 95, 0, 0, 96, 0, 0, 97, 0, 0, 0, 98, 0, - 0, 0, 99, 0, 0, 0,100, 0, 0, 0, 0,101,102, 93, 0, 0, - 103, 0, 0, 0, 84, 0, 0,104, 0, 0, 0,105,106, 0, 0,107, - 108, 0, 0, 0, 0, 0, 0,109, 0, 0,110, 0, 0, 0, 0,111, - 33, 0,112,113,114, 57, 0, 0,115, 35, 0, 0,116, 0, 0, 0, - 117, 0, 0, 0, 0, 0, 0,118, 0, 0,119, 0, 0, 0, 0,120, - 88, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 52,121, 0, 0, 0, - 0,122, 0, 0,123, 0, 0, 0, 0,121, 0, 0,124, 0, 0, 0, - 0, 0, 79, 0, 0, 0, 0,125, 0, 0, 0,126, 0, 0, 0,127, - 0,128, 0, 0, 0, 0,129,130,131, 0,132, 0,133, 0, 0, 0, - 134,135,136, 0, 77, 0, 0, 0, 0, 0, 35, 0, 0, 0,137, 0, - 0, 0,138, 0, 0, 0,139, 0, 0,140, 0, 0,141, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 4, - 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, 18, 1, 1, 1, - 19, 1, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, 25, 26, 27, 28, - 29, 30, 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, 34, 35, 1, 36, - 37, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, 42, 0, 0, 0, - 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, 21, 0, 0, 47, - 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, 0, 19, 52, 1, - 0, 0, 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, 54, 21, 35, 1, - 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, 0, 0, 0, 59, - 0, 60, 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, 0, 0, 64, 0, - 0, 0, 65, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 68, 0, - 0, 69, 70, 0, 71, 72, 73, 74, 75, 76, 0, 0, 0, 77, 0, 0, - 0, 78, 79, 0, 0, 0, 0, 47, 0, 0, 0, 49, 0, 80, 0, 0, - 0, 62, 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, 0, 0, 83, 0, - 0, 19, 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, 1, 52, 15, 86, - 36, 10, 21, 87, 0, 55, 0, 0, 0, 0, 19, 10, 1, 0, 0, 0, - 0, 0, 88, 0, 0, 89, 0, 0, 88, 0, 0, 0, 0, 78, 0, 0, - 87, 9, 12, 4, 90, 8, 91, 47, 0, 58, 50, 0, 21, 1, 21, 92, - 93, 1, 1, 1, 1, 94, 95, 96, 97, 1, 98, 58, 81, 99,100, 4, - 58, 0, 0, 0, 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, 0, 61, - 0, 0,101,102, 0, 0,103, 0, 0, 1, 1, 50, 0, 0, 0, 38, - 0, 63, 0, 0, 0, 0, 0, 62, 0, 0,104, 68, 61, 0, 0, 0, - 78, 0, 0, 0,105,106, 58, 38, 81, 0, 0, 0, 0, 0, 0,107, - 1, 14, 4, 12, 84, 0, 0, 0, 0, 38, 87, 0, 0, 0, 0,108, - 0, 0,109, 61, 0,110, 0, 0, 0, 1, 0, 0, 0, 0, 49, 50, - 0, 0, 19, 58, 0, 0, 0, 51, 0,111, 14, 52,112, 41, 0, 0, - 62, 0, 0, 61, 0, 0,113, 0, 87, 0, 0, 0, 61, 62, 0, 0, - 62, 0, 89, 0, 0,113, 0, 0, 0, 0,114, 0, 0, 0, 78, 55, - 0, 38, 1, 58, 1, 58, 0, 0, 0, 0, 0, 88, 63, 89, 0, 0, - 115, 0, 0, 0, 55, 0, 0, 0, 0,115, 0, 0, 0, 0, 61, 0, - 0, 0, 0, 79, 0, 61, 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, - 79, 0, 0, 0, 8, 91, 0, 0, 1, 87, 0, 0,116, 0, 0, 0, - 0, 0, 0,117, 0,118,119,120,121, 0,104, 4,122, 49, 23, 0, - 0, 0, 38, 50, 38, 58, 0, 0, 1, 87, 1, 1, 1, 1, 39, 1, - 48,105, 87, 0, 0, 0, 0, 1, 0, 0, 0,123, 0, 0, 0,112, - 4,122, 0, 0, 0, 1,124, 0, 0, 0, 0, 0,230,230,230,230, - 230,232,220,220,220,220,232,216,220,220,220,220,220,202,202,220, - 220,220,220,202,202,220,220,220, 1, 1, 1, 1, 1,220,220,220, - 220,230,230,230,230,240,230,220,220,220,230,230,230,220,220, 0, - 230,230,230,220,220,220,220,230,232,220,220,230,233,234,234,233, - 234,234,233,230, 0, 0, 0,230, 0,220,230,230,230,230,220,230, - 230,230,222,220,230,230,220,220,230,222,228,230, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, 25, 0, - 230,220, 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, 28, 29, 30, 31, - 32, 33, 34,230,230,220,220,230,220,230,230,220, 35, 0, 0, 0, - 0, 0,230,230,230, 0, 0,230,230, 0,220,230,230,220, 0, 0, - 0, 36, 0, 0,230,220,230,230,220,220,230,220,220,230,220,230, - 220,230,230, 0, 0,220, 0, 0,230,230, 0,230, 0,230,230,230, - 230,230, 0, 0, 0,220,220,220,230,220,220,220,230,230, 0,220, - 27, 28, 29,230, 7, 0, 0, 0, 0, 9, 0, 0, 0,230,220,230, - 230, 0, 0, 0, 0, 0,230, 0, 0, 84, 91, 0, 0, 0, 0, 9, - 9, 0, 0, 0, 0, 0, 9, 0,103,103, 9, 0,107,107,107,107, - 118,118, 9, 0,122,122,122,122,220,220, 0, 0, 0,220, 0,220, - 0,216, 0, 0, 0,129,130, 0,132, 0, 0, 0, 0, 0,130,130, - 130,130, 0, 0,130, 0,230,230, 9, 0,230,230, 0, 0,220, 0, - 0, 0, 0, 7, 0, 9, 9, 0, 9, 9, 0, 0, 0,230, 0, 0, - 0,228, 0, 0, 0,222,230,220,220, 0, 0, 0,230, 0, 0,220, - 230,220, 0,220,230,230,230, 0, 0, 0, 9, 9, 0, 0, 7, 0, + 0, 0, 0,122, 0, 0, 0, 0,123, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,124, + 125,126, 0, 0, 0, 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,128,129, 0, 0,130, 0, 0, 0, 0,121, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,131, 0,132, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,133, 0, 0, 0, 0, + 0, 0, 0,134, 0, 0, 0, 0, 0, 0, 0,135, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136, 0, 0, 0,137, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, + 1, 2, 3, 4, 5, 6, 7, 4, 4, 8, 9, 10, 1, 11, 12, 13, + 14, 15, 16, 17, 18, 1, 1, 1, 0, 0, 0, 0, 19, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, + 25, 26, 27, 28, 29, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 31, 0, 0, 0, 32, 33, 34, 35, 1, 36, 0, 0, 0, 0, + 37, 0, 0, 0, 0, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, + 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, + 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 0, 0, 0, 0, 19, 1, + 21, 0, 0, 47, 0, 0, 0, 0, 0, 38, 48, 1, 1, 49, 49, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, + 0, 19, 52, 1, 0, 0, 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, + 54, 21, 35, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 56, + 57, 58, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 59, 0, 0, 0, 56, 0, 60, 0, 0, 0, 0, 0, 0, + 0, 0, 61, 62, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 64, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 68, 0, 0, 0, 0, 0, 0, 69, 70, 0, 0, 0, 0, 0, + 71, 72, 73, 74, 75, 76, 0, 0, 0, 0, 0, 0, 0, 77, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 78, 79, 0, 0, 0, 0, 47, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, + 0, 80, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, + 63, 0, 0, 81, 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 83, 0, 0, 0, 0, 0, 0, 19, 84, 0, 62, 0, 0, 0, + 0, 49, 1, 85, 0, 0, 0, 0, 1, 52, 15, 86, 36, 10, 21, 1, + 1, 1, 1, 41, 1, 21, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 55, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 19, 10, + 1, 0, 0, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 89, 0, 0, + 88, 0, 0, 0, 0, 0, 0, 0, 0, 78, 0, 0, 0, 0, 0, 0, + 90, 9, 12, 4, 91, 8, 92, 47, 0, 58, 50, 0, 21, 1, 21, 93, + 94, 1, 1, 1, 1, 1, 1, 1, 1, 95, 96, 97, 0, 0, 0, 0, + 98, 1, 99, 58, 81,100,101, 4, 58, 0, 0, 0, 0, 0, 0, 19, + 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 0,102,103, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,104, 0, 0, 0, 0, 19, 0, 1, 1, 50, 0, 0, 0, 0, + 0, 0, 0, 38, 0, 0, 0, 0, 50, 0, 0, 0, 0, 63, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 0, 1, 1, 1, 1, + 50, 0, 0, 0, 0, 0,105, 68, 0, 0, 0, 0, 0, 0, 0, 0, + 61, 0, 0, 0, 0, 0, 0, 0, 78, 0, 0, 0, 62, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,106,107, 58, 38, 81, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, + 0, 0, 0,108, 1, 14, 4, 12, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 47, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 38, 90, 0, 0, 0, 0,109, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,110, 61, 0,111, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 49, 50, 0, 0, 0, 0, 0, 0, 19, 58, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,112, 51, 0,112, 14, 52, + 84, 0, 0, 0,113, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 62, 0, 0, 61, 0, 0, 0, 0, 0, 0,114, 0, 90, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 61, 62, 0, 0, 62, 0, 89, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,114, 0, 0, 0, 0,115, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78, 55, 0, 38, 1, 58, + 1, 58, 0, 0, 0, 0, 0, 88, 62, 0, 0, 0, 63, 89, 0, 0, + 0, 0, 0, 59,116, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,116, 0, 0, 0, 0, 61, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 78, 0, 0, 0, + 0, 0, 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 56, 0, 89, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 61, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 92, 0, 0, 0, 0, 0, 0, + 1, 90, 0, 0, 0, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,118, 0,119,120,121,122, 0,105, 4,123, 49, 23, 0, + 0, 0, 0, 0, 0, 0, 38, 50, 0, 0, 0, 0, 38, 58, 0, 0, + 0, 0, 0, 0, 1, 90, 1, 1, 1, 1, 39, 1, 48,106, 90, 0, + 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 59, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,124, + 0, 0, 0, 0, 0, 0, 0,113, 0, 0, 0, 0, 19, 59, 0, 38, + 0, 81, 0, 0, 0, 0, 0, 0, 4,123, 0, 0, 0, 1,125, 0, + 0, 0, 0, 0, 0, 0, 0, 0,230,230,230,230,230,232,220,220, + 220,220,232,216,220,220,220,220,220,202,202,220,220,220,220,202, + 202,220,220,220, 1, 1, 1, 1, 1,220,220,220,220,230,230,230, + 230,240,230,220,220,220,230,230,230,220,220, 0,230,230,230,220, + 220,220,220,230,232,220,220,230,233,234,234,233,234,234,233,230, + 0, 0, 0,230, 0,220,230,230,230,230,220,230,230,230,222,220, + 230,230,220,220,230,222,228,230, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, 25, 0,230,220, 0, 18, + 30, 31, 32, 0, 0, 0, 0, 27, 28, 29, 30, 31, 32, 33, 34,230, + 230,220,220,230,220,230,230,220, 35, 0, 0, 0, 0, 0,230,230, + 230, 0, 0,230,230, 0,220,230,230,220, 0, 0, 0, 36, 0, 0, + 230,220,230,230,220,220,230,220,220,230,220,230,220,230,230, 0, + 0,220, 0, 0,230,230, 0,230, 0,230,230,230,230,230, 0, 0, + 0,220,220,220,230,220,220,220,230,230, 0,220, 27, 28, 29,230, + 7, 0, 0, 0, 0, 9, 0, 0, 0,230,220,230,230, 0, 0, 0, + 0, 0,230, 0, 0, 84, 91, 0, 0, 0, 0, 9, 9, 0, 0, 0, + 0, 0, 9, 0,103,103, 9, 0,107,107,107,107,118,118, 9, 0, + 122,122,122,122,220,220, 0, 0, 0,220, 0,220, 0,216, 0, 0, + 0,129,130, 0,132, 0, 0, 0, 0, 0,130,130,130,130, 0, 0, + 130, 0,230,230, 9, 0,230,230, 0, 0,220, 0, 0, 0, 0, 7, + 0, 9, 9, 0, 9, 9, 0, 0, 0,230, 0, 0, 0,228, 0, 0, + 0,222,230,220,220, 0, 0, 0,230, 0, 0,220,230,220, 0,220, + 230,230,230,234, 0, 0, 9, 9, 0, 0, 7, 0,230,230,230, 0, 230, 0, 1, 1, 1, 0, 0, 0,230,234,214,220,202,230,230,230, 230,230,232,228,228,220,218,230,233,220,230,220,230,230, 1, 1, 1, 1, 1,230, 0, 1, 1,230,220,230, 1, 1, 0, 0,218,228, @@ -1683,63 +1482,81 @@ _hb_ucd_u8[17612] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 34, 9, 0, 0, 20, 20, 1, 20, 20, 0, 0, 0, 0, 0, 0, 0, 26, 21, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 47, 48, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 13, 13, 13, 13, 13, 14, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 15, 16, 17, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 20, 20, 20, 20, 20, 20, - 20, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 20, 33, - 34, 35, 34, 34, 36, 37, 20, 20, 20, 20, 20, 20, 38, 20, 39, 40, - 41, 41, 41, 41, 41, 42, 43, 44, 20, 20, 20, 20, 20, 20, 20, 45, - 46, 20, 20, 47, 20, 20, 20, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 20, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 9, 10, 11, 11, 11, 11, 12, 13, + 13, 13, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 13, 13, 13, + 24, 25, 26, 26, 26, 27, 13, 13, 13, 28, 29, 30, 13, 31, 32, 33, + 34, 35, 36, 37, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 38, 7, 7, 39, 7, 40, 7, 7, + 7, 41, 13, 42, 7, 7, 43, 7, 7, 7, 44, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 60, 13, 13, - 13, 61, 62, 13, 13, 13, 13, 63, 13, 13, 13, 13, 13, 13, 64, 65, - 20, 20, 66, 20, 13, 13, 13, 13, 67, 13, 13, 13, 68, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 45, 0, 0, 1, 2, 2, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 33, 34, 35, 36, 37, 37, + 37, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 2, 2, 53, 54, 55, 56, 57, 58, 59, 59, 59, 59, 60, 59, + 59, 59, 59, 59, 59, 59, 61, 61, 59, 59, 59, 59, 62, 59, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 59, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 78, 69, 69, 69, 69, 79, 79, 79, 79, 79, 79, 79, 79, 79, 80, + 81, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 94, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 69, 69, 96, 97, 98, 99, 99, 99, + 100,101,102,103,104,105,106,107,108,109, 95,110,111,112,113,114, + 115,116,117,117,118,119,120,121,122,123,124,125,126,127,128,129, + 130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145, + 95,146,147,148,149, 95,150,151,152,153,154,155,156,157,158,159, + 160,161, 95,162,163,164,165,165,165,165,165,165,165,166,167,165, + 168, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95,169,170,170,170,170,170,170,170,170,171,170, + 170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, + 170,170,170,170,170,170,170,170,170,170,170,170,170,172,173,173, + 173,173,174, 95, 95, 95, 95, 95,175, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95,176,176,176,176,177,178,179,180, 95, 95, + 181, 95,182,183,184,185,186,186,186,186,186,186,186,186,186,186, + 186,186,186,186,186,186,186,186,186,186,186,186,187,187,187,188, + 189,190, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95,191,192,193,194,195,195,196, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,197,198, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 59,199, + 59, 59, 59,200,201,202, 59,203,204,205,206,207,208, 95,209,210, + 211, 59, 59,212, 59,213,214,214,214,214,214,215, 95, 95, 95, 95, + 95, 95, 95, 95,216, 95,217,218,219, 95, 95,220, 95, 95, 95,221, + 95,222, 95,223, 95,224,225,226,227, 95, 95, 95, 95, 95,228,229, + 230, 95,231,232, 95, 95,233,234, 59,235,236, 95, 59, 59, 59, 59, + 59, 59, 59,237, 59,238,239,240, 59, 59,241,242, 59,243, 95, 95, + 95, 95, 95, 95, 95, 95, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69,244, 69, 69,245, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69,246, 69, 69, 69, 69, 69, 69, 69, 69, 69,247, 69, 69, + 69, 69,248, 95, 95, 95, 69, 69, 69, 69,249, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 69, 69, 69, 69, 69, 69,250, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,251, 95, + 95, 95, 95, 95, 95, 95,252, 95,253,254, 0, 1, 2, 2, 0, 1, + 2, 2, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 0, 19, 0, 0, 0, 0, 0, 0, 0, 19, 19, @@ -1764,46 +1581,46 @@ _hb_ucd_u8[17612] = 64, 2, 2, 64, 64, 64, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 2, 2, 90, 90, 90, 90, 90, 90, 90, 2, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 2, 2, 95, 2, 37, 37, - 37, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, - 2, 2, 2, 2, 2, 3, 3, 3, 0, 3, 3, 3, 3, 3, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 1, 1, 1, 1, 7, 7, 7, 7, 7, - 7, 7, 0, 0, 7, 7, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, - 5, 5, 5, 2, 2, 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 2, - 5, 2, 2, 2, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 5, 2, - 2, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, - 2, 2, 5, 5, 2, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 2, 2, 11, 11, 11, 2, 11, 11, 11, 11, 11, - 11, 2, 2, 2, 2, 11, 11, 2, 2, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 2, 11, 11, 11, 11, 11, 11, 11, 2, - 11, 11, 2, 11, 11, 2, 11, 11, 2, 2, 11, 2, 11, 11, 11, 2, - 2, 11, 11, 11, 2, 2, 2, 11, 2, 2, 2, 2, 2, 2, 2, 11, - 11, 11, 11, 2, 11, 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 2, 2, 10, 10, 10, 2, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 2, 10, 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, 2, - 10, 10, 2, 10, 10, 10, 10, 10, 2, 2, 10, 10, 10, 10, 10, 10, - 2, 10, 10, 10, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 10, 10, - 10, 10, 2, 2, 10, 10, 10, 10, 2, 2, 2, 2, 2, 2, 2, 10, - 10, 10, 10, 10, 10, 10, 2, 21, 21, 21, 2, 21, 21, 21, 21, 21, - 21, 21, 21, 2, 2, 21, 21, 2, 2, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 2, 21, 21, 21, 21, 21, 21, 21, 2, - 21, 21, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, 21, 21, 2, - 2, 21, 21, 21, 2, 2, 2, 2, 2, 2, 2, 21, 21, 21, 2, 2, - 2, 2, 21, 21, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, 2, - 22, 22, 2, 22, 22, 22, 22, 22, 22, 2, 2, 2, 22, 22, 22, 2, - 22, 22, 22, 22, 2, 2, 2, 22, 22, 2, 22, 2, 22, 22, 2, 2, - 2, 22, 22, 2, 2, 2, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 2, 2, 2, 2, 22, 22, 22, 2, 2, 2, 2, 2, 2, 22, 2, 2, - 2, 2, 2, 2, 22, 22, 22, 22, 22, 2, 2, 2, 2, 2, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 2, 23, 23, 23, 2, - 23, 23, 23, 23, 23, 23, 23, 23, 2, 2, 23, 23, 23, 23, 23, 2, - 23, 23, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 23, 2, 23, 23, - 23, 2, 2, 23, 2, 2, 23, 23, 23, 23, 2, 2, 23, 23, 2, 2, - 2, 2, 2, 2, 2, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 2, 16, 16, 16, 2, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 2, 16, 16, 16, 16, 16, 2, 2, 16, 16, 16, 16, 16, 2, - 16, 16, 16, 16, 2, 2, 2, 2, 2, 2, 2, 16, 16, 2, 16, 16, + 37, 2, 2, 2, 2, 2, 3, 3, 2, 2, 2, 2, 2, 3, 3, 3, + 0, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1, + 1, 1, 1, 7, 7, 7, 7, 7, 7, 7, 0, 0, 7, 7, 5, 5, + 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 2, + 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, + 5, 5, 5, 5, 5, 5, 5, 2, 5, 2, 2, 2, 5, 5, 5, 5, + 2, 2, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 2, 2, 2, + 2, 2, 2, 2, 2, 5, 2, 2, 2, 2, 5, 5, 2, 5, 5, 5, + 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 11, + 11, 11, 2, 11, 11, 11, 11, 11, 11, 2, 2, 2, 2, 11, 11, 2, + 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, + 11, 11, 11, 11, 11, 11, 11, 2, 11, 11, 2, 11, 11, 2, 11, 11, + 2, 2, 11, 2, 11, 11, 11, 2, 2, 11, 11, 11, 2, 2, 2, 11, + 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, 11, 2, 11, 2, 2, 2, + 2, 2, 2, 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, 2, 10, + 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, + 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, + 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 2, 10, 10, 10, 10, 10, + 2, 2, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, 2, 2, 10, 2, + 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 2, 2, 10, 10, 10, 10, + 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 2, 21, + 21, 21, 2, 21, 21, 21, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, + 2, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 2, + 21, 21, 21, 21, 21, 21, 21, 2, 21, 21, 2, 21, 21, 21, 21, 21, + 2, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, 2, 2, 2, 2, + 2, 2, 2, 21, 21, 21, 2, 2, 2, 2, 21, 21, 2, 21, 21, 21, + 21, 21, 2, 2, 21, 21, 2, 2, 22, 22, 2, 22, 22, 22, 22, 22, + 22, 2, 2, 2, 22, 22, 22, 2, 22, 22, 22, 22, 2, 2, 2, 22, + 22, 2, 22, 2, 22, 22, 2, 2, 2, 22, 22, 2, 2, 2, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 2, 2, 2, 2, 22, 22, 22, 2, + 2, 2, 2, 2, 2, 22, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, + 22, 2, 2, 2, 2, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 2, 23, 23, 23, 2, 23, 23, 23, 23, 23, 23, 23, 23, + 2, 2, 23, 23, 23, 23, 23, 2, 23, 23, 23, 23, 2, 2, 2, 2, + 2, 2, 2, 23, 23, 2, 23, 23, 23, 2, 23, 23, 2, 2, 23, 23, + 23, 23, 2, 2, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 2, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 16, + 2, 2, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 2, 2, 2, 2, + 2, 2, 2, 16, 16, 2, 2, 2, 2, 2, 16, 16, 16, 2, 16, 16, 16, 16, 2, 2, 16, 16, 2, 16, 16, 16, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 2, 20, 20, 20, 2, 20, 20, 20, 20, 20, 20, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, @@ -1850,137 +1667,135 @@ _hb_ucd_u8[17612] = 54, 54, 2, 2, 54, 54, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 2, 91, 91, 91, 91, 91, 2, 2, 91, 91, 91, 2, 2, 2, 2, 2, 2, 91, 91, 91, 91, 91, 91, 2, 2, 1, 1, - 1, 1, 1, 1, 1, 2, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 2, 62, 62, 76, 76, 76, 76, 76, 76, 76, 76, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 2, 2, 2, 2, 2, 2, - 2, 2, 93, 93, 93, 93, 70, 70, 70, 70, 70, 70, 70, 70, 2, 2, - 2, 70, 70, 70, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 73, 73, - 73, 73, 73, 73, 73, 73, 6, 6, 6, 2, 2, 2, 2, 2, 8, 8, - 8, 2, 2, 8, 8, 8, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 1, 1, 0, 2, 2, 2, 2, 2, 19, 19, - 19, 19, 19, 19, 9, 9, 9, 9, 9, 6, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 9, 9, 9, 9, 9, 19, 19, 19, 19, 9, 9, 9, 9, - 9, 19, 19, 19, 19, 19, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 9, 9, 9, 9, 9, 9, 9, 2, 2, 2, 9, - 2, 9, 2, 9, 2, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 9, - 9, 9, 2, 2, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 2, 2, - 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 19, - 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, - 0, 0, 0, 0, 0, 2, 19, 19, 19, 19, 19, 2, 2, 2, 0, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 0, 0, - 0, 0, 0, 0, 9, 0, 0, 0, 19, 19, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 19, 0, 19, 0, 0, 0, 2, 2, 2, 2, 0, 0, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 2, 27, 27, - 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 0, 56, 56, 56, 56, 56, 56, 56, 56, 55, 55, - 55, 55, 2, 2, 2, 2, 2, 55, 55, 55, 55, 55, 55, 55, 61, 61, - 61, 61, 61, 61, 61, 61, 2, 2, 2, 2, 2, 2, 2, 61, 61, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 2, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 2, 2, 0, 0, - 0, 0, 0, 13, 0, 13, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 1, 1, 1, 1, 12, 12, 13, 13, 13, 13, 0, 0, 0, 0, 2, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 2, 2, 1, 1, 0, 0, 15, 15, 15, 0, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 0, 0, 17, 17, 17, 2, 2, 2, 2, 2, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 2, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 2, 2, 2, 2, 2, 2, 2, 2, 0, 12, 12, - 12, 12, 12, 12, 12, 0, 17, 17, 17, 17, 17, 17, 17, 0, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 2, 2, 2, 39, 39, - 39, 39, 39, 39, 39, 2, 86, 86, 86, 86, 86, 86, 86, 86, 77, 77, - 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 2, 2, 2, 2, 79, 79, - 79, 79, 79, 79, 79, 79, 0, 0, 19, 19, 19, 19, 19, 19, 0, 0, - 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 2, 2, 19, 19, - 2, 19, 2, 19, 19, 19, 2, 2, 19, 19, 19, 19, 19, 19, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 2, 2, 2, 65, 65, - 65, 65, 65, 65, 65, 65, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, - 75, 75, 75, 75, 2, 2, 2, 2, 2, 2, 2, 2, 75, 75, 75, 75, - 2, 2, 2, 2, 2, 2, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 0, 69, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 74, 12, 12, - 12, 12, 12, 2, 2, 2, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 2, 0, 84, 84, 2, 2, 2, 2, 84, 84, 33, 33, - 33, 33, 33, 33, 33, 2, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 2, 68, 68, 68, 68, 68, 68, 2, 2, 68, 68, - 2, 2, 68, 68, 68, 68, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 2, 2, 2, 2, 2, 2, 2, 2, 92, 92, 92, 92, 92, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 2, 2, 30, - 30, 30, 30, 30, 30, 2, 19, 19, 19, 0, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 9, 19, 19, 19, 19, 0, 0, 2, 2, 2, 2, 87, 87, - 87, 87, 87, 87, 2, 2, 87, 87, 2, 2, 2, 2, 2, 2, 12, 12, - 12, 12, 2, 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 12, 13, 13, - 2, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 19, 2, 2, 2, - 2, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 2, 14, 14, 14, 14, 14, 2, 14, 2, 14, 14, - 2, 14, 14, 2, 14, 14, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, - 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 2, 2, - 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 3, 1, 1, - 1, 1, 1, 1, 6, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, - 3, 3, 3, 2, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 2, 2, - 12, 12, 12, 12, 12, 12, 2, 2, 12, 12, 12, 2, 2, 2, 2, 0, - 0, 0, 0, 0, 2, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 2, 49, 49, - 49, 2, 49, 49, 2, 49, 49, 49, 49, 49, 49, 49, 2, 2, 49, 49, - 49, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, - 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 2, 9, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 1, 2, 2, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 2, 2, 2, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 2, 2, 2, 2, 2, 2, 2, 1, 0, - 0, 0, 0, 0, 0, 0, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 2, 2, 2, 2, 2, 2, 2, 2, 2, 42, 42, 42, 41, 41, - 41, 41, 41, 41, 41, 41, 41, 41, 41, 2, 2, 2, 2, 2,118,118, - 118,118,118,118,118,118,118,118,118, 2, 2, 2, 2, 2, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 2, 53, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 2, 2, 2, 2, 59, 59, - 59, 59, 59, 59, 2, 2, 40, 40, 40, 40, 40, 40, 40, 40, 51, 51, - 51, 51, 51, 51, 51, 51, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 2, 2, 50, 50, 2, 2, 2, 2, 2, 2,135,135, - 135,135,135,135,135,135,135,135,135,135, 2, 2, 2, 2,106,106, - 106,106,106,106,106,106,104,104,104,104,104,104,104,104,104,104, - 104,104, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,104,161,161, - 161,161,161,161,161,161,161,161,161, 2,161,161,161,161,161,161, - 161, 2,161,161, 2,161,161,161, 2,161,161,161,161,161,161,161, - 2,161,161, 2, 2, 2,170,170,170,170,170,170,170,170,170,170, - 170,170, 2, 2, 2, 2,110,110,110,110,110,110,110,110,110,110, - 110,110,110,110,110, 2,110,110,110,110,110,110, 2, 2, 19, 19, - 19, 19, 19, 19, 2, 19, 19, 2, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 2, 2, 2, 2, 2, 47, 47, 47, 47, 47, 47, 2, 2, 47, 2, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 2, 47, 47, 2, 2, 2, 47, 2, 2, 47, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 2, 81,120,120, - 120,120,120,120,120,120,116,116,116,116,116,116,116,116,116,116, - 116,116,116,116,116, 2, 2, 2, 2, 2, 2, 2, 2,116,128,128, - 128,128,128,128,128,128,128,128,128, 2,128,128, 2, 2, 2, 2, - 2,128,128,128,128,128, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 2, 2, 2, 66, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 2, 2, 2, 2, 2, 72, 98, 98, 98, 98, 98, 98, 98, 98, 97, 97, - 97, 97, 97, 97, 97, 97, 2, 2, 2, 2, 97, 97, 97, 97, 2, 2, - 97, 97, 97, 97, 97, 97, 57, 57, 57, 57, 2, 57, 57, 2, 2, 2, - 2, 2, 57, 57, 57, 57, 57, 57, 57, 57, 2, 57, 57, 57, 2, 57, - 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 2, 2, 57, 57, 57, 2, 2, 2, 2, 57, 57, 2, - 2, 2, 2, 2, 2, 2, 88, 88, 88, 88, 88, 88, 88, 88,117,117, - 117,117,117,117,117,117,112,112,112,112,112,112,112,112,112,112, - 112,112,112,112,112, 2, 2, 2, 2,112,112,112,112,112, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 2, 2, 2, 78, - 78, 78, 78, 78, 78, 78, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 2, 2, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 2, 2, 2, 2, 2,122,122,122,122,122,122,122,122,122,122, - 2, 2, 2, 2, 2, 2, 2,122,122,122,122, 2, 2, 2, 2,122, - 122,122,122,122,122,122, 89, 89, 89, 89, 89, 89, 89, 89, 89, 2, - 2, 2, 2, 2, 2, 2,130,130,130,130,130,130,130,130,130,130, - 130, 2, 2, 2, 2, 2, 2, 2,130,130,130,130,130,130,144,144, - 144,144,144,144,144,144,144,144, 2, 2, 2, 2, 2, 2,165,165, - 165,165,165,165,165,165,165,165,165,165,165,165, 2, 2, 2,165, - 165,165,165,165,165,165, 2, 2, 2, 2, 2, 2,165,165,156,156, + 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 2, 62, 62, 76, 76, + 76, 76, 76, 76, 76, 76, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 2, 2, 2, 2, 2, 2, 2, 2, 93, 93, 93, 93, 70, 70, + 70, 70, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 70, 70, 70, 70, + 2, 2, 2, 70, 70, 70, 73, 73, 73, 73, 73, 73, 73, 73, 6, 6, + 6, 2, 2, 2, 2, 2, 8, 8, 8, 2, 2, 8, 8, 8, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, + 0, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, + 9, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, 9, + 19, 19, 19, 19, 9, 9, 9, 9, 9, 19, 19, 19, 19, 19, 6, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 9, 9, + 9, 9, 9, 9, 2, 2, 2, 9, 2, 9, 2, 9, 2, 9, 9, 9, + 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 2, 2, 9, 9, 9, 9, + 9, 9, 2, 9, 9, 9, 2, 2, 9, 9, 9, 2, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 2, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 19, 2, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 2, 19, 19, + 19, 19, 19, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 1, 2, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, + 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 19, 0, + 0, 0, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 2, 27, 27, + 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 2, 2, 0, 0, 56, 56, + 56, 56, 56, 56, 56, 56, 55, 55, 55, 55, 2, 2, 2, 2, 2, 55, + 55, 55, 55, 55, 55, 55, 61, 61, 61, 61, 61, 61, 61, 61, 2, 2, + 2, 2, 2, 2, 2, 61, 61, 2, 2, 2, 2, 2, 2, 2, 0, 0, + 0, 0, 0, 0, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 13, 13, + 13, 13, 13, 13, 2, 2, 0, 0, 0, 0, 0, 13, 0, 13, 0, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 13, 13, + 13, 13, 0, 0, 0, 0, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 1, + 1, 0, 0, 15, 15, 15, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 17, 17, 17, 2, 2, + 2, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 2, 2, + 2, 2, 2, 2, 2, 0, 12, 12, 12, 12, 12, 12, 12, 0, 17, 17, + 17, 17, 17, 17, 17, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 2, 2, 2, 39, 39, 39, 39, 39, 39, 39, 2, 86, 86, + 86, 86, 86, 86, 86, 86, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 2, 2, 2, 2, 79, 79, 79, 79, 79, 79, 79, 79, 0, 0, + 19, 19, 19, 19, 19, 19, 0, 0, 0, 19, 19, 19, 19, 19, 2, 19, + 19, 19, 19, 19, 19, 19, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 2, 2, 2, 65, 65, 65, 65, 65, 65, 65, 65, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 2, 2, 2, 2, + 2, 2, 2, 2, 75, 75, 75, 75, 2, 2, 2, 2, 2, 2, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 0, 69, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 74, 12, 12, 12, 12, 12, 2, 2, 2, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 2, 0, 84, 84, + 2, 2, 2, 2, 84, 84, 33, 33, 33, 33, 33, 33, 33, 2, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 2, 68, 68, + 68, 68, 68, 68, 2, 2, 68, 68, 2, 2, 68, 68, 68, 68, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 2, 2, 2, 2, 2, 2, 2, + 2, 92, 92, 92, 92, 92, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 2, 2, 30, 30, 30, 30, 30, 30, 2, 19, 19, + 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 19, 19, 19, 19, + 0, 0, 2, 2, 2, 2, 87, 87, 87, 87, 87, 87, 2, 2, 87, 87, + 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 2, 2, 2, 2, 2, 2, + 2, 12, 12, 12, 12, 12, 13, 13, 2, 2, 2, 2, 2, 2, 19, 19, + 19, 19, 19, 19, 19, 2, 2, 2, 2, 4, 4, 4, 4, 4, 2, 2, + 2, 2, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 14, 14, + 14, 14, 14, 2, 14, 2, 14, 14, 2, 14, 14, 2, 14, 14, 3, 3, + 3, 3, 3, 3, 0, 0, 1, 1, 1, 1, 1, 1, 6, 6, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 3, 3, + 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 2, 2, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, + 17, 17, 17, 17, 0, 0, 2, 2, 12, 12, 12, 12, 12, 12, 2, 2, + 12, 12, 12, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 2, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 2, 49, 49, 49, 2, 49, 49, 2, 49, 49, 49, + 49, 49, 49, 49, 2, 2, 49, 49, 49, 2, 2, 2, 2, 2, 0, 0, + 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, + 0, 0, 0, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 2, 0, 0, + 0, 0, 0, 1, 2, 2, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 2, 2, 2, 67, 67, 67, 67, 67, 67, 67, 67, 67, 2, + 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 42, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 2, 2, 2, 2, 2,118,118,118,118,118,118,118,118,118,118, + 118, 2, 2, 2, 2, 2, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 2, 53, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 2, 2, 2, 2, 59, 59, 59, 59, 59, 59, 2, 2, 40, 40, + 40, 40, 40, 40, 40, 40, 51, 51, 51, 51, 51, 51, 51, 51, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 2, 2, 50, 50, + 2, 2, 2, 2, 2, 2,135,135,135,135,135,135,135,135,135,135, + 135,135, 2, 2, 2, 2,106,106,106,106,106,106,106,106,104,104, + 104,104,104,104,104,104,104,104,104,104, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2,104,161,161,161,161,161,161,161,161,161,161, + 161, 2,161,161,161,161,161,161,161, 2,161,161, 2,161,161,161, + 2,161,161,161,161,161,161,161, 2,161,161, 2, 2, 2,170,170, + 170,170,170,170,170,170,170,170,170,170, 2, 2, 2, 2,110,110, + 110,110,110,110,110,110,110,110,110,110,110,110,110, 2,110,110, + 110,110,110,110, 2, 2, 19, 19, 19, 19, 19, 19, 2, 19, 19, 2, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 2, 2, 2, 2, 2, 47, 47, + 47, 47, 47, 47, 2, 2, 47, 2, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 2, 47, 47, 2, + 2, 2, 47, 2, 2, 47, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 2, 81,120,120,120,120,120,120,120,120,116,116, + 116,116,116,116,116,116,116,116,116,116,116,116,116, 2, 2, 2, + 2, 2, 2, 2, 2,116,128,128,128,128,128,128,128,128,128,128, + 128, 2,128,128, 2, 2, 2, 2, 2,128,128,128,128,128, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 2, 2, 2, 66, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 2, 2, 2, 2, 2, 72,173,173, + 173,173,173,173,173,173,173,173, 2, 2, 2, 2, 2, 2, 98, 98, + 98, 98, 98, 98, 98, 98, 97, 97, 97, 97, 97, 97, 97, 97, 2, 2, + 2, 2, 97, 97, 97, 97, 2, 2, 97, 97, 97, 97, 97, 97, 57, 57, + 57, 57, 2, 57, 57, 2, 2, 2, 2, 2, 57, 57, 57, 57, 57, 57, + 57, 57, 2, 57, 57, 57, 2, 57, 57, 57, 57, 57, 57, 57, 57, 57, + 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 2, 2, 57, 57, + 57, 2, 2, 2, 2, 57, 57, 2, 2, 2, 2, 2, 2, 2, 88, 88, + 88, 88, 88, 88, 88, 88,117,117,117,117,117,117,117,117,112,112, + 112,112,112,112,112,112,112,112,112,112,112,112,112, 2, 2, 2, + 2,112,112,112,112,112, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 2, 2, 2, 78, 78, 78, 78, 78, 78, 78, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 2, 2, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, 82, 2, 2, 2, 2, 2,122,122, + 122,122,122,122,122,122,122,122, 2, 2, 2, 2, 2, 2, 2,122, + 122,122,122, 2, 2, 2, 2,122,122,122,122,122,122,122, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 2, 2, 2, 2, 2, 2, 2,130,130, + 130,130,130,130,130,130,130,130,130, 2, 2, 2, 2, 2, 2, 2, + 130,130,130,130,130,130,144,144,144,144,144,144,144,144,144,144, + 2, 2, 2, 2, 2, 2,165,165,165,165,165,165,165,165,165,165, + 165,165,165,165, 2, 2, 2,165,165,165,165,165,165,165, 2, 2, + 2, 2, 2, 2,165,165, 3, 3, 3, 3, 3, 3, 3, 2,156,156, 156,156,156,156,156,156,156,156, 2,156,156,156, 2, 2,156,156, - 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 2, - 2, 2, 3, 3, 3, 3,147,147,147,147,147,147,147,147,148,148, + 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 2, + 2, 2, 2, 2, 2, 2,147,147,147,147,147,147,147,147,148,148, 148,148,148,148,148,148,148,148, 2, 2, 2, 2, 2, 2,158,158, 158,158,158,158,158,158,158,158, 2, 2, 2, 2, 2, 2,153,153, 153,153,153,153,153,153,153,153,153,153, 2, 2, 2, 2,149,149, @@ -2039,46 +1854,51 @@ _hb_ucd_u8[17612] = 143,143,143,143, 2,143,143, 2,143,143,143,143,143,143,143,143, 143,143,143,143,143,143,143,143,143,143,143,143,143, 2,143,143, 2,143,143,143,143,143,143, 2, 2, 2, 2, 2, 2, 2,143,143, - 2, 2, 2, 2, 2, 2,145,145,145,145,145,145,145,145,145, 2, - 2, 2, 2, 2, 2, 2,163,163,163,163,163,163,163,163,163, 2, - 163,163,163,163,163,163,163,163,163, 2, 2, 2,163,163,163,163, - 163, 2, 2, 2, 2, 2, 86, 2, 2, 2, 2, 2, 2, 2, 22, 22, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 22, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, 2, 2, 2, 2, 2, 2, 63, 63, - 63, 63, 63, 63, 63, 2, 63, 63, 63, 63, 63, 2, 2, 2, 63, 63, - 63, 63, 2, 2, 2, 2,157,157,157,157,157,157,157,157,157,157, - 157, 2, 2, 2, 2, 2, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 2, 2, 80, 80, 80, 2, 2, 2, 2, 2,127,127, - 127,127,127,127,127,127,127,127,127,127,127,127,127, 2,166,166, - 166,166,166,166,166,166,166,166, 2, 2, 2, 2, 2, 2, 79, 2, - 2, 2, 2, 2, 2, 2,115,115,115,115,115,115,115,115,115,115, - 115,115,115,115,115, 2,115,115, 2, 2, 2, 2,115,115,159,159, - 159,159,159,159,159,159,159,159,159,159,159,159,159, 2,159,159, - 2, 2, 2, 2, 2, 2,103,103,103,103,103,103,103,103,103,103, - 103,103,103,103, 2, 2,119,119,119,119,119,119,119,119,119,119, - 119,119,119,119, 2, 2,119,119, 2,119,119,119,119,119, 2, 2, - 2, 2, 2,119,119,119,167,167,167,167,167,167,167,167,167,167, - 2, 2, 2, 2, 2, 2,146,146,146,146,146,146,146,146,146,146, - 146, 2, 2, 2, 2, 2, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 2, 2, 2, 2, 2, 2,175,175,175,175,175,175,175,175,175,175, + 175,175, 2, 2, 2, 2,175,175, 2, 2, 2, 2, 2, 2,145,145, + 145,145,145,145,145,145,145, 2, 2, 2, 2, 2, 2, 2,163,163, + 163,163,163,163,163,163,163, 2,163,163,163,163,163,163,163,163, + 163, 2, 2, 2,163,163,163,163,163, 2, 2, 2, 2, 2, 86, 2, + 2, 2, 2, 2, 2, 2, 22, 22, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 22, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, + 2, 2, 2, 2, 2, 2, 63, 63, 63, 63, 63, 63, 63, 2, 63, 63, + 63, 63, 63, 2, 2, 2, 63, 63, 63, 63, 2, 2, 2, 2,157,157, + 157,157,157,157,157,157,157,157,157, 2, 2, 2, 2, 2, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 2, 2, 80, 80, + 80, 2, 2, 2, 2, 2,127,127,127,127,127,127,127,127,127,127, + 127,127,127,127,127, 2,166,166,166,166,166,166,166,166,166,166, + 2, 2, 2, 2, 2, 2, 79, 2, 2, 2, 2, 2, 2, 2,115,115, + 115,115,115,115,115,115,115,115,115,115,115,115,115, 2,115,115, + 2, 2, 2, 2,115,115,159,159,159,159,159,159,159,159,159,159, + 159,159,159,159,159, 2,159,159, 2, 2, 2, 2, 2, 2,103,103, + 103,103,103,103,103,103,103,103,103,103,103,103, 2, 2,119,119, + 119,119,119,119,119,119,119,119,119,119,119,119, 2, 2,119,119, + 2,119,119,119,119,119, 2, 2, 2, 2, 2,119,119,119,167,167, + 167,167,167,167,167,167,167,167, 2, 2, 2, 2, 2, 2,146,146, + 146,146,146,146,146,146,146,146,146, 2, 2, 2, 2, 2,172,172, + 172,172,172,172,172,172,172, 2, 2,172,172,172,172,172,172,172, + 172,172, 2, 2, 2, 2, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 2, 2, 2, 2, 99, 2, 2, 2, 2, 2, 2, 2, 99,136,139, - 13, 13,155, 2, 2, 2,136,136,136,136,136,136,136,136,155,155, - 155,155,155,155,155,155,155,155,155,155,155,155, 2, 2, 2, 2, - 2, 2, 2, 2, 2,155,136, 2, 2, 2, 2, 2, 2, 2, 17, 17, + 13, 13,155, 2, 2, 2, 13, 13, 13, 13, 13, 13, 13, 2,136,136, + 136,136,136,136,136,136,155,155,155,155,155,155,155,155,155,155, + 155,155,155,155, 2, 2, 2, 2, 2, 2, 2, 2, 2,155,136,136, + 136,136,136,136,136, 2,136,136,136, 2, 2, 2, 2, 2, 17, 17, 17, 17, 2, 17, 17, 17, 17, 17, 17, 17, 2, 17, 17, 2, 17, 15, 15, 15, 15, 15, 15, 15, 17, 17, 17, 2, 2, 2, 2, 2, 2, 2, 15, 2, 2, 2, 2, 2, 15, 15, 15, 2, 2, 17, 2, 2, 2, 2, 2, 2, 17, 17, 17, 17,139,139,139,139,139,139,139,139,139,139, 139,139, 2, 2, 2, 2,105,105,105,105,105,105,105,105,105,105, 105, 2, 2, 2, 2, 2,105,105,105,105,105, 2, 2, 2,105, 2, - 2, 2, 2, 2, 2, 2,105,105, 2, 2,105,105,105,105, 1, 1, - 1, 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, + 2, 2, 2, 2, 2, 2,105,105, 2, 2,105,105,105,105, 2, 2, + 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 1, 1, + 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 2, 2, 0, 2, 2, 0, 0, 2, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, - 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, - 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 2, 2, 2, - 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0,131,131, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 2, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0,131,131, 131,131,131,131,131,131,131,131,131,131, 2, 2, 2, 2, 2, 2, 2,131,131,131,131,131, 2,131,131,131,131,131,131,131, 2, 2, 2, 2, 2, 19, 19, 19, 56, 56, 56, 56, 56, 56, 56, 2, 56, 2, @@ -2090,7 +1910,9 @@ _hb_ucd_u8[17612] = 160,160,160,160,160, 2,152,152,152,152,152,152,152,152,152,152, 2, 2, 2, 2, 2,152,164,164,164,164,164,164,164,164,164,164, 2, 2, 2, 2, 2, 2,168,168,168,168,168,168,168,168,168,168, - 168, 2, 2, 2, 2,168, 30, 30, 30, 30, 2, 30, 30, 2,113,113, + 168, 2, 2, 2, 2,168,174,174,174,174,174,174,174,174,174,174, + 174,174,174,174,174, 2,174,174,174,174,174,174, 2, 2, 2, 2, + 2, 2, 2, 2,174,174, 30, 30, 30, 30, 2, 30, 30, 2,113,113, 113,113,113,113,113,113,113,113,113,113,113, 2, 2,113,113,113, 113,113,113,113,113, 2,132,132,132,132,132,132,132,132,132,132, 132,132, 2, 2, 2, 2,132,132, 2, 2, 2, 2,132,132, 3, 3, @@ -2101,8 +1923,8 @@ _hb_ucd_u8[17612] = 3, 3, 3, 2, 3, 2, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 15, 0, - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 2, 2, - 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 13, 2, 2, 2, 2, 2, 2, 2, 13, 13, 13, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 10, 9, 11, 12, 13, @@ -2186,8 +2008,7 @@ _hb_ucd_u8[17612] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, }; -static const uint16_t -_hb_ucd_u16[10400] = +static const uint16_t _hb_ucd_u16[10832]= { 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12, 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23, @@ -2210,27 +2031,29 @@ _hb_ucd_u16[10400] = 48, 48, 48, 48, 168, 169, 48, 48, 168, 48, 48, 170, 171, 172, 48, 48, 48, 171, 48, 48, 48, 173, 174, 175, 48, 176, 9, 9, 9, 9, 9, 177, 178, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 179, 48, 180, 181, 48, 48, 48, 48, 182, 183, 48, 184, 48, 185, 48, 186, 187, 188, 48, 48, 48, 189, 190, 191, 192, 193, 194, 192, 48, 48, 195, 48, 48, 196, 197, 48, 198, 48, 48, 48, 48, 199, 48, 200, 201, 202, 203, 48, 204, 205, 48, 48, 206, 48, 207, 208, 209, 209, - 48, 210, 48, 48, 48, 211, 212, 213, 192, 192, 214, 215, 216, 140, 140, 140, - 217, 48, 48, 218, 219, 160, 220, 221, 222, 48, 223, 64, 48, 48, 224, 225, - 48, 48, 226, 227, 228, 64, 48, 229, 230, 9, 9, 231, 232, 233, 234, 235, - 11, 11, 236, 27, 27, 27, 237, 238, 11, 239, 27, 27, 32, 32, 32, 32, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 240, 13, 13, 13, 13, 13, 13, - 241, 242, 241, 241, 242, 243, 241, 244, 245, 245, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, 271, 272, 272, 273, 274, 275, 209, 276, 277, 209, 278, - 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, - 280, 209, 281, 209, 209, 209, 209, 282, 209, 283, 279, 284, 209, 285, 286, 209, - 209, 209, 176, 140, 287, 140, 271, 271, 271, 288, 209, 209, 209, 209, 289, 271, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 290, 291, 209, 209, 292, - 209, 209, 209, 209, 209, 209, 293, 209, 209, 209, 209, 209, 209, 209, 209, 209, - 209, 209, 209, 209, 209, 209, 294, 295, 271, 296, 209, 209, 297, 279, 298, 279, + 48, 210, 48, 48, 48, 211, 212, 213, 192, 192, 214, 215, 32, 216, 217, 140, + 218, 48, 48, 219, 220, 160, 221, 222, 223, 48, 224, 64, 48, 48, 225, 226, + 48, 48, 227, 228, 229, 64, 48, 230, 231, 9, 9, 232, 233, 234, 235, 236, + 11, 11, 237, 27, 27, 27, 238, 239, 11, 240, 27, 27, 32, 32, 32, 32, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 241, 13, 13, 13, 13, 13, 13, + 242, 243, 242, 242, 243, 244, 242, 245, 246, 246, 246, 247, 248, 249, 250, 251, + 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 273, 274, 275, 276, 209, 277, 278, 209, 279, + 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, + 281, 209, 282, 209, 209, 209, 209, 283, 209, 284, 280, 285, 209, 286, 287, 209, + 209, 209, 176, 140, 288, 140, 272, 272, 272, 289, 209, 209, 209, 209, 290, 272, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 291, 292, 209, 209, 293, + 209, 209, 209, 209, 209, 209, 294, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 209, 209, 209, 209, 209, 209, 295, 296, 272, 297, 209, 209, 298, 280, 299, 280, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, - 279, 279, 279, 279, 279, 279, 279, 279, 299, 300, 279, 279, 279, 301, 279, 302, - 209, 209, 209, 279, 303, 209, 209, 304, 209, 305, 209, 209, 209, 209, 209, 209, + 280, 280, 280, 280, 280, 280, 280, 280, 300, 301, 280, 280, 280, 302, 280, 303, + 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, + 209, 209, 209, 280, 304, 209, 209, 305, 209, 209, 209, 209, 209, 209, 209, 209, 9, 9, 9, 11, 11, 11, 306, 307, 13, 13, 13, 13, 13, 13, 308, 309, 11, 11, 310, 48, 48, 48, 311, 312, 48, 313, 314, 314, 314, 314, 32, 32, 315, 316, 317, 318, 319, 320, 140, 140, 209, 321, 209, 209, 209, 209, 209, 322, @@ -2238,226 +2061,201 @@ _hb_ucd_u16[10400] = 324, 325, 326, 327, 136, 48, 48, 48, 48, 328, 178, 48, 48, 48, 48, 329, 330, 48, 48, 136, 48, 48, 48, 48, 200, 331, 48, 48, 209, 209, 332, 48, 209, 333, 334, 209, 335, 336, 209, 209, 334, 209, 209, 336, 209, 209, 209, 209, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 209, 209, 209, 209, 48, 337, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 151, 209, 209, 209, 338, 48, 48, 229, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 151, 209, 209, 209, 338, 48, 48, 230, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 339, 48, 340, 140, 13, 13, 341, 342, 13, 343, 48, 48, 48, 48, 344, 345, 31, 346, 347, 348, 13, 13, 13, 349, 350, 351, 352, 353, 354, 355, 140, 356, 357, 48, 358, 359, 48, 48, 48, 360, 361, 48, 48, 362, 363, 192, 32, 364, 64, 48, 365, 48, 366, 367, 48, 151, 76, 48, 48, 368, 369, 370, 371, 372, 48, 48, 373, 374, 375, 376, 48, 377, 48, 48, 48, 378, 379, 380, 381, 382, 383, 384, 314, 11, 11, 385, 386, 11, 11, 11, 11, 11, 48, 48, 387, 192, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 388, 48, 389, 48, 48, 206, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, + 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, 207, 140, 140, 392, 393, 394, 395, 396, 48, 48, 48, 48, 48, 48, 397, 398, 399, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 400, 209, 48, 48, 48, 48, 401, 48, 48, 402, 140, 140, 403, 32, 404, 32, 405, 406, 407, 408, 409, 48, 48, 48, 48, 48, 48, 48, 410, 411, 2, 3, 4, 5, 412, 413, 414, 48, 415, 48, 200, 416, 417, 418, 419, 420, 48, 172, 421, 204, 204, 140, 140, 48, 48, 48, 48, 48, 48, 48, 71, - 422, 271, 271, 423, 272, 272, 272, 424, 425, 426, 427, 140, 140, 209, 209, 428, + 422, 272, 272, 423, 273, 273, 273, 424, 425, 426, 427, 140, 140, 209, 209, 428, 140, 140, 140, 140, 140, 140, 140, 140, 48, 151, 48, 48, 48, 100, 429, 430, 48, 48, 431, 48, 432, 48, 48, 433, 48, 434, 48, 48, 435, 436, 140, 140, 9, 9, 437, 11, 11, 48, 48, 48, 48, 204, 192, 9, 9, 438, 11, 439, 48, 48, 440, 48, 48, 48, 441, 442, 442, 443, 444, 445, 48, 48, 48, 388, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 313, 48, 199, 440, 140, 446, 27, 27, 447, 140, 140, 140, 140, 448, 48, 48, 449, 48, 450, 48, 451, 48, 200, 452, 140, 140, 140, 48, 453, - 48, 454, 48, 455, 140, 140, 140, 140, 48, 48, 48, 456, 271, 457, 271, 271, + 48, 454, 48, 455, 48, 207, 140, 140, 48, 48, 48, 456, 272, 457, 272, 272, 458, 459, 48, 460, 461, 462, 48, 463, 48, 464, 140, 140, 465, 48, 466, 467, 48, 48, 48, 468, 48, 469, 48, 470, 48, 471, 472, 140, 140, 140, 140, 140, 48, 48, 48, 48, 196, 140, 140, 140, 9, 9, 9, 473, 11, 11, 11, 474, 48, 48, 475, 192, 476, 9, 477, 11, 478, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 271, 479, 48, 48, 480, 481, 482, 140, 140, 483, - 48, 464, 484, 48, 62, 485, 140, 48, 486, 140, 140, 48, 487, 140, 48, 313, - 488, 48, 48, 489, 490, 457, 491, 492, 222, 48, 48, 493, 494, 48, 196, 192, - 495, 48, 496, 497, 498, 48, 48, 499, 222, 48, 48, 500, 501, 502, 503, 504, - 48, 97, 505, 506, 507, 140, 140, 140, 508, 509, 510, 48, 48, 511, 512, 192, - 513, 83, 84, 514, 515, 516, 517, 518, 519, 48, 48, 520, 521, 522, 523, 140, - 48, 48, 48, 524, 525, 526, 481, 140, 48, 48, 48, 527, 528, 192, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 529, 530, 531, 532, 140, 140, - 48, 48, 48, 533, 534, 192, 535, 140, 48, 48, 536, 537, 192, 538, 539, 140, - 48, 540, 541, 542, 313, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 48, 505, 543, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 544, - 545, 546, 48, 547, 548, 192, 140, 140, 140, 140, 549, 48, 48, 550, 551, 140, - 552, 48, 48, 553, 554, 555, 48, 48, 556, 557, 558, 48, 48, 48, 48, 196, - 559, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 560, 192, - 84, 48, 529, 561, 562, 148, 175, 563, 48, 564, 565, 566, 140, 140, 140, 140, - 567, 48, 48, 568, 569, 192, 570, 48, 571, 572, 192, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 573, - 574, 115, 48, 575, 576, 577, 140, 140, 140, 140, 140, 100, 271, 578, 579, 580, + 140, 140, 140, 140, 140, 140, 272, 479, 48, 48, 480, 481, 482, 483, 140, 484, + 48, 464, 485, 48, 62, 486, 140, 48, 487, 140, 140, 48, 488, 140, 48, 313, + 489, 48, 48, 490, 491, 457, 492, 493, 223, 48, 48, 494, 495, 48, 196, 192, + 496, 48, 497, 498, 499, 48, 48, 500, 223, 48, 48, 501, 502, 503, 504, 505, + 48, 97, 506, 507, 508, 140, 140, 140, 509, 510, 511, 48, 48, 512, 513, 192, + 514, 83, 84, 515, 516, 517, 518, 519, 520, 48, 48, 521, 522, 523, 524, 140, + 48, 48, 48, 525, 526, 527, 481, 140, 48, 48, 48, 528, 529, 192, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 530, 531, 532, 533, 140, 140, + 48, 48, 48, 534, 535, 192, 536, 140, 48, 48, 537, 538, 192, 539, 540, 140, + 48, 541, 542, 543, 313, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 506, 544, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 545, + 546, 547, 48, 548, 549, 192, 140, 140, 140, 140, 550, 48, 48, 551, 552, 140, + 553, 48, 48, 554, 555, 556, 48, 48, 557, 558, 559, 48, 48, 48, 48, 196, + 560, 140, 140, 140, 140, 140, 561, 140, 140, 140, 140, 140, 48, 48, 562, 192, + 84, 48, 530, 563, 564, 148, 175, 565, 48, 566, 567, 568, 140, 140, 140, 140, + 569, 48, 48, 570, 571, 192, 572, 48, 573, 574, 192, 48, 48, 575, 192, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 576, + 577, 115, 48, 578, 579, 580, 140, 140, 140, 140, 140, 100, 272, 581, 582, 583, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 207, 140, 140, 140, 140, 140, 140, - 272, 272, 272, 272, 272, 272, 581, 582, 48, 48, 48, 48, 48, 48, 48, 48, + 273, 273, 273, 273, 273, 273, 584, 585, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 388, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 583, - 48, 48, 48, 584, 585, 586, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 586, + 48, 48, 48, 587, 588, 589, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 71, 48, 48, 48, 48, 313, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 587, 588, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 48, 48, 196, 48, 200, 370, 48, 48, 48, 48, 200, 192, 48, 204, 589, - 48, 48, 48, 590, 591, 592, 593, 594, 48, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 595, 48, 596, 192, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 9, 9, 11, 11, 271, 597, 140, 140, 140, 140, 140, 140, - 48, 48, 48, 48, 598, 599, 600, 600, 601, 602, 140, 140, 140, 140, 603, 604, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 440, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 199, 140, 605, - 196, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 606, - 48, 48, 607, 608, 140, 609, 610, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 590, 591, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 196, 48, 200, 370, 48, 48, 48, 48, 200, 192, 48, 204, 592, + 48, 48, 48, 593, 594, 595, 596, 597, 48, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 598, 48, 599, 192, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 9, 9, 11, 11, 272, 600, 9, 601, 11, 602, 140, 140, + 48, 48, 48, 48, 603, 604, 605, 605, 606, 607, 140, 140, 140, 140, 608, 609, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 199, 140, 610, + 48, 200, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 48, 611, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 612, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 611, 613, 140, 614, 615, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 206, - 48, 48, 48, 48, 48, 48, 71, 151, 196, 611, 612, 140, 140, 140, 140, 140, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 192, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 322, 140, 140, 140, 140, - 32, 32, 613, 32, 614, 209, 209, 209, 209, 209, 209, 209, 322, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 48, 48, 48, 71, 151, 196, 616, 617, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 618, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 619, 209, 427, 209, 620, + 32, 32, 216, 32, 621, 209, 209, 209, 209, 209, 209, 209, 322, 140, 140, 140, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 323, - 209, 209, 615, 209, 209, 209, 616, 617, 618, 209, 619, 209, 209, 209, 287, 140, - 209, 209, 209, 209, 620, 140, 140, 140, 140, 140, 140, 140, 271, 621, 271, 621, - 209, 209, 209, 209, 209, 338, 271, 461, 140, 140, 140, 140, 140, 140, 140, 140, - 9, 622, 11, 623, 624, 625, 241, 9, 626, 627, 628, 629, 630, 9, 622, 11, - 631, 632, 11, 633, 634, 635, 636, 9, 637, 11, 9, 622, 11, 623, 624, 11, - 241, 9, 626, 636, 9, 637, 11, 9, 622, 11, 638, 9, 639, 640, 641, 642, - 11, 643, 9, 644, 645, 646, 647, 11, 648, 9, 649, 11, 650, 538, 538, 538, - 32, 32, 32, 651, 32, 32, 652, 653, 654, 655, 45, 140, 140, 140, 140, 140, - 656, 657, 658, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 659, 660, 661, 27, 27, 27, 662, 140, 663, 140, 140, 140, 140, 140, 140, 140, - 48, 48, 151, 664, 665, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 666, 140, 48, 48, 667, 668, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 669, 192, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 587, 670, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 671, 200, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 672, 614, 140, 140, - 9, 9, 626, 11, 673, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 503, 271, 271, 674, 675, 140, 140, 140, 140, - 503, 271, 676, 677, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 678, 48, 679, 680, 681, 682, 683, 684, 685, 206, 686, 206, 140, 140, 140, 687, - 209, 209, 688, 209, 209, 209, 209, 209, 209, 322, 333, 689, 689, 689, 209, 323, - 690, 209, 209, 209, 209, 209, 209, 209, 209, 209, 691, 140, 140, 140, 692, 209, - 693, 209, 209, 688, 694, 695, 323, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 696, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 697, 426, 426, - 209, 209, 209, 209, 209, 209, 209, 698, 209, 209, 209, 209, 209, 176, 688, 427, - 688, 209, 209, 209, 699, 176, 209, 209, 699, 209, 691, 688, 695, 140, 140, 140, - 209, 209, 209, 209, 209, 322, 691, 426, 700, 209, 209, 209, 701, 702, 176, 694, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 703, 209, 209, 209, 209, 209, 192, + 209, 209, 622, 209, 209, 209, 623, 624, 625, 209, 626, 209, 209, 209, 288, 140, + 209, 209, 209, 209, 627, 140, 140, 140, 140, 140, 140, 140, 272, 628, 272, 628, + 209, 209, 209, 209, 209, 338, 272, 461, 140, 140, 140, 140, 140, 140, 140, 140, + 9, 629, 11, 630, 631, 632, 242, 9, 633, 634, 635, 636, 637, 9, 629, 11, + 638, 639, 11, 640, 641, 642, 643, 9, 644, 11, 9, 629, 11, 630, 631, 11, + 242, 9, 633, 643, 9, 644, 11, 9, 629, 11, 645, 9, 646, 647, 648, 649, + 11, 650, 9, 651, 652, 653, 654, 11, 655, 9, 656, 11, 657, 539, 539, 539, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 32, 32, 32, 658, 32, 32, 659, 660, 661, 662, 45, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 663, 664, 665, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 666, 667, 668, 27, 27, 27, 669, 140, 670, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 151, 671, 672, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 673, 140, 48, 48, 674, 675, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 676, 192, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 590, 677, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 200, 678, 679, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 680, 200, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 681, 621, 140, 140, + 9, 9, 633, 11, 682, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 504, 272, 272, 683, 684, 140, 140, 140, 140, + 504, 272, 685, 686, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 687, 48, 688, 689, 690, 691, 692, 693, 694, 206, 695, 206, 140, 140, 140, 696, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 209, 209, 697, 209, 209, 209, 209, 209, 209, 322, 333, 698, 698, 698, 209, 323, + 699, 209, 209, 209, 209, 209, 209, 209, 209, 209, 700, 140, 140, 140, 701, 209, + 702, 209, 209, 697, 703, 704, 323, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 705, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 706, 426, 426, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 176, 697, 427, + 697, 209, 209, 209, 707, 176, 209, 209, 707, 209, 700, 697, 704, 708, 140, 140, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 209, 209, 209, 209, 209, 707, 700, 426, 709, 209, 209, 209, 710, 711, 712, 703, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 713, 209, 209, 209, 209, 209, 714, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, - 48, 48, 48, 207, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 481, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 100, 48, 48, 48, 48, 48, 48, 204, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 204, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 48, 48, 48, 71, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, 140, 140, 140, - 704, 140, 584, 584, 584, 584, 584, 584, 140, 140, 140, 140, 140, 140, 140, 140, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 140, - 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 705, - 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 706, - 0, 1, 2, 3, 4, 4, 4, 4, 4, 4, 5, 6, 7, 8, 9, 10, - 11, 11, 12, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 57, 58, 59, 60, 60, 60, 60, 61, 62, 63, 64, 65, 66, 67, 68, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, - 92, 93, 94, 95, 96, 97, 98, 7, 4, 4, 4, 4, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 110, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 112, 112, 112, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 114, 0, - 115, 116, 117, 118, 119, 120, 121, 122, 0, 123, 124, 125, 126, 126, 126, 127, - 128, 129, 130, 131, 132, 60, 133, 134, 135, 136, 0, 137, 138, 139, 0, 0, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 0, 126, 126, 126, 126, 126, 126, 126, 126, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 141, 142, 143, 143, 143, 143, 144, 11, 145, 146, 147, 4, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 166, 167, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 126, 126, 126, 126, 126, 169, 126, 170, 171, 172, 19, 173, - 19, 19, 19, 19, 174, 19, 175, 176, 177, 178, 19, 179, 180, 181, 182, 183, - 184, 185, 186, 187, 188, 189, 190, 191, 168, 168, 192, 193, 194, 195, 196, 197, - 198, 199, 200, 201, 202, 203, 204, 205, 206, 206, 206, 206, 207, 208, 209, 168, - 210, 211, 212, 213, 214, 168, 215, 216, 217, 218, 219, 220, 221, 222, 223, 168, - 224, 225, 226, 227, 228, 229, 230, 168, 168, 231, 232, 233, 234, 235, 236, 237, - 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, - 254, 255, 256, 257, 168, 168, 258, 259, 260, 261, 262, 263, 264, 265, 168, 168, - 266, 168, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 168, 168, 278, - 279, 280, 281, 168, 282, 283, 284, 168, 168, 168, 168, 285, 286, 287, 288, 289, - 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 291, 168, - 290, 292, 290, 290, 290, 293, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 294, 295, - 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, - 296, 297, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, - 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 298, - 299, 299, 299, 299, 299, 299, 299, 299, 299, 300, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 301, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 302, 302, 302, 302, 302, 302, 302, 302, 303, 304, 305, 306, 307, 308, 309, 168, - 168, 168, 168, 168, 168, 310, 168, 168, 168, 311, 312, 168, 313, 314, 315, 316, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 318, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 319, 319, 319, 319, - 319, 319, 319, 320, 321, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 322, - 323, 324, 324, 324, 325, 326, 327, 327, 327, 327, 327, 328, 168, 168, 168, 168, - 329, 330, 331, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 0, 0, 0, 332, 0, 0, 0, 0, 0, 0, 333, 168, 334, 335, 0, 336, - 0, 0, 0, 337, 338, 339, 340, 341, 189, 342, 168, 343, 0, 344, 168, 168, - 0, 345, 346, 347, 348, 349, 0, 0, 0, 0, 350, 0, 0, 0, 0, 351, - 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 353, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 354, 168, 168, 168, - 355, 356, 357, 168, 358, 359, 168, 168, 168, 168, 360, 361, 168, 168, 168, 168, - 168, 168, 168, 362, 168, 168, 168, 363, 168, 168, 168, 168, 168, 168, 168, 364, - 365, 365, 365, 366, 367, 368, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 369, 370, 168, 371, 168, 168, 168, 372, 373, 374, 375, 168, 168, 168, 168, - 376, 0, 377, 378, 0, 0, 379, 380, 381, 382, 168, 168, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 383, 0, 384, 0, 385, - 386, 387, 388, 389, 0, 0, 0, 0, 0, 390, 391, 392, 0, 0, 393, 332, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 394, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 395, 126, 126, 126, - 396, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 397, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 398, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 399, 168, 168, 168, 168, 168, 168, - 126, 126, 126, 126, 126, 126, 126, 126, 399, 168, 168, 168, 168, 168, 168, 168, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 400, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 401, 168, - 402, 0, 168, 168, 7, 7, 7, 403, 0, 1, 2, 3, 4, 4, 4, 4, + 48, 204, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 71, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 207, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 715, 140, 587, 587, 587, 587, 587, 587, 140, 140, 140, 140, 140, 140, 140, 140, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 140, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 716, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 717, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 1, 2, 2, 3, 0, 0, 0, 0, 0, 4, 0, 4, 2, 2, 5, 2, 2, 2, 5, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, - 0, 0, 0, 0, 7, 8, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 10, 11, 12, 13, 14, 14, 15, 14, 14, 14, - 14, 14, 14, 14, 16, 17, 14, 14, 18, 18, 18, 18, 18, 18, 18, 18, - 19, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 20, 21, - 21, 21, 22, 20, 21, 21, 21, 21, 21, 23, 24, 25, 25, 25, 25, 25, - 25, 26, 25, 25, 25, 27, 28, 26, 29, 30, 31, 32, 31, 31, 31, 31, - 33, 34, 35, 31, 31, 31, 36, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 29, 31, 31, 31, 31, 37, 38, 37, 37, 37, 37, 37, 37, - 37, 39, 31, 31, 31, 31, 31, 31, 40, 40, 40, 40, 40, 40, 41, 26, - 42, 42, 42, 42, 42, 42, 42, 43, 44, 44, 44, 44, 44, 45, 44, 46, - 47, 47, 47, 48, 37, 49, 31, 31, 31, 50, 51, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 52, 31, 31, 31, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 54, 53, 55, 53, 53, 53, 56, 57, 58, 59, 59, 60, 61, 62, - 57, 63, 64, 65, 66, 59, 59, 67, 68, 69, 70, 71, 71, 72, 73, 74, - 69, 75, 76, 77, 78, 71, 79, 26, 80, 81, 82, 83, 83, 84, 85, 86, - 81, 87, 88, 26, 89, 83, 90, 91, 92, 93, 94, 95, 95, 96, 97, 98, - 93, 99, 100, 101, 102, 95, 95, 26, 103, 104, 105, 106, 107, 104, 108, 109, - 104, 105, 110, 26, 111, 108, 108, 112, 113, 114, 115, 113, 113, 115, 113, 116, - 114, 117, 118, 119, 120, 113, 121, 113, 122, 123, 124, 122, 122, 124, 125, 126, - 123, 127, 128, 128, 129, 122, 130, 26, 131, 132, 133, 131, 131, 131, 131, 131, - 132, 133, 134, 131, 135, 131, 131, 131, 136, 137, 138, 139, 137, 137, 140, 141, - 138, 142, 143, 137, 144, 137, 145, 26, 146, 147, 147, 147, 147, 147, 147, 148, - 147, 147, 147, 149, 26, 26, 26, 26, 150, 151, 152, 152, 153, 152, 152, 154, - 155, 156, 152, 157, 26, 26, 26, 26, 158, 158, 158, 158, 158, 158, 158, 158, - 158, 159, 158, 158, 158, 160, 159, 158, 158, 158, 158, 159, 158, 158, 158, 161, - 158, 161, 162, 163, 26, 26, 26, 26, 164, 164, 164, 164, 164, 164, 164, 164, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 6, 0, 0, 0, 0, 7, 8, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 14, 14, 14, 14, 14, 14, 14, 16, 17, 14, 14, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 19, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 20, 21, 21, 21, 22, 20, 21, 21, 21, 21, + 21, 23, 24, 25, 25, 25, 25, 25, 25, 26, 25, 25, 25, 27, 28, 26, + 29, 30, 31, 32, 31, 31, 31, 31, 33, 34, 35, 31, 31, 31, 36, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 29, 31, 31, 31, 31, + 37, 38, 37, 37, 37, 37, 37, 37, 37, 39, 31, 31, 31, 31, 31, 31, + 40, 40, 40, 40, 40, 40, 41, 26, 42, 42, 42, 42, 42, 42, 42, 43, + 44, 44, 44, 44, 44, 45, 44, 46, 47, 47, 47, 48, 37, 49, 31, 31, + 31, 31, 50, 31, 31, 31, 31, 31, 31, 31, 31, 31, 51, 31, 31, 31, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 52, 54, 52, 52, 52, + 55, 56, 57, 58, 58, 59, 60, 61, 56, 62, 63, 64, 65, 58, 58, 66, + 67, 68, 69, 70, 70, 71, 72, 73, 68, 74, 75, 76, 77, 70, 78, 26, + 79, 80, 81, 82, 82, 83, 84, 85, 80, 86, 87, 26, 88, 82, 89, 90, + 91, 92, 93, 94, 94, 95, 96, 97, 92, 98, 99, 100, 101, 94, 94, 26, + 102, 103, 104, 105, 106, 103, 107, 108, 103, 104, 109, 26, 110, 107, 107, 111, + 112, 113, 114, 112, 112, 114, 112, 115, 113, 116, 117, 118, 119, 112, 120, 112, + 121, 122, 123, 121, 121, 123, 124, 125, 122, 126, 127, 128, 129, 121, 130, 26, + 131, 132, 133, 131, 131, 131, 131, 131, 132, 133, 134, 131, 135, 131, 131, 131, + 136, 137, 138, 139, 137, 137, 140, 141, 138, 142, 143, 137, 144, 137, 145, 26, + 146, 147, 147, 147, 147, 147, 147, 148, 147, 147, 147, 149, 26, 26, 26, 26, + 150, 151, 152, 152, 153, 152, 152, 154, 155, 156, 152, 157, 26, 26, 26, 26, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 159, 158, 158, 158, 160, 159, 158, + 158, 158, 158, 159, 158, 158, 158, 161, 158, 161, 162, 163, 26, 26, 26, 26, + 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 165, 165, 165, 165, 166, 167, 165, 165, 165, 165, 165, 168, - 169, 169, 169, 169, 169, 169, 169, 169, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 171, 172, 171, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 171, 172, - 171, 170, 172, 170, 170, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 170, - 170, 170, 170, 173, 170, 170, 170, 174, 170, 170, 170, 175, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 177, 177, 178, 178, 178, 178, 178, 178, 178, 178, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 171, 172, 171, 170, 170, 170, 170, + 170, 171, 170, 170, 170, 170, 171, 172, 171, 170, 172, 170, 170, 170, 170, 170, + 170, 170, 171, 170, 170, 170, 170, 170, 170, 170, 170, 173, 170, 170, 170, 174, + 170, 170, 170, 175, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 177, 177, + 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 179, 179, 179, 180, 181, 181, 181, 181, 181, 181, 181, 181, 181, 182, 181, 183, 184, 184, 185, 186, 187, 187, 188, 26, 189, 189, 190, 26, 191, 192, 193, 26, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 195, 194, 196, 194, 196, @@ -2466,165 +2264,215 @@ _hb_ucd_u16[10400] = 203, 203, 203, 204, 203, 205, 203, 205, 206, 203, 207, 207, 207, 208, 209, 26, 210, 210, 210, 210, 210, 211, 210, 210, 210, 212, 210, 213, 194, 194, 194, 194, 214, 214, 214, 215, 216, 216, 216, 216, 216, 216, 216, 217, 216, 216, 216, 218, - 216, 219, 216, 219, 216, 220, 9, 9, 9, 221, 26, 26, 26, 26, 26, 26, - 222, 222, 222, 222, 222, 222, 222, 222, 222, 223, 222, 222, 222, 222, 222, 222, - 224, 224, 224, 224, 224, 224, 224, 224, 225, 225, 225, 225, 225, 225, 226, 227, - 228, 228, 228, 228, 228, 228, 228, 229, 228, 230, 231, 231, 231, 231, 231, 231, - 18, 232, 165, 165, 165, 165, 165, 233, 224, 26, 234, 9, 235, 236, 237, 238, - 2, 2, 2, 2, 239, 240, 2, 2, 2, 2, 2, 241, 242, 243, 2, 244, - 2, 2, 2, 2, 2, 2, 2, 245, 14, 14, 246, 246, 14, 14, 14, 14, - 246, 246, 14, 247, 14, 14, 14, 246, 14, 14, 14, 14, 14, 14, 248, 14, - 248, 14, 249, 250, 14, 14, 251, 252, 0, 253, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 254, 0, 255, 256, 0, 257, 2, 258, 0, 0, 0, 0, - 259, 26, 9, 9, 9, 9, 260, 26, 0, 0, 0, 0, 261, 262, 4, 0, - 0, 263, 0, 0, 2, 2, 2, 2, 2, 264, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 265, 26, 26, 0, 266, 26, 26, 0, 0, 0, 0, - 267, 267, 267, 267, 267, 267, 267, 267, 0, 0, 0, 0, 0, 0, 268, 0, - 0, 0, 269, 0, 0, 0, 0, 0, 270, 270, 270, 270, 270, 270, 270, 270, - 270, 270, 270, 270, 2, 2, 2, 2, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 271, 272, 165, 165, 165, 165, 166, 167, 273, 273, - 273, 273, 273, 273, 273, 274, 275, 274, 170, 170, 172, 26, 172, 172, 172, 172, - 172, 172, 172, 172, 18, 18, 18, 18, 0, 0, 0, 276, 26, 26, 26, 26, - 277, 277, 277, 278, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 279, 26, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 280, 26, 26, 26, 0, 0, - 281, 0, 0, 0, 282, 283, 0, 284, 285, 286, 286, 286, 286, 286, 286, 286, - 286, 286, 287, 288, 289, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 291, - 292, 293, 293, 293, 293, 293, 294, 169, 169, 295, 0, 0, 293, 293, 293, 293, - 0, 0, 0, 0, 276, 296, 290, 290, 169, 169, 169, 295, 0, 0, 0, 0, - 0, 0, 0, 0, 169, 169, 169, 297, 0, 0, 290, 290, 290, 290, 290, 298, - 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 0, 0, 0, 0, 0, - 299, 299, 299, 299, 299, 299, 299, 299, 299, 300, 299, 299, 299, 299, 299, 299, - 301, 26, 302, 302, 302, 302, 302, 302, 303, 303, 303, 303, 303, 303, 303, 303, - 303, 303, 303, 303, 303, 304, 26, 26, 18, 18, 18, 18, 305, 305, 305, 305, - 305, 305, 305, 305, 305, 305, 305, 26, 0, 0, 0, 0, 306, 2, 2, 2, - 2, 307, 2, 2, 2, 2, 2, 2, 2, 308, 309, 258, 26, 26, 310, 2, - 311, 311, 311, 311, 311, 312, 0, 265, 313, 313, 313, 313, 313, 313, 313, 26, - 314, 314, 314, 314, 314, 314, 314, 314, 315, 316, 314, 317, 53, 53, 53, 53, - 318, 318, 318, 318, 318, 319, 320, 320, 320, 320, 321, 322, 169, 169, 169, 323, - 324, 324, 324, 324, 324, 324, 324, 324, 324, 325, 324, 326, 164, 164, 164, 327, - 328, 328, 328, 328, 328, 328, 329, 26, 328, 330, 328, 331, 164, 164, 164, 164, - 332, 332, 332, 332, 332, 332, 332, 332, 333, 26, 26, 334, 335, 335, 336, 26, - 337, 337, 337, 26, 172, 172, 2, 2, 2, 2, 2, 338, 339, 340, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, 335, 335, 335, 335, 335, 341, 335, 342, - 169, 169, 169, 169, 343, 26, 169, 169, 295, 344, 169, 169, 169, 169, 169, 343, - 26, 26, 26, 26, 26, 26, 26, 26, 277, 277, 277, 277, 277, 280, 277, 277, - 277, 277, 277, 345, 26, 26, 26, 26, 346, 26, 347, 348, 25, 25, 349, 350, - 351, 25, 31, 31, 31, 31, 31, 31, 352, 26, 353, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 354, 31, 31, 355, 31, 31, 31, 31, 31, - 31, 356, 26, 26, 26, 26, 31, 31, 9, 9, 0, 265, 9, 357, 0, 0, - 0, 0, 358, 0, 257, 359, 360, 31, 31, 31, 31, 31, 31, 31, 31, 361, - 362, 0, 0, 0, 1, 2, 2, 3, 1, 2, 2, 3, 363, 290, 289, 290, - 290, 290, 290, 364, 169, 169, 169, 295, 365, 365, 365, 366, 257, 257, 26, 367, - 368, 369, 368, 368, 370, 368, 368, 371, 368, 372, 368, 372, 26, 26, 26, 26, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 373, - 374, 0, 0, 0, 0, 0, 375, 0, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 252, 0, 376, 377, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 378, - 379, 379, 379, 380, 381, 381, 381, 381, 381, 381, 382, 26, 383, 0, 0, 359, - 384, 384, 384, 384, 385, 386, 387, 387, 387, 388, 389, 389, 389, 389, 389, 390, - 391, 391, 391, 392, 393, 393, 393, 393, 394, 393, 395, 26, 26, 26, 26, 26, - 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 397, 397, 397, 397, 397, 397, - 398, 398, 398, 399, 398, 400, 401, 401, 401, 401, 402, 401, 401, 401, 401, 402, - 403, 403, 403, 403, 403, 26, 404, 404, 404, 404, 404, 404, 405, 406, 407, 408, - 407, 408, 409, 407, 410, 407, 410, 411, 412, 412, 412, 412, 412, 412, 413, 26, - 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 415, 26, - 414, 414, 416, 26, 414, 26, 26, 26, 417, 2, 2, 2, 2, 2, 418, 419, - 420, 421, 422, 422, 422, 422, 423, 424, 425, 425, 426, 425, 427, 427, 427, 427, - 428, 428, 428, 429, 430, 428, 26, 26, 26, 26, 26, 26, 431, 431, 432, 433, - 434, 434, 434, 435, 436, 436, 436, 437, 438, 438, 438, 438, 439, 439, 439, 440, - 439, 439, 441, 439, 439, 439, 439, 439, 442, 443, 444, 445, 446, 446, 447, 448, - 446, 449, 446, 449, 450, 450, 450, 450, 451, 451, 451, 451, 26, 26, 26, 26, - 452, 452, 452, 452, 453, 454, 453, 26, 455, 455, 455, 455, 455, 455, 456, 457, - 458, 458, 459, 458, 460, 460, 461, 460, 462, 462, 463, 464, 26, 465, 26, 26, - 466, 466, 466, 466, 466, 466, 466, 466, 466, 467, 26, 26, 26, 26, 26, 26, - 468, 468, 468, 468, 468, 468, 469, 26, 468, 468, 468, 468, 468, 468, 469, 470, - 471, 471, 471, 471, 471, 26, 471, 472, 473, 473, 473, 473, 474, 475, 473, 473, - 474, 476, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 31, 31, 31, 50, - 477, 477, 477, 477, 477, 478, 479, 26, 480, 26, 26, 26, 26, 26, 26, 481, - 482, 482, 482, 482, 482, 26, 483, 483, 483, 483, 483, 484, 26, 26, 485, 485, - 485, 486, 26, 26, 26, 26, 487, 487, 487, 488, 26, 26, 489, 489, 490, 26, - 491, 491, 491, 491, 491, 491, 491, 491, 491, 492, 493, 491, 491, 491, 492, 494, - 495, 495, 495, 495, 495, 495, 495, 495, 496, 497, 498, 498, 498, 499, 498, 500, - 501, 501, 501, 501, 501, 501, 502, 501, 501, 26, 503, 503, 503, 503, 504, 26, - 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 506, 137, 507, 26, - 508, 508, 509, 508, 508, 508, 508, 508, 510, 26, 26, 26, 26, 26, 26, 26, - 511, 512, 513, 514, 513, 515, 516, 516, 516, 516, 516, 516, 516, 517, 516, 518, - 519, 520, 521, 522, 522, 523, 524, 525, 520, 526, 527, 528, 529, 530, 530, 26, - 531, 532, 531, 531, 531, 531, 533, 531, 534, 535, 533, 536, 537, 26, 26, 26, - 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 539, 540, 26, 26, 26, - 541, 541, 541, 541, 541, 541, 541, 541, 541, 26, 541, 542, 26, 26, 26, 26, - 543, 543, 543, 543, 543, 543, 544, 543, 543, 543, 543, 544, 26, 26, 26, 26, - 545, 545, 545, 545, 545, 545, 545, 545, 546, 26, 545, 547, 198, 548, 26, 26, - 549, 549, 549, 549, 549, 549, 549, 550, 549, 550, 164, 164, 551, 26, 26, 26, - 552, 552, 552, 553, 552, 554, 552, 552, 555, 26, 26, 26, 26, 26, 26, 26, - 556, 556, 556, 556, 556, 556, 556, 557, 26, 26, 26, 26, 558, 558, 558, 558, - 558, 558, 558, 558, 558, 558, 559, 560, 561, 562, 563, 564, 564, 564, 565, 566, - 561, 26, 564, 567, 26, 26, 26, 26, 26, 26, 26, 26, 568, 569, 568, 568, - 568, 568, 568, 569, 570, 26, 26, 26, 571, 571, 571, 571, 571, 571, 571, 571, - 571, 26, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 573, 26, 178, 178, - 574, 574, 574, 574, 574, 574, 574, 575, 53, 576, 26, 26, 26, 26, 26, 26, - 577, 577, 577, 577, 578, 26, 577, 578, 579, 580, 579, 579, 579, 579, 581, 579, - 582, 26, 579, 579, 579, 583, 584, 584, 584, 584, 585, 584, 584, 586, 587, 26, - 588, 589, 590, 590, 590, 590, 588, 591, 590, 26, 590, 592, 593, 594, 595, 595, - 595, 596, 597, 598, 595, 599, 26, 26, 26, 26, 26, 26, 600, 600, 600, 601, - 602, 602, 603, 602, 602, 602, 602, 604, 602, 602, 602, 605, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 606, 26, 108, 108, 108, 108, 108, 108, 607, 608, - 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 610, 26, 26, 26, 26, - 609, 609, 609, 609, 609, 611, 612, 26, 613, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 614, 614, 614, 614, 614, 614, 614, 614, 614, 614, 614, 614, 615, 26, - 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 617, 26, 616, 616, 616, 616, - 616, 616, 616, 616, 616, 616, 616, 618, 619, 619, 619, 619, 619, 619, 619, 619, - 620, 26, 26, 26, 26, 26, 26, 26, 621, 621, 621, 621, 621, 621, 621, 622, - 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 623, - 624, 624, 624, 625, 624, 626, 627, 627, 627, 627, 627, 627, 627, 627, 627, 628, - 627, 629, 630, 630, 630, 631, 631, 26, 632, 632, 632, 632, 632, 632, 632, 632, - 633, 26, 632, 634, 634, 632, 632, 635, 632, 632, 26, 26, 26, 26, 26, 26, - 636, 636, 636, 636, 636, 636, 636, 637, 638, 638, 638, 638, 638, 638, 638, 638, - 638, 638, 638, 639, 26, 26, 26, 26, 640, 640, 640, 640, 640, 640, 640, 640, - 640, 641, 640, 640, 640, 640, 640, 640, 640, 642, 640, 640, 26, 26, 26, 26, - 26, 26, 26, 26, 643, 26, 345, 26, 644, 644, 644, 644, 644, 644, 644, 644, - 644, 644, 644, 644, 644, 644, 644, 26, 645, 645, 645, 645, 645, 645, 645, 645, - 645, 645, 646, 26, 26, 26, 26, 647, 644, 648, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 649, 650, 651, 286, 286, 286, 286, 286, 286, 286, - 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 652, 26, 653, 26, - 26, 26, 654, 26, 655, 26, 656, 656, 656, 656, 656, 656, 656, 656, 656, 656, - 656, 656, 656, 656, 656, 656, 656, 657, 658, 658, 658, 658, 658, 658, 658, 658, - 658, 658, 658, 658, 658, 659, 658, 660, 658, 661, 658, 662, 359, 26, 26, 26, - 0, 0, 0, 0, 0, 0, 0, 265, 0, 0, 0, 0, 0, 0, 359, 26, - 9, 9, 9, 9, 9, 663, 9, 9, 221, 26, 0, 0, 0, 0, 0, 0, - 359, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 276, 26, - 0, 0, 0, 0, 257, 362, 0, 0, 0, 0, 0, 0, 664, 665, 0, 666, - 667, 668, 0, 0, 0, 669, 0, 0, 0, 0, 0, 0, 0, 266, 26, 26, - 246, 26, 26, 26, 26, 26, 26, 26, 0, 0, 359, 26, 0, 0, 359, 26, - 0, 0, 257, 26, 0, 0, 0, 259, 0, 0, 254, 0, 0, 0, 0, 0, - 0, 0, 0, 254, 670, 671, 0, 672, 673, 0, 0, 0, 0, 0, 0, 0, - 269, 674, 254, 254, 0, 0, 0, 675, 676, 677, 678, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 276, 0, 0, 0, 0, 268, 0, 0, 0, 0, 0, 0, - 679, 679, 679, 679, 679, 679, 679, 679, 679, 680, 26, 681, 682, 679, 26, 26, - 2, 2, 2, 346, 683, 419, 26, 26, 684, 270, 270, 685, 686, 687, 18, 18, - 18, 18, 18, 18, 18, 688, 26, 26, 26, 689, 26, 26, 26, 26, 26, 26, - 690, 690, 690, 690, 690, 691, 690, 692, 690, 693, 26, 26, 26, 26, 26, 26, - 26, 26, 694, 694, 694, 695, 26, 26, 696, 696, 696, 696, 696, 696, 696, 697, - 26, 26, 698, 698, 698, 698, 698, 699, 26, 26, 700, 700, 700, 700, 700, 701, - 26, 26, 26, 26, 172, 702, 170, 172, 703, 703, 703, 703, 703, 703, 703, 703, - 704, 703, 705, 26, 26, 26, 26, 26, 706, 706, 706, 706, 706, 706, 706, 706, - 706, 707, 706, 708, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 362, 0, - 0, 0, 0, 0, 0, 0, 376, 26, 362, 0, 0, 0, 0, 0, 0, 276, - 709, 31, 31, 31, 710, 711, 712, 713, 714, 715, 710, 716, 710, 712, 712, 717, - 31, 718, 31, 719, 720, 718, 31, 719, 26, 26, 26, 26, 26, 26, 721, 26, - 0, 0, 0, 0, 0, 359, 0, 0, 0, 0, 359, 26, 0, 257, 362, 0, - 362, 0, 362, 0, 0, 0, 276, 26, 0, 0, 0, 0, 0, 276, 26, 26, - 26, 26, 26, 26, 722, 0, 0, 0, 723, 26, 0, 0, 0, 0, 0, 359, - 0, 259, 265, 26, 276, 26, 26, 26, 0, 0, 0, 724, 0, 376, 0, 376, - 0, 0, 0, 0, 0, 0, 257, 725, 0, 0, 0, 265, 0, 359, 259, 26, - 0, 359, 0, 0, 0, 0, 0, 0, 0, 26, 0, 265, 0, 0, 0, 0, - 0, 26, 0, 0, 0, 276, 0, 359, 265, 26, 26, 26, 26, 26, 26, 26, - 0, 0, 359, 26, 0, 276, 0, 376, 0, 726, 0, 0, 0, 0, 0, 0, - 257, 722, 0, 727, 0, 265, 0, 259, 0, 0, 358, 0, 0, 0, 0, 0, - 277, 277, 277, 277, 26, 26, 26, 26, 277, 277, 277, 277, 277, 277, 277, 345, - 277, 277, 277, 280, 277, 277, 277, 277, 277, 277, 277, 277, 345, 26, 277, 277, - 277, 277, 277, 277, 728, 26, 277, 277, 277, 277, 277, 280, 26, 26, 26, 26, - 277, 729, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 26, 26, - 730, 26, 26, 26, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, + 216, 219, 216, 219, 216, 220, 9, 9, 9, 9, 9, 221, 9, 222, 26, 26, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 224, 223, 223, 223, 223, 223, 223, + 225, 225, 225, 225, 225, 225, 225, 225, 226, 226, 226, 226, 226, 226, 227, 228, + 229, 229, 229, 229, 229, 229, 229, 230, 229, 231, 232, 232, 232, 232, 232, 232, + 18, 233, 165, 165, 165, 165, 165, 234, 225, 26, 235, 9, 236, 237, 238, 239, + 2, 2, 2, 2, 240, 241, 2, 2, 2, 2, 2, 242, 243, 244, 2, 245, + 2, 2, 2, 2, 2, 2, 2, 246, 9, 9, 9, 9, 9, 9, 9, 9, + 14, 14, 247, 247, 14, 14, 14, 14, 247, 247, 14, 248, 14, 14, 14, 247, + 14, 14, 14, 14, 14, 14, 249, 14, 249, 14, 250, 251, 14, 14, 252, 253, + 0, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 256, 257, + 0, 258, 2, 259, 0, 0, 0, 0, 260, 26, 9, 9, 9, 9, 261, 26, + 0, 0, 0, 0, 262, 263, 4, 0, 0, 264, 0, 0, 2, 2, 2, 2, + 2, 265, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 260, 26, 26, 0, 266, 26, 26, 0, 0, 0, 0, + 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 268, 0, + 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 2, 2, 2, 2, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 270, 271, + 165, 165, 165, 165, 166, 167, 272, 272, 272, 272, 272, 272, 272, 273, 274, 273, + 170, 170, 172, 26, 172, 172, 172, 172, 172, 172, 172, 172, 18, 18, 18, 18, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, 26, 26, 26, 26, + 276, 276, 276, 277, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 278, 26, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 279, 26, 26, 26, 0, 0, + 280, 0, 0, 0, 281, 282, 0, 283, 284, 285, 285, 285, 285, 285, 285, 285, + 285, 285, 286, 287, 288, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 290, + 291, 292, 292, 292, 292, 292, 293, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 294, 0, 0, 292, 292, 292, 292, 0, 0, 0, 0, 275, 295, 289, 289, + 169, 169, 169, 294, 0, 0, 0, 0, 0, 0, 0, 0, 169, 169, 169, 296, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 289, 289, 289, 289, 289, 297, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 0, 0, 0, 0, 0, + 276, 276, 276, 276, 276, 276, 276, 276, 0, 0, 0, 0, 0, 0, 0, 0, + 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, + 298, 299, 298, 298, 298, 298, 298, 298, 300, 26, 301, 301, 301, 301, 301, 301, + 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, + 302, 302, 302, 302, 302, 303, 26, 26, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 26, + 0, 0, 0, 0, 305, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 306, 2, 2, 2, 2, 2, 2, 2, 2, 2, 259, 26, 26, 307, 2, + 308, 308, 308, 308, 308, 309, 0, 260, 310, 310, 310, 310, 310, 310, 310, 26, + 311, 311, 311, 311, 311, 311, 311, 311, 312, 313, 311, 314, 52, 52, 52, 52, + 315, 315, 315, 315, 315, 316, 317, 317, 317, 317, 318, 319, 169, 169, 169, 320, + 321, 321, 321, 321, 321, 321, 321, 321, 321, 322, 321, 323, 164, 164, 164, 324, + 325, 325, 325, 325, 325, 325, 326, 26, 325, 327, 325, 328, 164, 164, 164, 164, + 329, 329, 329, 329, 329, 329, 329, 329, 330, 26, 26, 331, 332, 332, 333, 26, + 334, 334, 334, 26, 172, 172, 2, 2, 2, 2, 2, 335, 336, 337, 176, 176, + 176, 176, 176, 176, 176, 176, 176, 176, 332, 332, 332, 332, 332, 338, 332, 339, + 169, 169, 169, 169, 340, 26, 169, 169, 294, 341, 169, 169, 169, 169, 169, 340, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 279, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 342, 26, 26, 26, 26, + 343, 26, 344, 345, 25, 25, 346, 347, 348, 25, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 349, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 26, 26, 26, 26, 31, 31, + 9, 9, 0, 260, 9, 350, 0, 0, 0, 0, 351, 0, 258, 352, 353, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 354, + 355, 0, 0, 0, 1, 2, 2, 3, 1, 2, 2, 3, 356, 289, 288, 289, + 289, 289, 289, 357, 169, 169, 169, 294, 358, 358, 358, 359, 258, 258, 26, 360, + 361, 362, 361, 361, 363, 361, 361, 364, 361, 365, 361, 365, 26, 26, 26, 26, + 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 366, + 367, 0, 0, 0, 0, 0, 368, 0, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 253, 0, 369, 370, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 371, + 372, 372, 372, 373, 374, 374, 374, 374, 374, 374, 375, 26, 376, 0, 0, 352, + 377, 377, 377, 377, 378, 379, 380, 380, 380, 381, 382, 382, 382, 382, 382, 383, + 384, 384, 384, 385, 386, 386, 386, 386, 387, 386, 388, 26, 26, 26, 26, 26, + 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 390, 390, 390, 390, 390, 390, + 391, 391, 391, 392, 391, 393, 394, 394, 394, 394, 395, 394, 394, 394, 394, 395, + 396, 396, 396, 396, 396, 26, 397, 397, 397, 397, 397, 397, 398, 399, 400, 401, + 400, 401, 402, 400, 403, 400, 403, 404, 405, 405, 405, 405, 405, 405, 406, 26, + 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, + 407, 407, 407, 407, 407, 407, 408, 26, 407, 407, 409, 26, 407, 26, 26, 26, + 410, 2, 2, 2, 2, 2, 411, 412, 26, 26, 26, 26, 26, 26, 26, 26, + 413, 414, 415, 415, 415, 415, 416, 417, 418, 418, 419, 418, 420, 420, 420, 420, + 421, 421, 421, 422, 423, 421, 26, 26, 26, 26, 26, 26, 424, 424, 425, 426, + 427, 427, 427, 428, 429, 429, 429, 430, 431, 431, 431, 432, 26, 26, 26, 26, + 433, 433, 433, 433, 434, 434, 434, 435, 434, 434, 436, 434, 434, 434, 434, 434, + 437, 438, 439, 440, 441, 441, 442, 443, 441, 444, 441, 444, 445, 445, 445, 445, + 446, 446, 446, 446, 26, 26, 26, 26, 447, 447, 447, 447, 448, 449, 448, 26, + 450, 450, 450, 450, 450, 450, 451, 452, 453, 453, 454, 453, 455, 455, 456, 455, + 457, 457, 458, 459, 26, 460, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 461, 461, 461, 461, 461, 461, 461, 461, 461, 462, 26, 26, 26, 26, 26, 26, + 463, 463, 463, 463, 463, 463, 464, 26, 463, 463, 463, 463, 463, 463, 464, 465, + 466, 466, 466, 466, 466, 26, 466, 467, 468, 468, 468, 468, 469, 470, 468, 468, + 469, 471, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 31, 31, 31, 472, + 473, 473, 473, 473, 473, 474, 475, 26, 476, 26, 31, 477, 26, 26, 26, 476, + 478, 478, 478, 478, 478, 26, 479, 479, 479, 479, 479, 480, 26, 26, 481, 481, + 481, 482, 26, 26, 26, 26, 483, 483, 483, 484, 26, 26, 485, 485, 486, 26, + 487, 487, 487, 487, 487, 487, 487, 487, 487, 488, 489, 487, 487, 487, 488, 490, + 491, 491, 491, 491, 491, 491, 491, 491, 492, 493, 494, 494, 494, 495, 494, 496, + 497, 497, 497, 497, 497, 497, 498, 497, 497, 26, 499, 499, 499, 499, 500, 26, + 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 502, 137, 503, 26, + 504, 504, 505, 504, 504, 504, 504, 504, 506, 26, 26, 26, 26, 26, 26, 26, + 507, 508, 509, 510, 509, 511, 512, 512, 512, 512, 512, 512, 512, 513, 512, 514, + 515, 516, 517, 518, 518, 519, 520, 521, 516, 522, 523, 524, 525, 526, 526, 26, + 527, 528, 527, 527, 527, 527, 529, 527, 530, 531, 529, 532, 533, 26, 26, 26, + 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 535, 536, 26, 26, 26, + 537, 537, 537, 537, 537, 537, 537, 537, 537, 26, 537, 538, 26, 26, 26, 26, + 539, 539, 539, 539, 539, 539, 540, 539, 539, 539, 539, 540, 26, 26, 26, 26, + 541, 541, 541, 541, 541, 541, 541, 541, 542, 26, 541, 543, 198, 544, 26, 26, + 545, 545, 545, 545, 545, 545, 545, 546, 545, 546, 164, 164, 547, 26, 26, 26, + 548, 548, 548, 549, 548, 550, 548, 548, 551, 26, 26, 26, 26, 26, 26, 26, + 552, 552, 552, 552, 552, 552, 552, 553, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 555, 556, + 557, 558, 559, 560, 560, 560, 561, 562, 557, 26, 560, 563, 26, 26, 26, 26, + 26, 26, 26, 26, 564, 565, 564, 564, 564, 564, 564, 565, 566, 26, 26, 26, + 567, 567, 567, 567, 567, 567, 567, 567, 567, 26, 568, 568, 568, 568, 568, 568, + 568, 568, 568, 568, 569, 26, 178, 178, 570, 570, 570, 570, 570, 570, 570, 571, + 52, 572, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 501, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 573, 573, 573, 573, 574, 26, 573, 574, + 575, 576, 575, 575, 575, 575, 577, 575, 578, 26, 575, 575, 575, 579, 580, 580, + 580, 580, 581, 580, 580, 582, 583, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 584, 585, 586, 586, 586, 586, 584, 587, 586, 26, 586, 588, 589, 590, 591, 591, + 591, 592, 593, 594, 591, 595, 596, 596, 596, 596, 596, 597, 596, 598, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 599, 599, 599, 600, + 601, 601, 602, 601, 601, 601, 601, 603, 601, 601, 601, 604, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 605, 26, 107, 107, 107, 107, 107, 107, 606, 607, + 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, + 608, 608, 608, 609, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 610, 611, 26, + 608, 608, 608, 608, 608, 608, 608, 608, 612, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 613, 613, 613, 613, 613, 613, 613, 613, 613, 613, 613, 613, 614, 26, + 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, + 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 616, 26, 615, 615, 615, 615, + 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 617, + 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, + 618, 618, 618, 618, 618, 618, 618, 618, 619, 26, 26, 26, 26, 26, 26, 26, + 620, 620, 620, 620, 620, 620, 620, 621, 26, 26, 26, 26, 26, 26, 26, 26, + 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, + 304, 304, 304, 304, 304, 304, 304, 622, 623, 623, 623, 624, 623, 625, 626, 626, + 626, 626, 626, 626, 626, 626, 626, 627, 626, 628, 629, 629, 629, 630, 630, 26, + 631, 631, 631, 631, 631, 631, 631, 631, 632, 26, 631, 633, 633, 631, 631, 634, + 631, 631, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 635, 635, 635, 635, 635, 635, 635, 636, + 26, 26, 26, 26, 26, 26, 26, 26, 637, 637, 637, 637, 637, 637, 637, 637, + 637, 637, 637, 638, 639, 639, 639, 640, 639, 639, 641, 26, 26, 26, 26, 26, + 642, 642, 642, 642, 642, 642, 642, 642, 642, 643, 642, 642, 642, 642, 642, 642, + 642, 644, 642, 642, 26, 26, 26, 26, 26, 26, 26, 26, 645, 26, 646, 26, + 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, + 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, + 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 649, 26, 26, 26, 26, 650, + 647, 647, 647, 651, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 652, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 653, 654, + 655, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, + 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, + 285, 285, 285, 285, 656, 26, 657, 26, 26, 26, 658, 26, 659, 26, 660, 660, + 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, + 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 661, + 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 663, 662, 664, + 662, 665, 662, 666, 352, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 369, + 0, 0, 0, 0, 0, 0, 352, 667, 0, 0, 668, 26, 0, 0, 668, 26, + 9, 9, 9, 9, 9, 221, 9, 9, 669, 26, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 352, 26, 26, 26, 26, 26, 26, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, 26, + 0, 0, 0, 0, 258, 355, 0, 0, 0, 0, 0, 0, 670, 671, 0, 672, + 673, 674, 0, 0, 0, 675, 0, 0, 0, 0, 0, 0, 0, 266, 26, 26, + 14, 14, 14, 14, 14, 14, 14, 14, 247, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 352, 26, 0, 0, 352, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 258, 26, 0, 0, 0, 668, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, + 0, 0, 0, 255, 676, 677, 0, 678, 679, 0, 0, 0, 0, 0, 0, 0, + 680, 681, 255, 255, 0, 0, 0, 682, 683, 667, 684, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 268, 0, 0, 0, 0, 0, 0, + 685, 685, 685, 685, 685, 685, 685, 685, 685, 685, 685, 685, 685, 685, 685, 685, + 685, 686, 26, 687, 688, 685, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 2, 2, 2, 343, 689, 412, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 690, 269, 269, 691, 692, 693, 18, 18, 18, 18, 18, 18, 18, 694, 26, 26, + 26, 695, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 696, 696, 696, 696, 696, 697, 696, 698, 696, 699, 26, 26, 26, 26, 26, 26, + 26, 26, 700, 700, 700, 701, 26, 26, 702, 702, 702, 702, 702, 702, 702, 703, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 704, 704, 704, 704, 704, 705, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 706, 706, 706, 706, 706, 707, + 26, 26, 26, 26, 26, 26, 26, 26, 708, 708, 708, 709, 708, 708, 710, 711, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 172, 712, 170, 172, + 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, + 713, 713, 713, 713, 713, 713, 713, 713, 714, 713, 715, 26, 26, 26, 26, 26, + 716, 716, 716, 716, 716, 716, 716, 716, 716, 717, 716, 718, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 355, 0, + 0, 0, 0, 0, 0, 0, 369, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 355, 0, 0, 0, 0, 0, 0, 275, 26, 26, 26, 26, 26, 26, 26, 26, + 719, 31, 31, 31, 720, 721, 722, 723, 724, 725, 720, 726, 720, 722, 722, 727, + 31, 728, 31, 729, 730, 728, 31, 729, 26, 26, 26, 26, 26, 26, 731, 26, + 0, 0, 0, 0, 0, 352, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 352, 26, 0, 258, 355, 0, 355, 0, 355, 0, 0, 0, 275, 26, + 0, 0, 0, 0, 0, 275, 26, 26, 26, 26, 26, 26, 732, 0, 0, 0, + 733, 26, 0, 0, 0, 0, 0, 352, 0, 668, 260, 26, 275, 26, 26, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 734, 0, 369, 0, 369, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 260, 0, 352, 668, 26, + 0, 352, 0, 0, 0, 0, 0, 0, 0, 26, 0, 260, 0, 0, 0, 0, + 0, 26, 0, 0, 0, 275, 0, 352, 260, 26, 0, 668, 26, 26, 26, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 275, 0, 369, + 0, 735, 0, 0, 0, 0, 0, 0, 258, 736, 0, 737, 0, 367, 0, 668, + 0, 0, 351, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 266, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 26, 26, 26, 26, + 276, 276, 276, 279, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 276, 279, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 738, 26, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 279, 26, 26, 26, 26, + 276, 276, 276, 279, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 739, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 342, + 740, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962, 969, 970, 971, 976,1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0, 0,1080,1081,1082,1086,1110, 0, 0, @@ -2840,8 +2688,7 @@ _hb_ucd_u16[10400] = 789, 928, 792, 95, 796, 797, 798, 800, 96, 929, 802, 804, 806, 97, 98, 807, 930, 99, 931, 932, 933, 814, 100, 816, 817, 818, 819, 820, 821, 935, 0, 0, }; -static const int16_t -_hb_ucd_i16[196] = +static const int16_t _hb_ucd_i16[196]= { 0, 0, 0, 0, 1, -1, 0, 0, 2, 0, -2, 0, 0, 0, 0, 2, 0, -2, 0, 0, 0, 0, 0, 16, 0, 0, 0, -16, 0, 0, 1, -1, @@ -2858,47 +2705,42 @@ _hb_ucd_i16[196] = -1, 0, 1, -1, }; -static inline uint_fast8_t -_hb_ucd_gc (unsigned u) +static inline uint8_t _hb_ucd_gc (unsigned u) { - return u<1114110u?_hb_ucd_u8[6472+(((_hb_ucd_u8[816+(((_hb_ucd_u16[((_hb_ucd_u8[272+(((_hb_ucd_u8[u>>1>>3>>4>>4])<<4)+((u>>1>>3>>4)&15u))])<<4)+((u>>1>>3)&15u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; + return u<1114110 ? _hb_ucd_u8[7920u+((_hb_ucd_u8[2176u+((_hb_ucd_u16[((_hb_ucd_u8[((((((u)>>1))>>3))>>5)])<<5)+((((((u)>>1))>>3))&31)])<<3)+((((u)>>1))&7)])<<1)+((u)&1)] : 2; } -static inline uint_fast8_t -_hb_ucd_ccc (unsigned u) +static inline uint8_t _hb_ucd_ccc (unsigned u) { - return u<125259u?_hb_ucd_u8[8504+(((_hb_ucd_u8[7936+(((_hb_ucd_u8[7460+(((_hb_ucd_u8[7100+(((_hb_ucd_u8[6854+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; + return u<125259 ? _hb_ucd_u8[10388u+((_hb_ucd_u8[9284u+((_hb_ucd_u8[8548u+((_hb_ucd_u8[8302u+((((((u)>>2))>>3))>>4)])<<4)+((((((u)>>2))>>3))&15)])<<3)+((((u)>>2))&7)])<<2)+((u)&3)] : 0; } -static inline unsigned -_hb_ucd_b4 (const uint8_t* a, unsigned i) +static inline uint8_t _hb_ucd_b4 (const uint8_t* a, unsigned i) { - return (a[i>>1]>>((i&1u)<<2))&15u; + return (a[i>>1]>>((i&1)<<2))&15; } -static inline int_fast16_t -_hb_ucd_bmg (unsigned u) +static inline int16_t _hb_ucd_bmg (unsigned u) { - return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9252+(((_hb_ucd_u8[9132+(((_hb_ucd_b4(9004+_hb_ucd_u8,u>>2>>3>>3))<<3)+((u>>2>>3)&7u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u)]:0; + return u<65380 ? _hb_ucd_i16[((_hb_ucd_u8[11140u+((_hb_ucd_u8[11020u+((_hb_ucd_b4(_hb_ucd_u8+10892u,((((((u)>>2))>>3))>>3)))<<3)+((((((u)>>2))>>3))&7)])<<3)+((((u)>>2))&7)])<<2)+((u)&3)] : 0; } -static inline uint_fast8_t -_hb_ucd_sc (unsigned u) +static inline uint8_t _hb_ucd_sc (unsigned u) { - return u<918000u?_hb_ucd_u8[10486+(((_hb_ucd_u16[3744+(((_hb_ucd_u16[2624+(((_hb_ucd_u8[9588+(u>>3>>3>>4)])<<4)+((u>>3>>3)&15u))])<<3)+((u>>3)&7u))])<<3)+((u)&7u))]:2; + return u<918000 ? _hb_ucd_u8[12662u+((_hb_ucd_u16[3328u+((_hb_ucd_u8[11926u+((_hb_ucd_u8[11476u+((((((u)>>3))>>4))>>4)])<<4)+((((((u)>>3))>>4))&15)])<<4)+((((u)>>3))&15)])<<3)+((u)&7)] : 2; } -static inline uint_fast16_t -_hb_ucd_dm (unsigned u) +static inline uint16_t _hb_ucd_dm (unsigned u) { - return u<195102u?_hb_ucd_u16[6976+(((_hb_ucd_u8[16716+(((_hb_ucd_u8[16334+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; + return u<195102 ? _hb_ucd_u16[7408u+((_hb_ucd_u8[18972u+((_hb_ucd_u8[18590u+((((u)>>4))>>5)])<<5)+((((u)>>4))&31)])<<4)+((u)&15)] : 0; } #elif !defined(HB_NO_UCD_UNASSIGNED) -static const uint8_t -_hb_ucd_u8[17524] = +#include + +static const uint8_t _hb_ucd_u8[14800]= { 0, 1, 2, 3, 4, 5, 5, 5, 5, 5, 6, 5, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, 17, 15, 18, 19, 20, 21, 22, 23, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 25, 26, 5, 27, 28, - 5, 29, 30, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 5, 29, 5, 30, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, @@ -2929,23 +2771,23 @@ _hb_ucd_u8[17524] = 17, 17, 17,103, 17, 17,104,100,100,100,100,100,100,100,100,100, 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, 100,105,100,100,100,100,100,100, 17, 17,106,107,100,108,109,110, - 17, 17, 17, 17, 17, 17, 17,111, 17, 17, 17, 17,112,113,100,100, - 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,114, - 17,115,116,100,100,100,100,100,100,100,100,100,117,100,100,100, - 100,100,100,100,100,100,100,100,100,100,100,100,118, 39,119,120, - 121,122,123,124,125,126,127,128, 39, 39,129,100,100,100,100,130, - 131,132,133,100,134,135,100,136,137,138,100,100,139,140,141,100, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,111,112,100,100, + 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,113, + 17,114,115,100,100,100,100,100,100,100,100,100,116,100,100,100, + 100,100,100,100,100,100,100,100,100,100,100,100,117, 39,118,119, + 120,121,122,123,124,125,126,127, 39, 39,128,100,100,100,100,129, + 130,131,132,100,133,134,135,136,137,138,100,100,139,140,141,100, 142,143,144,145, 39, 39,146,147,148, 39,149,150,100,100,100,100, 17, 17, 17, 17, 17, 17,151, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17,152,153, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,154, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,155, 17, 17,156,100, - 100,100,100,100,100,100,100,100, 17, 17,157,100,100,100,100,100, - 17, 17, 17,158, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17,159,100,100,100,100,100,100,100,100,100,100,100,100, - 160,161,100,100,100,100,100,100,100,100,100,100,100,100,100,100, + 17, 17, 17, 17, 17, 17, 17, 17,152, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,153, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,154, 17, 17,155,100, + 100,100,100,100,100,100,100,100, 17, 17,156,100,100,100,100,100, + 17, 17, 17,157, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17,158,100,100,100,100,100,100,100,100,100,100,100, + 159,160,100,100,100,100,100,100,100,100,100,100,100,100,100,100, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,161, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,162, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,163, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2, 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, @@ -2959,409 +2801,415 @@ _hb_ucd_u8[17524] = 34, 11, 34, 34, 32, 35, 32, 16, 36, 36, 37, 34, 38, 37, 34, 34, 34, 34, 34, 34, 34, 34, 16, 32, 34, 38, 32, 11, 32, 32, 32, 32, 32, 32, 16, 16, 16, 11, 34, 32, 34, 34, 11, 32, 32, 32, 32, 32, - 16, 16, 39, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 41, 41, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, - 40, 40, 42, 41, 41, 41, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, - 43, 43, 43, 43, 43, 43, 43, 43, 32, 32, 42, 32, 44, 45, 16, 10, - 44, 44, 41, 46, 11, 47, 47, 11, 34, 11, 11, 11, 11, 11, 11, 11, - 11, 48, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34, - 16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 49, 34, 32, 34, 11, - 32, 50, 43, 43, 51, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16, - 48, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 47, 52, 2, 2, 2, - 16, 16, 16, 16, 53, 54, 55, 56, 57, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 58, 59, 60, 43, 59, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 62, - 36, 63, 64, 44, 44, 44, 44, 44, 65, 65, 65, 8, 9, 66, 2, 67, - 43, 43, 43, 43, 43, 60, 68, 2, 69, 36, 36, 36, 36, 70, 43, 43, - 7, 7, 7, 7, 7, 2, 2, 36, 71, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 72, 43, 43, 43, 73, 50, 43, 43, 74, 75, 76, 43, 43, 36, - 7, 7, 7, 7, 7, 36, 77, 78, 2, 2, 2, 2, 2, 2, 2, 79, - 70, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 80, 62, 36, - 36, 36, 36, 43, 43, 43, 43, 43, 71, 44, 44, 44, 44, 44, 44, 44, - 7, 7, 7, 7, 7, 36, 36, 36, 36, 36, 36, 36, 36, 70, 43, 43, - 43, 43, 40, 21, 2, 81, 57, 20, 36, 36, 36, 43, 43, 75, 43, 43, - 43, 43, 75, 43, 75, 43, 43, 44, 2, 2, 2, 2, 2, 2, 2, 64, - 36, 36, 36, 36, 70, 43, 44, 64, 36, 36, 36, 36, 36, 61, 44, 44, - 36, 36, 36, 36, 82, 36, 36, 61, 65, 44, 44, 57, 43, 43, 43, 43, - 36, 36, 36, 36, 83, 43, 43, 43, 43, 84, 43, 43, 43, 43, 43, 43, - 43, 85, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 85, 71, 86, - 87, 43, 43, 43, 85, 86, 87, 86, 70, 43, 43, 43, 36, 36, 36, 36, - 36, 43, 2, 7, 7, 7, 7, 7, 88, 36, 36, 36, 36, 36, 36, 36, - 70, 86, 62, 36, 36, 36, 61, 62, 61, 62, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 61, 36, 36, 36, 61, 61, 44, 36, 36, 44, 71, 86, - 87, 43, 80, 89, 90, 89, 87, 61, 44, 44, 44, 89, 44, 44, 36, 62, - 36, 43, 44, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 56, 63, 80, - 57, 85, 62, 36, 36, 61, 44, 62, 61, 36, 62, 61, 36, 44, 80, 86, - 87, 80, 44, 57, 80, 57, 43, 44, 57, 44, 44, 44, 62, 36, 61, 61, - 44, 44, 44, 7, 7, 7, 7, 7, 43, 36, 70, 64, 44, 44, 44, 44, - 57, 85, 62, 36, 36, 36, 36, 62, 36, 62, 36, 36, 36, 36, 36, 36, - 61, 36, 62, 36, 36, 44, 71, 86, 87, 43, 43, 57, 85, 89, 87, 44, - 61, 44, 44, 44, 44, 44, 44, 44, 66, 44, 44, 44, 62, 43, 43, 43, - 57, 86, 62, 36, 36, 36, 61, 62, 61, 36, 62, 36, 36, 44, 71, 87, - 87, 43, 80, 89, 90, 89, 87, 44, 44, 44, 57, 85, 44, 44, 36, 62, - 78, 27, 27, 27, 44, 44, 44, 44, 44, 71, 62, 36, 36, 61, 44, 36, - 61, 36, 36, 44, 62, 61, 61, 36, 44, 62, 61, 44, 36, 61, 44, 36, - 36, 36, 36, 36, 36, 44, 44, 86, 85, 90, 44, 86, 90, 86, 87, 44, - 61, 44, 44, 89, 44, 44, 44, 44, 27, 91, 67, 67, 56, 92, 44, 44, - 85, 86, 71, 36, 36, 36, 61, 36, 61, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 44, 71, 43, 85, 86, 90, 43, 80, 43, 43, 44, - 44, 44, 57, 80, 36, 61, 62, 44, 44, 44, 44, 93, 27, 27, 27, 91, - 70, 86, 72, 36, 36, 36, 61, 36, 36, 36, 62, 36, 36, 44, 71, 87, - 86, 86, 90, 85, 90, 86, 43, 44, 44, 44, 89, 90, 44, 44, 62, 61, - 62, 94, 44, 44, 44, 44, 44, 44, 43, 86, 36, 36, 36, 36, 61, 36, - 36, 36, 36, 36, 36, 70, 71, 86, 87, 43, 80, 86, 90, 86, 87, 77, - 44, 44, 36, 94, 27, 27, 27, 95, 27, 27, 27, 27, 91, 36, 36, 36, - 57, 86, 62, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 36, 36, 36, - 36, 62, 36, 36, 36, 36, 62, 44, 36, 36, 36, 61, 44, 80, 44, 89, - 86, 43, 80, 80, 86, 86, 86, 86, 44, 86, 64, 44, 44, 44, 44, 44, - 62, 36, 36, 36, 36, 36, 36, 36, 70, 36, 43, 43, 43, 80, 44, 96, - 36, 36, 36, 75, 43, 43, 43, 60, 7, 7, 7, 7, 7, 2, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 62, 61, 61, 36, 36, 61, 36, 36, - 36, 36, 62, 62, 36, 36, 36, 36, 70, 36, 43, 43, 43, 43, 71, 44, - 36, 36, 61, 81, 43, 43, 43, 80, 7, 7, 7, 7, 7, 44, 36, 36, - 77, 67, 2, 2, 2, 2, 2, 2, 2, 97, 97, 67, 43, 67, 67, 67, - 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 50, 50, 50, 4, 4, 86, - 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, - 57, 43, 43, 43, 43, 43, 43, 85, 43, 43, 60, 43, 36, 36, 70, 43, - 43, 43, 43, 43, 57, 43, 43, 43, 43, 43, 43, 43, 43, 43, 80, 67, - 67, 67, 67, 76, 67, 67, 92, 67, 2, 2, 97, 67, 21, 64, 44, 44, - 36, 36, 36, 36, 36, 94, 87, 43, 85, 43, 43, 43, 87, 85, 87, 71, - 7, 7, 7, 7, 7, 2, 2, 2, 36, 36, 36, 86, 43, 36, 36, 43, - 71, 86, 98, 94, 86, 86, 86, 36, 70, 43, 71, 36, 36, 36, 36, 36, - 36, 85, 87, 85, 86, 86, 87, 94, 7, 7, 7, 7, 7, 86, 87, 67, - 11, 11, 11, 48, 44, 44, 48, 44, 16, 16, 16, 16, 16, 53, 45, 16, - 36, 36, 36, 36, 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44, - 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44, 36, 36, 36, 36, - 36, 36, 36, 61, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 57, 43, - 2, 2, 2, 2, 99, 27, 27, 27, 27, 27, 27, 27, 27, 27,100, 44, - 67, 67, 67, 67, 67, 44, 44, 44, 11, 11, 11, 44, 16, 16, 16, 44, - 101, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 77, 72, - 102, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,103,104, 44, - 36, 36, 36, 36, 36, 63, 2,105,106, 36, 36, 36, 61, 44, 44, 44, - 36, 43, 85, 44, 44, 44, 44, 62, 36, 43,107, 64, 44, 44, 44, 44, - 36, 43, 44, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 61, 36, - 61, 43, 44, 44, 44, 44, 44, 44, 36, 36, 43, 87, 43, 43, 43, 86, - 86, 86, 86, 85, 87, 43, 43, 43, 43, 43, 2, 88, 2, 66, 70, 44, - 7, 7, 7, 7, 7, 44, 44, 44, 27, 27, 27, 27, 27, 44, 44, 44, - 2, 2, 2,108, 2, 59, 43, 84, 36, 83, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 61, 44, 44, 44, 36, 36, 70, 71, 36, 36, 36, 36, - 36, 36, 36, 36, 70, 61, 44, 44, 36, 36, 36, 44, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 36, 36, 61, 43, 85, 86, 87, 85, 86, 44, 44, - 86, 85, 86, 86, 87, 43, 44, 44, 92, 44, 2, 7, 7, 7, 7, 7, - 36, 36, 36, 36, 36, 36, 36, 44, 36, 36, 61, 44, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 36, 44, 44, 36, 36, 36, 36, 36, 44, 44, 44, - 7, 7, 7, 7, 7,100, 44, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 36, 36, 36, 70, 85, 87, 44, 2, 36, 36, 94, 85, 43, 43, 43, 80, - 85, 85, 87, 43, 43, 43, 85, 86, 86, 87, 43, 43, 43, 43, 80, 57, - 2, 2, 2, 88, 2, 2, 2, 44, 43, 43, 43, 43, 43, 43, 43,109, - 43, 43, 43, 43, 43, 43, 43, 80, 43, 43, 98, 36, 36, 36, 36, 36, - 36, 36, 85, 43, 43, 85, 85, 86, 86, 85, 98, 36, 36, 36, 61, 2, - 97, 67, 67, 67, 67, 50, 43, 43, 43, 43, 67, 67, 67, 67, 21, 2, - 43, 98, 36, 36, 36, 36, 36, 36, 94, 43, 43, 86, 43, 87, 43, 36, - 36, 36, 36, 85, 43, 86, 87, 87, 43, 86, 44, 44, 44, 44, 2, 2, - 36, 36, 86, 86, 86, 86, 43, 43, 43, 43, 86, 43, 44, 93, 2, 2, - 7, 7, 7, 7, 7, 44, 62, 36, 36, 36, 36, 36, 40, 40, 40, 2, - 16, 16, 16, 16, 34,110, 44, 44, 11, 11, 11, 11, 11, 47, 48, 11, - 2, 2, 2, 2, 44, 44, 44, 44, 43, 60, 43, 43, 43, 43, 43, 43, - 85, 43, 43, 43, 71, 36, 70, 36, 36, 36, 71, 94, 43, 61, 44, 44, - 16, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 45, 16, 16, - 16, 16, 16, 16, 45, 16, 16, 16, 16, 16, 16, 16, 16,111, 40, 40, - 32, 32, 32, 16, 16, 16, 16, 32, 16, 16, 16, 16, 11, 11, 11, 11, - 16, 16, 16, 44, 11, 11, 11, 44, 16, 16, 16, 16, 48, 48, 48, 48, - 16, 16, 16, 16, 16, 16, 16, 44, 16, 16, 16, 16,112,112,112,112, - 16, 16,110, 16, 11, 11,113,114, 41, 16,110, 16, 11, 11,113, 41, - 16, 16, 44, 16, 11, 11,115, 41, 16, 16, 16, 16, 11, 11,116, 41, - 44, 16,110, 16, 11, 11,113,117,118,118,118,118,118,119, 65, 65, - 120,120,120, 2,121,122,121,122, 2, 2, 2, 2,123, 65, 65,124, - 2, 2, 2, 2,125,126, 2,127,128, 2,129,130, 2, 2, 2, 2, - 2, 9,128, 2, 2, 2, 2,131, 65, 65,132, 65, 65, 65, 65, 65, - 133, 44, 27, 27, 27, 8,129,134, 27, 27, 27, 27, 27, 8,129,104, - 40, 40, 40, 40, 40, 40, 81, 44, 20, 20, 20, 20, 20, 20, 20, 20, - 135, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43,136, 51, - 109, 51,109, 43, 43, 43, 43, 43, 80, 44, 44, 44, 44, 44, 44, 44, - 67,137, 67,138, 67, 34, 11, 16, 11, 32,138, 67, 49, 11, 11, 67, - 67, 67,137,137,137, 11, 11,139, 11, 11, 35, 36, 39, 67, 16, 11, - 8, 8, 49, 16, 16, 26, 67,140, 27, 27, 27, 27, 27, 27, 27, 27, - 105,105,105,105,105,105,105,105,105,141,142,105,143, 67, 44, 44, - 8, 8,144, 67, 67, 8, 67, 67,144, 26, 67,144, 67, 67, 67,144, - 67, 67, 67, 67, 67, 67, 67, 8, 67,144,144, 67, 67, 67, 67, 67, - 67, 67, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 67, 67, 67, 67, 4, 4, 67, 67, 8, 67, 67, 67,145,146, 67, 67, - 67, 67, 67, 67, 67, 67,144, 67, 67, 67, 67, 67, 67, 26, 8, 8, - 8, 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8, - 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 92, 44, 44, - 27, 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, - 67, 67, 67, 26, 67, 67, 67, 67, 26, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 8, 8, 8, 8, 67, 67, 67, 67, 67, 67, 67, 26, - 67, 67, 67, 67, 4, 4, 4, 4, 4, 4, 4, 27, 27, 27, 27, 27, - 27, 27, 67, 67, 67, 67, 67, 67, 8, 8,129,147, 8, 8, 8, 8, - 8, 8, 8, 4, 4, 4, 4, 4, 8,129,148,148,148,148,148,148, - 148,148,148,148,147, 8, 8, 8, 8, 8, 8, 8, 4, 4, 8, 8, - 8, 8, 8, 8, 8, 8, 4, 8, 8, 8,144, 26, 8, 8,144, 67, - 67, 67, 44, 67, 67, 67, 67, 67, 67, 67, 67, 55, 67, 67, 67, 67, - 32, 11, 32, 34, 34, 34, 34, 11, 32, 32, 34, 16, 16, 16, 40, 11, - 32, 32,140, 67, 67,138, 34,149, 43, 32, 44, 44, 93, 2, 99, 2, - 16, 16, 16,150, 44, 44,150, 44, 36, 36, 36, 36, 44, 44, 44, 52, - 64, 44, 44, 44, 44, 44, 44, 57, 36, 36, 36, 61, 44, 44, 44, 44, - 36, 36, 36, 61, 36, 36, 36, 61, 2,121,121, 2,125,126,121, 2, - 2, 2, 2, 6, 2,108,121, 2,121, 4, 4, 4, 4, 2, 2, 88, - 2, 2, 2, 2, 2,120, 2, 2,108,151, 2, 2, 2, 2, 2, 2, - 67, 2,152,148,148,148,153, 44, 67, 67, 67, 67, 67, 55, 67, 67, - 67, 67, 44, 44, 44, 44, 44, 44, 67, 67, 67, 44, 44, 44, 44, 44, - 1, 2,154,155, 4, 4, 4, 4, 4, 67, 4, 4, 4, 4,156,157, - 158,105,105,105,105, 43, 43, 86,159, 40, 40, 67,105,160, 63, 67, - 36, 36, 36, 61, 57,161,162, 69, 36, 36, 36, 36, 36, 63, 40, 69, - 44, 44, 62, 36, 36, 36, 36, 36, 67, 27, 27, 67, 67, 67, 67, 67, - 67, 67, 67, 44, 44, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, 92, - 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, 27, - 163, 27, 27, 27, 27, 27, 27, 27, 36, 36, 83, 36, 36, 36, 36, 36, - 67, 67, 67, 92, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36,164, 2, - 7, 7, 7, 7, 7, 36, 44, 44, 32, 32, 32, 32, 32, 32, 32, 70, - 51,165, 43, 43, 43, 43, 43, 88, 32, 32, 32, 32, 32, 32, 40, 43, - 36, 36, 36,105,105,105,105,105, 43, 2, 2, 2, 44, 44, 44, 44, - 41, 41, 41,162, 40, 40, 40, 40, 41, 32, 32, 32, 32, 32, 32, 32, - 16, 32, 32, 32, 32, 32, 32, 32, 45, 16, 16, 16, 34, 34, 34, 32, - 32, 32, 32, 32, 42,166, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, + 16, 16, 36, 16, 16, 16, 16, 16, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 40, 40, 39, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, 40, + 39, 39, 41, 40, 40, 40, 41, 41, 40, 40, 40, 40, 40, 40, 40, 40, + 42, 42, 42, 42, 42, 42, 42, 42, 32, 32, 41, 32, 43, 44, 16, 10, + 43, 43, 40, 45, 11, 46, 46, 11, 34, 11, 11, 11, 11, 11, 11, 11, + 11, 47, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34, + 16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 48, 34, 32, 34, 11, + 32, 49, 42, 42, 50, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16, + 47, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 46, 51, 2, 2, 2, + 16, 16, 16, 16, 52, 53, 54, 55, 56, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 57, 58, 59, 42, 58, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 60, 43, 61, + 36, 62, 63, 43, 43, 43, 43, 43, 64, 64, 64, 8, 9, 65, 2, 66, + 42, 42, 42, 42, 42, 59, 67, 2, 68, 36, 36, 36, 36, 69, 42, 42, + 7, 7, 7, 7, 7, 2, 2, 36, 70, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 71, 42, 42, 42, 72, 49, 42, 42, 73, 74, 75, 42, 42, 36, + 7, 7, 7, 7, 7, 36, 76, 77, 2, 2, 2, 2, 2, 2, 2, 78, + 69, 36, 36, 36, 36, 36, 36, 36, 42, 42, 42, 42, 42, 79, 61, 36, + 36, 36, 36, 42, 42, 42, 42, 42, 70, 43, 43, 43, 43, 43, 43, 43, + 7, 7, 7, 7, 7, 36, 36, 36, 36, 36, 36, 36, 36, 69, 42, 42, + 42, 42, 39, 21, 2, 80, 56, 20, 36, 36, 36, 42, 42, 74, 42, 42, + 42, 42, 74, 42, 74, 42, 42, 43, 2, 2, 2, 2, 2, 2, 2, 63, + 36, 36, 36, 36, 69, 42, 43, 63, 36, 36, 36, 36, 36, 60, 43, 43, + 36, 36, 36, 36, 81, 36, 36, 36, 64, 43, 43, 56, 42, 42, 42, 42, + 36, 36, 36, 36, 82, 42, 42, 42, 42, 83, 42, 42, 42, 42, 42, 42, + 42, 84, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 84, 70, 85, + 86, 42, 42, 42, 84, 85, 86, 85, 69, 42, 42, 42, 36, 36, 36, 36, + 36, 42, 2, 7, 7, 7, 7, 7, 87, 36, 36, 36, 36, 36, 36, 36, + 69, 85, 61, 36, 36, 36, 60, 61, 60, 61, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 60, 36, 36, 36, 60, 60, 43, 36, 36, 43, 70, 85, + 86, 42, 79, 88, 89, 88, 86, 60, 43, 43, 43, 88, 43, 43, 36, 61, + 36, 42, 43, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 55, 62, 79, + 56, 84, 61, 36, 36, 60, 43, 61, 60, 36, 61, 60, 36, 43, 79, 85, + 86, 79, 43, 56, 79, 56, 42, 43, 56, 43, 43, 43, 61, 36, 60, 60, + 43, 43, 43, 7, 7, 7, 7, 7, 42, 36, 69, 63, 43, 43, 43, 43, + 56, 84, 61, 36, 36, 36, 36, 61, 36, 61, 36, 36, 36, 36, 36, 36, + 60, 36, 61, 36, 36, 43, 70, 85, 86, 42, 42, 56, 84, 88, 86, 43, + 60, 43, 43, 43, 43, 43, 43, 43, 65, 43, 43, 43, 61, 42, 42, 42, + 56, 85, 61, 36, 36, 36, 60, 61, 60, 36, 61, 36, 36, 43, 70, 86, + 86, 42, 79, 88, 89, 88, 86, 43, 43, 43, 56, 84, 43, 43, 36, 61, + 77, 27, 27, 27, 43, 43, 43, 43, 43, 70, 61, 36, 36, 60, 43, 36, + 60, 36, 36, 43, 61, 60, 60, 36, 43, 61, 60, 43, 36, 60, 43, 36, + 36, 36, 36, 36, 36, 43, 43, 85, 84, 89, 43, 85, 89, 85, 86, 43, + 60, 43, 43, 88, 43, 43, 43, 43, 27, 90, 66, 66, 55, 91, 43, 43, + 84, 85, 70, 36, 36, 36, 60, 36, 60, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 43, 70, 42, 84, 85, 89, 42, 79, 42, 42, 43, + 43, 43, 56, 79, 36, 60, 36, 43, 43, 43, 43, 92, 27, 27, 27, 90, + 69, 85, 71, 36, 36, 36, 60, 36, 36, 36, 61, 36, 36, 43, 70, 86, + 85, 85, 89, 84, 89, 85, 42, 43, 43, 43, 88, 89, 43, 43, 36, 60, + 61, 93, 43, 43, 43, 43, 43, 43, 42, 85, 36, 36, 36, 36, 60, 36, + 36, 36, 36, 36, 36, 69, 70, 85, 86, 42, 79, 85, 89, 85, 86, 76, + 43, 43, 36, 93, 27, 27, 27, 94, 27, 27, 27, 27, 90, 36, 36, 36, + 56, 85, 61, 36, 36, 36, 36, 36, 36, 36, 36, 60, 43, 36, 36, 36, + 36, 61, 36, 36, 36, 36, 61, 43, 36, 36, 36, 60, 43, 79, 43, 88, + 85, 42, 79, 79, 85, 85, 85, 85, 43, 85, 63, 43, 43, 43, 43, 43, + 61, 36, 36, 36, 36, 36, 36, 36, 69, 36, 42, 42, 42, 79, 43, 95, + 36, 36, 36, 74, 42, 42, 42, 59, 7, 7, 7, 7, 7, 2, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 61, 60, 60, 36, 36, 60, 36, 36, + 36, 36, 61, 61, 36, 36, 36, 36, 69, 36, 42, 42, 42, 42, 70, 43, + 36, 36, 60, 80, 42, 42, 42, 79, 7, 7, 7, 7, 7, 43, 36, 36, + 76, 66, 2, 2, 2, 2, 2, 2, 2, 96, 96, 66, 42, 66, 66, 66, + 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 49, 49, 49, 4, 4, 85, + 36, 36, 36, 36, 61, 36, 36, 36, 36, 36, 36, 36, 36, 36, 60, 43, + 56, 42, 42, 42, 42, 42, 42, 84, 42, 42, 59, 42, 36, 36, 69, 42, + 42, 42, 42, 42, 56, 42, 42, 42, 42, 42, 42, 42, 42, 42, 79, 66, + 66, 66, 66, 75, 66, 66, 91, 66, 2, 2, 96, 66, 21, 63, 43, 43, + 36, 36, 36, 36, 36, 93, 86, 42, 84, 42, 42, 42, 86, 84, 86, 70, + 7, 7, 7, 7, 7, 2, 2, 2, 36, 36, 36, 85, 42, 36, 36, 42, + 70, 85, 97, 93, 85, 85, 85, 36, 69, 42, 70, 36, 36, 36, 36, 36, + 36, 84, 86, 84, 85, 85, 86, 93, 7, 7, 7, 7, 7, 85, 86, 66, + 11, 11, 11, 47, 43, 43, 47, 43, 16, 16, 16, 16, 16, 52, 44, 16, + 36, 36, 36, 36, 60, 36, 36, 43, 36, 36, 36, 60, 60, 36, 36, 43, + 60, 36, 36, 43, 36, 36, 36, 60, 60, 36, 36, 43, 36, 36, 36, 36, + 36, 36, 36, 60, 36, 36, 36, 36, 36, 36, 36, 36, 36, 60, 56, 42, + 2, 2, 2, 2, 98, 27, 27, 27, 27, 27, 27, 27, 27, 27, 99, 43, + 66, 66, 66, 66, 66, 43, 43, 43, 11, 11, 11, 43, 16, 16, 16, 43, + 100, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 76, 71, + 101, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,102,103, 43, + 36, 36, 36, 36, 36, 62, 2,104,105, 36, 36, 36, 60, 43, 43, 43, + 36, 42, 84, 43, 43, 43, 43, 61, 36, 42,106, 63, 43, 43, 43, 43, + 36, 42, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36, 60, 36, + 60, 42, 43, 43, 43, 43, 43, 43, 36, 36, 42, 86, 42, 42, 42, 85, + 85, 85, 85, 84, 86, 42, 42, 42, 42, 42, 2, 87, 2, 65, 69, 43, + 7, 7, 7, 7, 7, 43, 43, 43, 27, 27, 27, 27, 27, 43, 43, 43, + 2, 2, 2,107, 2, 58, 42, 83, 36, 82, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 60, 43, 43, 43, 36, 36, 69, 70, 36, 36, 36, 36, + 36, 36, 36, 36, 69, 60, 43, 43, 36, 36, 36, 43, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 36, 60, 42, 84, 85, 86, 84, 85, 43, 43, + 85, 84, 85, 85, 86, 42, 43, 43, 91, 43, 2, 7, 7, 7, 7, 7, + 36, 36, 36, 36, 36, 36, 36, 43, 36, 36, 60, 43, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 43, 43, 36, 36, 36, 36, 36, 43, 43, 43, + 7, 7, 7, 7, 7, 99, 43, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 36, 36, 36, 69, 84, 86, 43, 2, 36, 36, 93, 84, 42, 42, 42, 79, + 84, 84, 86, 42, 42, 42, 84, 85, 85, 86, 42, 42, 42, 42, 79, 56, + 2, 2, 2, 87, 2, 2, 2, 43, 42, 42, 42, 42, 42, 42, 42,108, + 42, 42, 42, 42, 42, 42, 42, 43, 42, 42, 42, 42, 42, 42, 43, 43, + 42, 42, 97, 36, 36, 36, 36, 36, 36, 36, 84, 42, 42, 84, 84, 85, + 85, 84, 97, 36, 36, 36, 60, 2, 96, 66, 66, 66, 66, 49, 42, 42, + 42, 42, 66, 66, 66, 66, 21, 2, 42, 97, 36, 36, 36, 36, 36, 36, + 93, 42, 42, 85, 42, 86, 42, 36, 36, 36, 36, 84, 42, 85, 86, 86, + 42, 85, 43, 43, 43, 43, 2, 2, 36, 36, 85, 85, 85, 85, 42, 42, + 42, 42, 85, 42, 43, 92, 2, 2, 7, 7, 7, 7, 7, 43, 61, 36, + 36, 36, 36, 36, 39, 39, 39, 2, 16, 16, 16, 16, 34,109, 43, 43, + 11, 11, 11, 11, 11, 46, 47, 11, 2, 2, 2, 2, 43, 43, 43, 43, + 42, 59, 42, 42, 42, 42, 42, 42, 84, 42, 42, 42, 70, 36, 69, 36, + 36, 36, 70, 93, 42, 60, 43, 43, 16, 16, 16, 16, 16, 16, 39, 39, + 39, 39, 39, 39, 39, 44, 16, 16, 16, 16, 16, 16, 44, 16, 16, 16, + 16, 16, 16, 16, 16,110, 39, 39, 32, 32, 32, 16, 16, 16, 16, 32, + 16, 16, 16, 16, 11, 11, 11, 11, 16, 16, 16, 43, 11, 11, 11, 43, + 16, 16, 16, 16, 47, 47, 47, 47, 16, 16, 16, 16, 16, 16, 16, 43, + 16, 16, 16, 16,111,111,111,111, 16, 16,109, 16, 11, 11,112,113, + 40, 16,109, 16, 11, 11,112, 40, 16, 16, 43, 16, 11, 11,114, 40, + 16, 16, 16, 16, 11, 11,115, 40, 43, 16,109, 16, 11, 11,112,116, + 117,117,117,117,117,118, 64, 64,119,119,119, 2,120,121,120,121, + 2, 2, 2, 2,122, 64, 64,123, 2, 2, 2, 2,124,125, 2,126, + 127, 2,128,129, 2, 2, 2, 2, 2, 9,127, 2, 2, 2, 2,130, + 64, 64,131, 64, 64, 64, 64, 64,132, 43, 27, 27, 27, 8,128,133, + 27, 27, 27, 27, 27, 8,128,103, 39, 39, 39, 39, 39, 39, 80, 43, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 43, 43, 43, 43, 43, 43, 43, + 42, 42, 42, 42, 42, 42,134, 50,108, 50,108, 42, 42, 42, 42, 42, + 79, 43, 43, 43, 43, 43, 43, 43, 66,135, 66,136, 66, 34, 11, 16, + 11, 32,136, 66, 48, 11, 11, 66, 66, 66,135,135,135, 11, 11,137, + 11, 11, 35, 36,138, 66, 16, 11, 8, 8, 48, 16, 16, 26, 66,139, + 27, 27, 27, 27, 27, 27, 27, 27,104,104,104,104,104,104,104,104, + 104,140,141,104,142, 66, 43, 43, 8, 8,143, 66, 66, 8, 66, 66, + 143, 26, 66,143, 66, 66, 66,143, 66, 66, 66, 66, 66, 66, 66, 8, + 66,143,143, 66, 66, 66, 66, 66, 66, 66, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 66, 66, 66, 66, 4, 4, 66, 66, + 8, 66, 66, 66,144,145, 66, 66, 66, 66, 66, 66, 66, 66,143, 66, + 66, 66, 66, 66, 66, 26, 8, 8, 8, 8, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 8, 8, 8, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 91, 43, 43, 27, 27, 27, 27, 27, 27, 66, 66, + 66, 66, 66, 66, 66, 27, 27, 27, 66, 66, 66, 26, 66, 66, 66, 66, + 26, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 8, 8, 8, 8, + 66, 66, 66, 66, 66, 66, 66, 26, 66, 66, 66, 66, 4, 4, 4, 4, + 4, 4, 4, 27, 27, 27, 27, 27, 27, 27, 66, 66, 66, 66, 66, 66, + 8, 8,128,146, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, + 8,128,147,147,147,147,147,147,147,147,147,147,146, 8, 8, 8, + 8, 8, 8, 8, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, + 8, 8,143, 26, 8, 8,143, 66, 66, 66, 43, 66, 66, 66, 66, 66, + 32, 11, 32, 34, 34, 34, 34, 11, 32, 32, 34, 16, 16, 16, 39, 11, + 32, 32,139, 66, 66,136, 34,148, 42, 32, 43, 43, 92, 2, 98, 2, + 16, 16, 16,149, 43, 43,149, 43, 36, 36, 36, 36, 43, 43, 43, 51, + 63, 43, 43, 43, 43, 43, 43, 56, 36, 36, 36, 60, 43, 43, 43, 43, + 36, 36, 36, 60, 36, 36, 36, 60, 2,120,120, 2,124,125,120, 2, + 2, 2, 2, 6, 2,107,120, 2,120, 4, 4, 4, 4, 2, 2, 87, + 2, 2, 2, 2, 2,119, 2, 2,107,150, 2, 2, 2, 2, 2, 2, + 66, 2,151,147,147,147,152, 43, 66, 66, 66, 66, 66, 54, 66, 66, + 66, 66, 43, 43, 43, 43, 43, 43, 66, 66, 66, 43, 43, 43, 43, 43, + 1, 2,153,154, 4, 4, 4, 4, 4, 66, 4, 4, 4, 4,155,156, + 157,104,104,104,104, 42, 42, 85,158, 39, 39, 66,104,159, 62, 66, + 36, 36, 36, 60, 56,160,161, 68, 36, 36, 36, 36, 36, 62, 39, 68, + 43, 43, 61, 36, 36, 36, 36, 36, 66, 27, 27, 66, 66, 66, 66, 66, + 66, 66, 66, 43, 43, 43, 43, 54, 66, 66, 66, 66, 66, 66, 66, 91, + 27, 27, 27, 27, 27, 66, 66, 66, 66, 66, 66, 66, 27, 27, 27, 27, + 162, 27, 27, 27, 27, 27, 27, 27, 36, 36, 82, 36, 36, 36, 36, 36, + 66, 66, 66, 91, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36,163, 2, + 7, 7, 7, 7, 7, 36, 43, 43, 32, 32, 32, 32, 32, 32, 32, 69, + 50,164, 42, 42, 42, 42, 42, 87, 32, 32, 32, 32, 32, 32, 39, 42, + 36, 36, 36,104,104,104,104,104, 42, 2, 2, 2, 43, 43, 43, 43, + 40, 40, 40,161, 39, 39, 39, 39, 40, 32, 32, 32, 32, 32, 32, 32, + 16, 32, 32, 32, 32, 32, 32, 32, 44, 16, 16, 16, 34, 34, 34, 32, + 32, 32, 32, 32, 41,165, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 11, 11, 32, 11, 11, 32, 32, 32, 32, 32, 32, - 32, 32, 11, 11, 34, 34, 32, 44, 32,150,150, 32, 32, 32, 47, 44, - 44, 40,167, 35, 40, 35, 36, 36, 36, 71, 36, 71, 36, 70, 36, 36, - 36, 94, 87, 85, 67, 67, 80, 44, 27, 27, 27, 67,168, 44, 44, 44, - 36, 36, 2, 2, 44, 44, 44, 44, 86, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 86, 86, 86, 86, 86, 86, 86, 86, 43, 44, 44, 44, 44, 2, - 43, 36, 36, 36, 2, 72, 72, 70, 36, 36, 36, 43, 43, 43, 43, 2, - 36, 36, 36, 70, 43, 43, 43, 43, 43, 86, 44, 44, 44, 44, 44, 93, - 36, 70, 86, 43, 43, 86, 43, 86,107, 2, 2, 2, 2, 2, 2, 52, - 7, 7, 7, 7, 7, 44, 44, 2, 36, 36, 70, 69, 36, 36, 36, 36, - 7, 7, 7, 7, 7, 36, 36, 61, 36, 36, 36, 36, 70, 43, 43, 85, - 87, 85, 87, 80, 44, 44, 44, 44, 36, 70, 36, 36, 36, 36, 85, 44, - 7, 7, 7, 7, 7, 44, 2, 2, 69, 36, 36, 77, 67, 94, 85, 36, - 71, 43, 71, 70, 71, 36, 36, 43, 70, 61, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 62, 83, 2, 36, 36, 36, 36, 36, 94, 43, 86, - 2, 83,169, 80, 44, 44, 44, 44, 62, 36, 36, 61, 62, 36, 36, 61, - 62, 36, 36, 61, 44, 44, 44, 44, 16, 16, 16, 16, 16,114, 40, 40, - 16, 16, 16, 16,111, 41, 44, 44, 36, 94, 87, 86, 85,107, 87, 44, - 36, 36, 44, 44, 44, 44, 44, 44, 36, 36, 36, 61, 44, 62, 36, 36, - 170,170,170,170,170,170,170,170,171,171,171,171,171,171,171,171, - 16, 16, 16,110, 44, 44, 44, 44, 44,150, 16, 16, 44, 44, 62, 71, - 36, 36, 36, 36,172, 36, 36, 36, 36, 36, 36, 61, 36, 36, 61, 61, - 36, 62, 61, 36, 36, 36, 36, 36, 36, 41, 41, 41, 41, 41, 41, 41, - 41,117, 44, 44, 44, 44, 44, 44, 44, 62, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36,148, 44, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 44, 44, 44, 55, 36, 36, 36, 36, 36, 36,168, 67, - 2, 2, 2,152,130, 44, 44, 44, 6,173,174,148,148,148,148,148, - 148,148,130,152,130, 2,127,175, 2, 64, 2, 2,156,148,148,130, - 2,176, 8,177, 66, 2, 44, 44, 36, 36, 61, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 61, 79, 93, 2, 3, 2, 4, 5, 6, 2, - 16, 16, 16, 16, 16, 17, 18,129,130, 4, 2, 36, 36, 36, 36, 36, - 69, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 40, - 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 61, 44, - 20,178, 56,135, 26, 8,144, 92, 44, 44, 44, 44, 79, 65, 67, 44, - 36, 36, 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 61, 36, 62, - 2, 64, 44,179, 27, 27, 27, 27, 27, 27, 44, 55, 67, 67, 67, 67, - 105,105,143, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 27, 67, 92, - 67, 67, 67, 67, 67, 67, 92, 44, 92, 44, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 67, 50, 44,180, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 44, 44, 27, 27, 44, 44, 44, 44, 62, 36, - 155, 36, 36, 36, 36,181, 44, 44, 36, 36, 36, 43, 43, 80, 44, 44, - 36, 36, 36, 36, 36, 36, 36, 93, 36, 36, 44, 44, 36, 36, 36, 36, - 182,105,105, 44, 44, 44, 44, 44, 11, 11, 11, 11, 16, 16, 16, 16, - 11, 11, 44, 44, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 44, 44, - 36, 36, 36, 36, 44, 44, 44, 44, 36, 36, 44, 44, 44, 44, 44, 93, - 11, 11, 11, 11, 11, 47, 11, 11, 11, 47, 11,150, 16, 16, 16, 16, - 16,150, 16, 16, 16, 16, 16, 16, 16,150, 16, 16, 16,150,110, 44, - 40, 40, 40, 52, 40, 40, 40, 40, 81, 40, 40, 40, 40, 81, 44, 44, - 36, 36, 36, 44, 61, 36, 36, 36, 36, 36, 36, 62, 61, 44, 61, 62, - 36, 36, 36, 93, 27, 27, 27, 27, 36, 36, 36, 77,163, 27, 27, 27, - 44, 44, 44,179, 27, 27, 27, 27, 36, 61, 36, 44, 44,179, 27, 27, - 36, 36, 36, 27, 27, 27, 44, 93, 36, 36, 36, 36, 36, 44, 44, 93, - 36, 36, 36, 36, 44, 44, 27, 36, 44, 27, 27, 27, 27, 27, 27, 27, - 70, 43, 57, 80, 44, 44, 43, 43, 36, 36, 62, 36, 62, 36, 36, 36, - 36, 36, 36, 44, 43, 80, 44, 57, 27, 27, 27, 27,100, 44, 44, 44, - 2, 2, 2, 2, 64, 44, 44, 44, 36, 36, 36, 36, 36, 36,183, 30, - 36, 36, 36, 36, 36, 36,183, 27, 36, 36, 36, 36, 78, 36, 36, 36, - 36, 36, 70, 80, 44,179, 27, 27, 2, 2, 2, 64, 44, 44, 44, 44, - 36, 36, 36, 44, 93, 2, 2, 2, 36, 36, 36, 44, 27, 27, 27, 27, - 36, 61, 44, 44, 27, 27, 27, 27, 36, 44, 44, 44, 93, 2, 64, 44, - 44, 44, 44, 44,179, 27, 27, 27, 11, 47, 44, 44, 44, 44, 44, 44, - 16,110, 44, 44, 44, 27, 27, 27, 36, 36, 43, 43, 44, 44, 44, 44, - 7, 7, 7, 7, 7, 36, 36, 69, 11, 11, 11, 44, 57, 43, 43,159, - 16, 16, 16, 44, 44, 44, 44, 8, 27, 27, 27, 27, 27, 27, 27,100, - 36, 36, 36, 36, 36, 57,184, 44, 36, 44, 44, 44, 44, 44, 44, 44, - 44, 36, 61, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 43, 43, - 27, 27, 27, 95, 44, 44, 44, 44,180, 27, 30, 2, 2, 44, 44, 44, - 36, 43, 43, 2, 2, 44, 44, 44, 36, 36,183, 27, 27, 27, 44, 44, - 87, 98, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, - 43, 43, 43, 60, 2, 2, 2, 44, 27, 27, 27, 7, 7, 7, 7, 7, - 71, 70, 71, 44, 44, 44, 44, 57, 86, 87, 43, 85, 87, 60,185, 2, - 2, 80, 44, 44, 44, 44, 79, 44, 43, 71, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 70, 43, 43, 87, 43, 43, 43, 80, 7, 7, 7, 7, 7, - 2, 2, 94, 98, 44, 44, 44, 44, 36, 70, 2, 61, 44, 44, 44, 44, - 36, 94, 86, 43, 43, 43, 43, 85, 98, 36, 63, 2, 59, 43, 60, 87, - 7, 7, 7, 7, 7, 63, 63, 2,179, 27, 27, 27, 27, 27, 27, 27, - 27, 27,100, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 86, 87, - 43, 86, 85, 43, 2, 2, 2, 71, 70, 44, 44, 44, 44, 44, 44, 44, - 36, 36, 36, 61, 61, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 62, - 36, 36, 36, 36, 63, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 70, - 86, 87, 43, 43, 43, 80, 44, 44, 43, 86, 62, 36, 36, 36, 61, 62, - 61, 36, 62, 36, 36, 57, 71, 86, 85, 86, 90, 89, 90, 89, 86, 44, - 61, 44, 44, 89, 44, 44, 62, 36, 36, 86, 44, 43, 43, 43, 80, 44, - 43, 43, 80, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 62, 44, 61, - 36, 36, 36, 62, 86, 87, 43, 43, 80, 90, 89, 89, 86, 90, 86, 85, - 71, 71, 2, 93, 64, 44, 44, 44, 57, 80, 44, 44, 44, 44, 44, 44, - 36, 36, 94, 86, 43, 43, 43, 43, 86, 43, 85, 71, 36, 63, 2, 2, - 7, 7, 7, 7, 7, 2, 93, 71, 86, 87, 43, 43, 85, 85, 86, 87, - 85, 43, 36, 72, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 94, - 86, 43, 43, 44, 86, 86, 43, 87, 60, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 36, 36, 43, 44, 86, 87, 43, 43, 43, 85, 87, 87, - 60, 2, 61, 44, 44, 44, 44, 44, 2, 2, 2, 2, 2, 2, 64, 44, - 36, 36, 36, 36, 36, 70, 87, 86, 43, 43, 43, 87, 63, 44, 44, 44, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 44, 44, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 61, 57, 87, 86, 43, 43, 87, 43, 43, 44, 44, - 7, 7, 7, 7, 7, 27, 2, 97, 43, 43, 43, 43, 87, 60, 44, 44, - 27,100, 44, 44, 44, 44, 44, 62, 36, 36, 36, 61, 62, 44, 36, 36, - 36, 36, 62, 61, 36, 36, 36, 36, 86, 86, 86, 89, 90, 57, 85, 71, - 98, 87, 2, 64, 44, 44, 44, 44, 36, 36, 36, 36, 44, 36, 36, 36, - 94, 86, 43, 43, 44, 43, 86, 86, 71, 72, 90, 44, 44, 44, 44, 44, - 70, 43, 43, 43, 43, 71, 36, 36, 36, 70, 43, 43, 85, 70, 43, 60, - 2, 2, 2, 59, 44, 44, 44, 44, 70, 43, 43, 85, 87, 43, 36, 36, - 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 85, 43, 2, 72, 2, - 2, 64, 44, 44, 44, 44, 44, 44, 2, 2, 2, 2, 2, 44, 44, 44, - 63, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 80, 43, 43, 43, 87, - 63, 2, 2, 44, 44, 44, 44, 44, 2, 36, 36, 36, 36, 36, 36, 36, - 44, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 89, 43, 43, 43, - 85, 43, 87, 80, 44, 44, 44, 44, 36, 36, 36, 61, 36, 62, 36, 36, - 70, 43, 43, 80, 44, 80, 43, 57, 43, 43, 43, 70, 44, 44, 44, 44, - 36, 36, 36, 62, 61, 36, 36, 36, 36, 36, 36, 36, 36, 86, 86, 90, - 43, 89, 87, 87, 61, 44, 44, 44, 36, 70, 85,107, 64, 44, 44, 44, - 43, 94, 36, 36, 36, 36, 36, 36, 36, 36, 86, 43, 43, 80, 44, 86, - 85, 60, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 80, 44, 44, - 27, 27, 91, 67, 67, 67, 56, 20,168, 67, 67, 67, 67, 67, 67, 67, - 67, 44, 44, 44, 44, 44, 44, 93,105,105,105,105,105,105,105,181, - 2, 2, 64, 44, 44, 44, 44, 44, 63, 64, 44, 44, 44, 44, 44, 44, - 65, 65, 65, 65, 65, 65, 65, 65, 71, 36, 36, 70, 43, 43, 43, 43, - 43, 43, 43, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 43, - 43, 43, 43, 43, 43, 86, 87, 43, 43, 43, 60, 44, 44, 44, 44, 44, - 43, 43, 43, 60, 2, 2, 67, 67, 40, 40, 97, 44, 44, 44, 44, 44, - 7, 7, 7, 7, 7,179, 27, 27, 27, 62, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 44, 44, 62, 36, 40, 69, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 83,164, 2, 27, 27, 27, 30, 2, 64, 44, 44, - 36, 36, 36, 36, 36, 61, 44, 57, 94, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 44, 44, 44, 57, - 43, 74, 40, 40, 40, 40, 40, 40, 40, 88, 80, 44, 44, 44, 44, 44, - 86, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 62, - 40, 40, 52, 40, 40, 40, 52, 81, 36, 61, 44, 44, 44, 44, 44, 44, - 44, 61, 44, 44, 44, 44, 44, 44, 36, 61, 62, 44, 44, 44, 44, 44, - 44, 44, 36, 36, 44, 44, 44, 44, 36, 36, 36, 36, 36, 44, 50, 60, - 65, 65, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43, 43, 44, - 43, 43, 43, 80, 44, 44, 44, 44, 67, 67, 67, 92, 55, 67, 67, 67, - 67, 67,186, 87, 43, 67,186, 86, 86,187, 65, 65, 65, 84, 43, 43, - 43, 76, 50, 43, 43, 43, 67, 67, 67, 67, 67, 67, 67, 43, 43, 67, - 67, 43, 76, 44, 44, 44, 44, 44, 27, 27, 44, 44, 44, 44, 44, 44, - 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 16, 16, 16,110, 16, 16, 16, 16, 16, - 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 47, 11, - 44, 47, 48, 47, 48, 11, 47, 11, 11, 11, 11, 16, 16,150,150, 16, - 16, 16,150, 16, 16, 16, 16, 16, 16, 16, 11, 48, 11, 47, 48, 11, - 11, 11, 47, 11, 11, 11, 47, 16, 16, 16, 16, 16, 11, 48, 11, 47, - 11, 11, 47, 47, 44, 11, 11, 11, 47, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, - 16, 16, 16, 44, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, - 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, - 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, - 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, - 16, 33, 16, 16, 16, 32, 44, 7, 43, 43, 43, 76, 67, 50, 43, 43, - 43, 43, 43, 43, 43, 43, 76, 67, 67, 67, 50, 67, 67, 67, 67, 67, - 67, 67, 76, 21, 2, 2, 44, 44, 44, 44, 44, 44, 44, 57, 43, 43, - 16, 16, 16, 16, 16, 39, 16, 16, 16, 16, 16, 16, 16, 16, 16,110, - 44, 44,150, 16, 16,110, 44, 44, 43, 43, 43, 80, 43, 43, 43, 43, - 43, 43, 43, 43, 80, 57, 43, 43, 43, 57, 80, 43, 43, 80, 44, 44, - 40, 40, 40, 40, 40, 40, 40, 44, 44, 44, 44, 44, 44, 44, 44, 57, - 43, 43, 43, 74, 40, 40, 40, 44, 7, 7, 7, 7, 7, 44, 44, 77, - 36, 36, 36, 36, 36, 36, 36, 80, 36, 36, 36, 36, 36, 36, 43, 43, - 7, 7, 7, 7, 7, 44, 44, 96, 36, 36, 36, 36, 36, 83, 43, 43, - 188, 7, 7, 7, 7,189, 44, 93, 36, 36, 36, 61, 36, 36, 62, 61, - 36, 36, 61,179, 27, 27, 27, 27, 16, 16, 43, 43, 43, 74, 44, 44, - 27, 27, 27, 27, 27, 27,163, 27,190, 27,100, 44, 44, 44, 44, 44, - 27, 27, 27, 27, 27, 27, 27,163, 27, 27, 27, 27, 27, 27, 27, 44, - 36, 36, 62, 36, 36, 36, 36, 36, 62, 61, 61, 62, 62, 36, 36, 36, - 36, 61, 36, 36, 62, 62, 44, 44, 44, 61, 44, 62, 62, 62, 62, 36, - 62, 61, 61, 62, 62, 62, 62, 62, 62, 61, 61, 62, 36, 61, 36, 36, - 36, 61, 36, 36, 62, 36, 61, 61, 36, 36, 36, 36, 36, 62, 36, 36, - 62, 36, 62, 36, 36, 62, 36, 36, 8, 44, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 67, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, - 27, 27, 27, 27, 27, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 44, - 44, 44, 44, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 92, 44, 44, 44, 67, 44, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 25, 41, 41, 67, 67, 67, 67, 44, 44, 67, 67, - 67, 67, 67, 92, 44, 55, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 44, 44, 55, 67, 67, 67, 92, 44, 44, 44, 67, - 67, 67, 67, 67, 67, 67, 92, 55, 67, 92, 67, 67, 67, 67, 67, 67, - 79, 44, 44, 44, 44, 44, 44, 44,171,171,171,171,171,171,171, 44, - 171,171,171,171,171,171,171, 0, 0, 0, 29, 21, 21, 21, 23, 21, - 22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21, 9, 9, 9, - 9, 22, 21, 18, 24, 16, 24, 5, 5, 5, 5, 22, 25, 18, 25, 0, - 23, 23, 26, 21, 24, 26, 7, 20, 25, 1, 26, 24, 26, 25, 15, 15, - 24, 15, 7, 19, 15, 21, 9, 25, 9, 5, 5, 25, 5, 9, 5, 7, - 7, 7, 9, 8, 8, 5, 7, 5, 6, 6, 24, 24, 6, 24, 12, 12, - 2, 2, 6, 5, 9, 21, 9, 2, 2, 9, 25, 9, 26, 12, 11, 11, - 2, 6, 5, 21, 17, 2, 2, 26, 26, 23, 2, 12, 17, 12, 21, 12, - 12, 21, 7, 2, 2, 7, 7, 21, 21, 2, 1, 1, 21, 23, 26, 26, - 1, 21, 6, 7, 7, 12, 12, 7, 21, 7, 12, 1, 12, 6, 6, 12, - 12, 26, 7, 26, 26, 7, 2, 1, 12, 2, 6, 2, 24, 7, 7, 6, - 1, 12, 12, 10, 10, 10, 10, 12, 21, 6, 2, 10, 10, 2, 15, 26, - 26, 2, 2, 21, 7, 10, 15, 7, 2, 23, 21, 26, 10, 7, 21, 15, - 15, 2, 17, 7, 29, 7, 7, 22, 18, 2, 14, 14, 14, 7, 10, 21, - 17, 21, 11, 12, 5, 2, 5, 6, 8, 8, 8, 24, 5, 24, 2, 24, - 9, 24, 24, 2, 29, 29, 29, 1, 17, 17, 20, 19, 22, 20, 27, 28, - 1, 29, 21, 20, 19, 21, 21, 16, 16, 21, 25, 22, 18, 21, 21, 29, - 1, 2, 15, 6, 18, 6, 23, 2, 12, 11, 9, 26, 26, 9, 26, 5, - 5, 26, 14, 9, 5, 14, 14, 15, 25, 26, 26, 22, 18, 26, 18, 25, - 18, 22, 5, 12, 2, 5, 22, 21, 21, 22, 18, 17, 26, 6, 7, 14, - 17, 22, 18, 18, 26, 14, 17, 6, 14, 6, 12, 24, 24, 6, 26, 15, - 6, 21, 11, 21, 24, 9, 6, 9, 23, 26, 6, 10, 4, 4, 3, 3, - 7, 25, 17, 16, 16, 22, 16, 16, 25, 17, 25, 2, 25, 24, 2, 15, - 12, 15, 14, 2, 21, 14, 7, 15, 12, 17, 21, 1, 26, 10, 10, 1, - 7, 13, 13, 2, 23, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 0, 10, 11, 12, 13, 0, 14, 0, 0, 0, 0, 0, 15, 0, 16, 0, + 32, 32, 11, 11, 34, 34, 32, 32, 32, 32, 32, 32, 32, 32, 46, 43, + 51, 39,166, 35, 39, 35, 36, 36, 36, 70, 36, 70, 36, 69, 36, 36, + 36, 93, 86, 84, 66, 66, 79, 43, 27, 27, 27, 66,167, 43, 43, 43, + 36, 36, 2, 2, 43, 43, 43, 43, 85, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 85, 85, 85, 85, 85, 85, 85, 85, 42, 43, 43, 43, 43, 2, + 42, 36, 36, 36, 2, 71, 71, 69, 36, 36, 36, 42, 42, 42, 42, 2, + 36, 36, 36, 69, 42, 42, 42, 42, 42, 85, 43, 43, 43, 43, 43, 92, + 36, 69, 85, 42, 42, 85, 42, 85,106, 2, 2, 2, 2, 2, 2, 51, + 7, 7, 7, 7, 7, 43, 43, 2, 36, 36, 69, 68, 36, 36, 36, 36, + 7, 7, 7, 7, 7, 36, 36, 60, 36, 36, 36, 36, 69, 42, 42, 84, + 86, 84, 86, 79, 43, 43, 43, 43, 36, 69, 36, 36, 36, 36, 84, 43, + 7, 7, 7, 7, 7, 43, 2, 2, 68, 36, 36, 76, 66, 93, 84, 36, + 70, 42, 70, 69, 70, 36, 36, 42, 69, 60, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 61, 82, 2, 36, 36, 36, 36, 36, 93, 42, 85, + 2, 82,168, 79, 43, 43, 43, 43, 61, 36, 36, 60, 61, 36, 36, 60, + 61, 36, 36, 60, 43, 43, 43, 43, 16, 16, 16, 16, 16,113, 39, 39, + 16, 16, 16, 16,110, 40, 43, 43, 36, 93, 86, 85, 84,106, 86, 43, + 36, 36, 43, 43, 43, 43, 43, 43, 36, 36, 36, 60, 43, 61, 36, 36, + 169,169,169,169,169,169,169,169,170,170,170,170,170,170,170,170, + 16, 16, 16,109, 43, 43, 43, 43, 43,149, 16, 16, 43, 43, 61, 70, + 36, 36, 36, 36,171, 36, 36, 36, 36, 36, 36, 60, 36, 36, 60, 60, + 36, 61, 60, 36, 36, 36, 36, 36, 36, 40, 40, 40, 40, 40, 40, 40, + 40, 22, 66, 66, 66, 66, 66, 66, 66, 77, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36,147, 66, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 66, 66, 66, 66, 36, 36, 36, 36, 36, 36,167, 66, + 2, 2, 2,151,129, 43, 43, 43, 6,172,173,147,147,147,147,147, + 147,147,129,151,129, 2,126,174, 2, 63, 2, 2,155,147,147,129, + 2,175, 8,176, 65, 2, 43, 43, 36, 36, 60, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 60, 78, 92, 2, 3, 2, 4, 5, 6, 2, + 16, 16, 16, 16, 16, 17, 18,128,129, 4, 2, 36, 36, 36, 36, 36, + 68, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 39, + 43, 36, 36, 36, 43, 36, 36, 36, 43, 36, 36, 36, 43, 36, 60, 43, + 20,177, 55,178, 26, 8,143, 91, 43, 43, 43, 43, 78, 64, 66, 43, + 36, 36, 36, 36, 36, 36, 61, 36, 36, 36, 36, 36, 36, 60, 36, 61, + 2, 63, 43,179, 27, 27, 27, 27, 27, 27, 43, 54, 66, 66, 66, 66, + 104,104,142, 27, 90, 66, 66, 66, 66, 66, 66, 66, 66, 27, 66, 91, + 66, 66, 66, 66, 66, 66, 91, 43, 91, 43, 43, 43, 43, 43, 43, 43, + 66, 66, 66, 66, 66, 66, 49, 43,180, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 43, 43, 27, 27, 43, 43, 43, 43, 61, 36, + 154, 36, 36, 36, 36,181, 43, 43, 36, 36, 36, 42, 42, 79, 43, 43, + 36, 36, 36, 36, 36, 36, 36, 92, 36, 36, 43, 43, 36, 36, 36, 36, + 182,104,104, 43, 43, 43, 43, 43, 11, 11, 11, 11, 16, 16, 16, 16, + 11, 11, 43, 43, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 43, 43, + 36, 36, 36, 36, 43, 43, 43, 43, 36, 36, 43, 43, 43, 43, 43, 92, + 11, 11, 11, 11, 11, 46, 11, 11, 11, 46, 11,149, 16, 16, 16, 16, + 16,149, 16, 16, 16, 16, 16, 16, 16,149, 16, 16, 16,149,109, 43, + 39, 39, 39, 51, 39, 39, 39, 39, 80, 39, 39, 39, 39, 80, 43, 43, + 36, 36, 36, 43, 60, 36, 36, 36, 36, 36, 36, 61, 60, 43, 60, 61, + 36, 36, 36, 92, 27, 27, 27, 27, 36, 36, 36, 76,162, 27, 27, 27, + 43, 43, 43,179, 27, 27, 27, 27, 36, 60, 36, 43, 43,179, 27, 27, + 36, 36, 36, 27, 27, 27, 43, 92, 36, 36, 36, 36, 36, 43, 43, 92, + 36, 36, 36, 36, 43, 43, 27, 36, 43, 27, 27, 27, 27, 27, 27, 27, + 69, 42, 56, 79, 43, 43, 42, 42, 36, 36, 61, 36, 61, 36, 36, 36, + 36, 36, 36, 43, 42, 79, 43, 56, 27, 27, 27, 27, 99, 43, 43, 43, + 2, 2, 2, 2, 63, 43, 43, 43, 36, 36, 36, 36, 36, 36,183, 30, + 36, 36, 36, 36, 36, 36,183, 27, 36, 36, 36, 36, 77, 36, 36, 36, + 36, 36, 69, 79, 43,179, 27, 27, 2, 2, 2, 63, 43, 43, 43, 43, + 36, 36, 36, 43, 92, 2, 2, 2, 36, 36, 36, 43, 27, 27, 27, 27, + 36, 60, 43, 43, 27, 27, 27, 27, 36, 43, 43, 43, 92, 2, 63, 43, + 43, 43, 43, 43,179, 27, 27, 27, 11, 46, 43, 43, 43, 43, 43, 43, + 16,109, 43, 43, 43, 27, 27, 27, 36, 36, 42, 42, 43, 43, 43, 43, + 7, 7, 7, 7, 7, 36, 36, 68, 11, 11, 11, 43, 56, 42, 42,158, + 16, 16, 16, 43, 43, 43, 43, 8, 27, 27, 27, 27, 27, 27, 27, 99, + 36, 36, 36, 36, 36, 56,184, 43, 36, 43, 43, 43, 43, 43, 43, 43, + 43, 36, 82, 36, 43, 43, 43, 43, 96, 66, 66, 66, 91, 43, 43, 43, + 43, 43, 43, 43, 43, 42, 42, 42, 27, 27, 27, 94, 43, 43, 43, 43, + 180, 27, 30, 2, 2, 43, 43, 43, 36, 42, 42, 2, 2, 43, 43, 43, + 36, 36,183, 27, 27, 27, 43, 43, 86, 97, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 42, 42, 42, 42, 42, 42, 42, 59, 2, 2, 2, 43, + 27, 27, 27, 7, 7, 7, 7, 7, 70, 69, 70, 43, 43, 43, 43, 56, + 85, 86, 42, 84, 86, 59,185, 2, 2, 79, 43, 43, 43, 43, 78, 43, + 42, 70, 36, 36, 36, 36, 36, 36, 36, 36, 36, 69, 42, 42, 86, 42, + 42, 42, 79, 7, 7, 7, 7, 7, 2, 2, 93, 97, 43, 43, 43, 43, + 36, 69, 2, 60, 43, 43, 43, 43, 36, 93, 85, 42, 42, 42, 42, 84, + 97, 36, 62, 2, 58, 42, 59, 86, 7, 7, 7, 7, 7, 62, 62, 2, + 179, 27, 27, 27, 27, 27, 27, 27, 27, 27, 99, 43, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 85, 86, 42, 85, 84, 42, 2, 2, 2, 70, + 69, 43, 43, 43, 43, 43, 43, 43, 36, 36, 36, 60, 60, 36, 36, 61, + 36, 36, 36, 36, 36, 36, 36, 61, 36, 36, 36, 36, 62, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 36, 69, 85, 86, 42, 42, 42, 79, 43, 43, + 42, 85, 61, 36, 36, 36, 60, 61, 60, 36, 61, 36, 36, 56, 70, 85, + 84, 85, 89, 88, 89, 88, 85, 43, 60, 43, 43, 88, 43, 43, 61, 36, + 36, 85, 43, 42, 42, 42, 79, 43, 42, 42, 79, 43, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 61, 43, 60, 36, 36, 36, 61, 85, 86, 42, 42, + 79, 89, 88, 88, 85, 89, 85, 84, 70, 70, 2, 92, 63, 43, 43, 43, + 56, 79, 43, 43, 43, 43, 43, 43, 36, 36, 93, 85, 42, 42, 42, 42, + 85, 42, 84, 70, 36, 62, 2, 2, 7, 7, 7, 7, 7, 2, 92, 70, + 85, 86, 42, 42, 84, 84, 85, 86, 84, 42, 36, 71, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 36, 93, 85, 42, 42, 43, 85, 85, 42, 86, + 59, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 42, 43, + 85, 86, 42, 42, 42, 84, 86, 86, 59, 2, 60, 43, 43, 43, 43, 43, + 2, 2, 2, 2, 2, 2, 63, 43, 36, 36, 36, 36, 36, 69, 86, 85, + 42, 42, 42, 86, 62, 43, 43, 43, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 36, 60, 56, 86, + 85, 42, 42, 86, 42, 42, 43, 43, 7, 7, 7, 7, 7, 27, 2, 96, + 42, 42, 42, 42, 86, 59, 43, 43, 27, 99, 43, 43, 43, 43, 43, 61, + 36, 36, 36, 60, 61, 43, 36, 36, 36, 36, 61, 60, 36, 36, 36, 36, + 85, 85, 85, 88, 89, 56, 84, 70, 97, 86, 2, 63, 43, 43, 43, 43, + 36, 36, 36, 36, 43, 36, 36, 36, 93, 85, 42, 42, 43, 42, 85, 85, + 70, 71, 89, 43, 43, 43, 43, 43, 69, 42, 42, 42, 42, 70, 36, 36, + 36, 69, 42, 42, 84, 69, 42, 59, 2, 2, 2, 58, 43, 43, 43, 43, + 69, 42, 42, 84, 86, 42, 36, 36, 36, 36, 36, 36, 36, 42, 42, 42, + 42, 42, 42, 84, 42, 2, 71, 2, 2, 63, 43, 43, 43, 43, 43, 43, + 2, 2, 2, 2, 2, 43, 43, 43, 84, 42, 84, 84, 43, 43, 43, 43, + 62, 43, 43, 43, 43, 43, 43, 43, 42, 42, 42, 79, 42, 42, 42, 86, + 62, 2, 2, 43, 43, 43, 43, 43, 2, 36, 36, 36, 36, 36, 36, 36, + 43, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 88, 42, 42, 42, + 84, 42, 86, 79, 43, 43, 43, 43, 36, 36, 36, 60, 36, 61, 36, 36, + 69, 42, 42, 79, 43, 79, 42, 56, 42, 42, 42, 69, 43, 43, 43, 43, + 36, 36, 36, 61, 60, 36, 36, 36, 36, 36, 36, 36, 36, 85, 85, 89, + 42, 88, 86, 86, 60, 43, 43, 43, 36, 36, 36, 36, 82, 36, 43, 43, + 36, 69, 84,106, 63, 43, 43, 43, 42, 93, 36, 36, 36, 36, 36, 36, + 36, 36, 85, 42, 42, 79, 43, 85, 84, 59, 2, 2, 2, 2, 2, 2, + 7, 7, 7, 7, 7, 79, 43, 43, 27, 27, 90, 66, 66, 66, 55, 20, + 167, 66, 66, 66, 66, 66, 66, 66, 66, 43, 43, 43, 43, 43, 43, 92, + 104,104,104,104,104,104,104,181, 2, 2, 63, 43, 43, 43, 43, 43, + 62, 63, 43, 43, 43, 43, 43, 43, 64, 64, 64, 64, 64, 64, 64, 64, + 70, 36, 36, 69, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 36, 42, 42, 42, 42, 42, 42, 85, 86, 42, + 42, 42, 59, 43, 43, 43, 43, 43, 42, 42, 42, 59, 2, 2, 66, 66, + 39, 39, 96, 43, 43, 43, 43, 43, 7, 7, 7, 7, 7,179, 27, 27, + 27, 61, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 61, 36, + 39, 68, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 82,163, 2, + 27, 27, 27, 30, 2, 63, 43, 43, 11, 11, 11, 11, 46,149, 16, 16, + 16, 16, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 36, 60, 43, 56, + 93, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 43, 43, 43, 56, 42, 73, 39, 39, 39, 39, 39, 39, + 39, 87, 79, 43, 43, 43, 43, 43, 85, 39,104,181, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 61, 36, 60, 43, 43, 43, 43, 43, 43, + 39, 39, 51, 39, 39, 39, 51, 80, 43, 60, 43, 43, 43, 43, 43, 43, + 36, 60, 61, 43, 43, 43, 43, 43, 43, 43, 36, 36, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 43, 49, 59, 64, 64, 43, 43, 43, 43, 43, 43, + 7, 7, 7, 7, 7, 66, 91, 43, 66, 66, 43, 43, 43, 66, 66, 66, + 176, 43, 43, 43, 43, 43, 43, 43, 42, 42, 42, 79, 43, 43, 43, 43, + 66, 66, 66, 91, 54, 66, 66, 66, 66, 66,186, 86, 42, 66,186, 85, + 85,187, 64, 64, 64, 83, 42, 42, 42, 75, 49, 42, 42, 42, 66, 66, + 66, 66, 66, 66, 66, 42, 42, 66, 66, 42, 75, 43, 43, 43, 43, 43, + 27, 27, 43, 43, 43, 43, 43, 43, 11, 11, 11, 11, 11, 16, 16, 16, + 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 16, + 16, 16,109, 16, 16, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 46, 11, 43, 46, 47, 46, 47, 11, 46, 11, + 11, 11, 11, 16, 16,149,149, 16, 16, 16,149, 16, 16, 16, 16, 16, + 16, 16, 11, 47, 11, 46, 47, 11, 11, 11, 46, 11, 11, 11, 46, 16, + 16, 16, 16, 16, 11, 47, 11, 46, 11, 11, 46, 46, 43, 11, 11, 11, + 46, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 11, 11, + 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 43, 11, 11, 11, 11, + 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, + 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, + 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, + 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 32, 43, 7, + 42, 42, 42, 75, 66, 49, 42, 42, 42, 42, 42, 42, 42, 42, 75, 66, + 66, 66, 49, 66, 66, 66, 66, 66, 66, 66, 75, 21, 2, 2, 43, 43, + 43, 43, 43, 43, 43, 56, 42, 42, 16, 16, 16, 16, 16,138, 16, 16, + 16, 16, 16, 16, 16, 16, 16,109, 43, 43,149, 16, 16,109, 43, 43, + 42, 42, 42, 79, 42, 42, 42, 42, 42, 42, 42, 42, 79, 56, 42, 42, + 42, 56, 79, 42, 42, 79, 43, 43, 39, 39, 39, 39, 39, 39, 39, 43, + 43, 43, 43, 43, 43, 43, 43, 56, 42, 42, 42, 73, 39, 39, 39, 43, + 7, 7, 7, 7, 7, 43, 43, 76, 36, 36, 36, 36, 36, 36, 36, 79, + 36, 36, 36, 36, 36, 36, 42, 42, 7, 7, 7, 7, 7, 43, 43, 95, + 36, 36, 36, 36, 36, 82, 42, 42,188, 7, 7, 7, 7,189, 43, 92, + 36, 69, 36, 70, 36, 36, 36, 42, 36, 36, 69, 43, 43, 43, 43, 82, + 36, 36, 36, 60, 36, 36, 61, 60, 36, 36, 60,179, 27, 27, 27, 27, + 16, 16, 42, 42, 42, 73, 43, 43, 27, 27, 27, 27, 27, 27,162, 27, + 190, 27, 99, 43, 43, 43, 43, 43, 27, 27, 27, 27, 27, 27, 27,162, + 27, 27, 27, 27, 27, 27, 27, 43, 36, 36, 61, 36, 36, 36, 36, 36, + 61, 60, 60, 61, 61, 36, 36, 36, 36, 60, 36, 36, 61, 61, 43, 43, + 43, 60, 43, 61, 61, 61, 61, 36, 61, 60, 60, 61, 61, 61, 61, 61, + 61, 60, 60, 61, 36, 60, 36, 36, 36, 60, 36, 36, 61, 36, 60, 60, + 36, 36, 36, 36, 36, 61, 36, 36, 61, 36, 61, 36, 36, 61, 36, 36, + 8, 43, 43, 43, 43, 43, 43, 43, 66, 66, 66, 66, 66, 66, 43, 43, + 54, 66, 66, 66, 66, 66, 66, 66, 27, 27, 27, 27, 27, 27, 90, 66, + 66, 66, 66, 66, 66, 66, 66, 43, 43, 43, 43, 66, 66, 66, 66, 66, + 66, 91, 43, 43, 43, 43, 43, 43, 66, 66, 66, 66, 91, 43, 43, 43, + 66, 43, 43, 43, 43, 43, 43, 43, 66, 66, 66, 66, 66, 25, 40, 40, + 66, 66, 66, 66, 91, 43, 66, 66, 66, 66, 66, 66, 43, 43, 43, 43, + 8, 8, 8, 8,176, 43, 43, 43, 66, 66, 66, 66, 66, 91, 43, 66, + 66, 66, 66, 91, 91, 43, 54, 66, 66, 66, 66, 66, 66, 66, 91, 54, + 66, 66, 66, 66, 66, 91, 43, 54, 66, 91, 66, 66, 66, 66, 66, 66, + 7, 7, 7, 7, 7, 91, 43, 43, 78, 43, 43, 43, 43, 43, 43, 43, + 170,170,170,170,170,170,170, 43,170,170,170,170,170,170,170, 0, + 0, 0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13, + 25, 25, 25, 21, 21, 9, 9, 9, 9, 22, 21, 18, 24, 16, 24, 5, + 5, 5, 5, 22, 25, 18, 25, 0, 23, 23, 26, 21, 24, 26, 7, 20, + 25, 1, 26, 24, 26, 25, 15, 15, 24, 15, 7, 19, 15, 21, 9, 25, + 9, 5, 5, 25, 5, 9, 5, 7, 7, 7, 9, 8, 8, 5, 6, 6, + 24, 24, 6, 24, 12, 12, 2, 2, 6, 5, 9, 21, 9, 2, 2, 9, + 25, 9, 26, 12, 11, 11, 2, 6, 5, 21, 17, 2, 2, 26, 26, 23, + 2, 12, 17, 12, 21, 12, 12, 21, 7, 2, 2, 7, 7, 21, 21, 2, + 1, 1, 21, 23, 26, 26, 1, 21, 6, 7, 7, 12, 12, 7, 21, 7, + 12, 1, 12, 6, 6, 12, 12, 26, 7, 26, 26, 7, 2, 1, 12, 2, + 6, 2, 24, 7, 7, 6, 1, 12, 12, 10, 10, 10, 10, 12, 21, 6, + 2, 10, 10, 2, 15, 26, 26, 2, 2, 21, 7, 10, 15, 7, 2, 23, + 21, 26, 10, 7, 21, 15, 15, 2, 17, 7, 29, 7, 7, 22, 18, 2, + 14, 14, 14, 7, 10, 21, 17, 21, 11, 12, 5, 2, 5, 6, 8, 8, + 8, 24, 5, 24, 2, 24, 9, 24, 24, 2, 29, 29, 29, 1, 17, 17, + 20, 19, 22, 20, 27, 28, 1, 29, 21, 20, 19, 21, 21, 16, 16, 21, + 25, 22, 18, 21, 21, 29, 1, 2, 15, 6, 18, 6, 12, 11, 9, 26, + 26, 9, 26, 5, 7, 5, 5, 26, 14, 9, 5, 14, 14, 15, 25, 26, + 26, 22, 18, 26, 18, 25, 18, 22, 5, 12, 2, 5, 22, 21, 21, 22, + 18, 17, 26, 6, 7, 14, 17, 22, 18, 18, 26, 14, 17, 6, 14, 6, + 12, 24, 24, 6, 26, 15, 6, 21, 11, 21, 24, 9, 6, 9, 23, 26, + 6, 10, 4, 4, 3, 3, 7, 25, 17, 16, 16, 22, 16, 16, 25, 17, + 25, 2, 25, 24, 23, 2, 2, 15, 12, 15, 14, 2, 21, 14, 7, 15, + 12, 17, 21, 1, 26, 10, 10, 1, 7, 13, 13, 2, 23, 15, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, 13, 0, 14, 0, + 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, 0, 0, 0, 0, + 0, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 21, 22, 23, + 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 20, 0, 21, 22, 23, 0, 0, 0, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, + 0, 0, 0, 36, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 36, 0, 37, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 40, - 0, 0, 0, 0, 0, 0, 41, 42, 43, 0, 44, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 3, 0, - 0, 0, 4, 5, 6, 7, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, - 16, 17, 16, 18, 16, 19, 16, 19, 16, 19, 0, 19, 16, 20, 16, 19, - 21, 19, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 32, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, - 34, 0, 0, 35, 0, 0, 36, 0, 37, 0, 0, 0, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 49, - 0, 0, 0, 0, 0, 0, 0, 50, 0, 51, 0, 52, 53, 0, 54, 0, - 0, 0, 0, 0, 0, 55, 56, 57, 0, 0, 0, 0, 58, 0, 0, 59, - 60, 61, 62, 63, 0, 0, 64, 65, 0, 0, 0, 66, 0, 0, 0, 0, - 67, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 69, 0, 0, 0, 70, 0, 71, 0, 0, 72, 0, 0, 73, - 0, 0, 0, 0, 0, 0, 0, 0, 74, 75, 0, 0, 0, 0, 76, 77, - 0, 78, 79, 0, 0, 80, 81, 0, 82, 62, 0, 83, 84, 0, 0, 85, - 86, 87, 0, 88, 0, 89, 0, 90, 0, 0, 51, 91, 51, 0, 92, 0, - 93, 0, 0, 0, 81, 0, 0, 0, 94, 95, 0, 96, 97, 98, 99, 0, - 0, 0, 0, 0, 51, 0, 0, 0, 0,100,101, 0, 0, 0, 0, 0, - 0,102, 0, 0, 0, 0, 0, 0,103, 0, 0, 0, 0, 0, 0,104, - 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,106, 0, 0,107, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,108,109, 0, 0,110, 0, 0, - 0, 0, 0, 0,111, 0,112, 0,105, 0, 0, 0, 0, 0,113,114, - 0, 0, 0, 0, 0, 0, 0,115, 0, 0, 0,116, 0, 0, 0,117, - 0,118, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, 42, + 43, 44, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 2, 0, 0, 0, 0, 3, 0, 0, 0, 4, 5, 6, 7, 0, 8, + 9, 10, 0, 11, 12, 13, 14, 15, 16, 17, 16, 18, 16, 19, 16, 19, + 16, 19, 0, 19, 16, 20, 16, 19, 21, 19, 0, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 33, 0, 0, 0, 0, 0, 0, 34, 0, 0, 35, 0, 0, 36, 0, + 37, 0, 0, 0, 38, 39, 40, 41, 42, 43, 44, 45, 46, 0, 0, 47, + 0, 0, 0, 48, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 50, + 0, 51, 0, 52, 53, 0, 54, 0, 0, 0, 0, 0, 0, 55, 56, 57, + 0, 0, 0, 0, 58, 0, 0, 59, 60, 61, 62, 63, 0, 0, 64, 65, + 0, 0, 0, 66, 0, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 70, + 0, 71, 0, 0, 72, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, + 74, 75, 0, 0, 0, 0, 76, 77, 0, 78, 79, 0, 0, 80, 81, 0, + 82, 62, 0, 83, 84, 0, 0, 85, 86, 87, 0, 88, 0, 89, 0, 90, + 0, 0, 51, 91, 51, 0, 92, 0, 93, 0, 0, 0, 81, 0, 0, 0, + 94, 95, 0, 96, 97, 98, 99, 0, 0, 0, 0, 0, 51, 0, 0, 0, + 0,100,101, 0, 0, 0, 0, 0, 0,102, 0, 0, 0, 0, 0, 0, + 103, 0, 0, 0, 0, 0, 0,104,105, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,106, 0, 0,107, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,108,109, 0, 0,110, 0, 0, 0, 0, 0, 0,111, 0,112, 0, + 105, 0, 0, 0, 0, 0,113,114, 0, 0, 0, 0, 0, 0, 0,115, + 0, 0, 0,116, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, 0,118, + 0,119, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, 8, 0, 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, 0, 13, 0, 0, 14, 15, 0, 16, 0, 17, 18, 0, 0, 19, 0, 20, 21, 0, 0, 0, 0, 0, 22, 23, 0, 24, 25, 0, 0, 26, 0, 0, 0, 27, 0, 0, @@ -3371,560 +3219,384 @@ _hb_ucd_u8[17524] = 0, 43, 0, 44, 0, 0, 0, 45, 46, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 48, 49, 0, 0, 0, 0, 50, 0, 0, 0, 51, 0, 52, 0, 53, 0, 0, 0, 0, 54, 0, 0, 0, 0, 55, 0, 56, 0, 0, - 0, 0, 57, 58, 0, 0, 0, 59, 60, 0, 0, 0, 0, 0, 0, 61, - 52, 0, 62, 63, 0, 0, 64, 0, 0, 0, 65, 66, 0, 0, 0, 67, - 0, 68, 69, 70, 71, 72, 1, 73, 0, 74, 75, 76, 0, 0, 77, 78, - 0, 0, 0, 79, 0, 0, 1, 1, 0, 0, 80, 0, 0, 81, 0, 0, - 0, 0, 77, 82, 0, 83, 0, 0, 0, 0, 0, 78, 84, 0, 85, 0, - 52, 0, 1, 78, 0, 0, 86, 0, 0, 87, 0, 0, 0, 0, 0, 88, - 57, 0, 0, 0, 0, 0, 0, 89, 90, 0, 0, 84, 0, 0, 33, 0, - 0, 91, 0, 0, 0, 0, 92, 0, 0, 0, 0, 49, 0, 0, 93, 0, - 0, 0, 0, 94, 95, 0, 0, 96, 0, 0, 97, 0, 0, 0, 98, 0, - 0, 0, 99, 0, 0, 0,100, 0, 0, 0, 0,101,102, 93, 0, 0, - 103, 0, 0, 0, 84, 0, 0,104, 0, 0, 0,105,106, 0, 0,107, - 108, 0, 0, 0, 0, 0, 0,109, 0, 0,110, 0, 0, 0, 0,111, - 33, 0,112,113,114, 57, 0, 0,115, 35, 0, 0,116, 0, 0, 0, - 117, 0, 0, 0, 0, 0, 0,118, 0, 0,119, 0, 0, 0, 0,120, - 88, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 52,121, 0, 0, 0, - 0,122, 0, 0,123, 0, 0, 0, 0,121, 0, 0,124, 0, 0, 0, - 0, 0, 79, 0, 0, 0, 0,125, 0, 0, 0,126, 0, 0, 0,127, - 0,128, 0, 0, 0, 0,129,130,131, 0,132, 0,133, 0, 0, 0, - 134,135,136, 0, 77, 0, 0, 0, 0, 0, 35, 0, 0, 0,137, 0, - 0, 0,138, 0, 0, 0,139, 0, 0,140, 0, 0,141, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 4, - 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, 18, 1, 1, 1, - 19, 1, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, 25, 26, 27, 28, - 29, 30, 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, 34, 35, 1, 36, - 37, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, 42, 0, 0, 0, - 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, 21, 0, 0, 47, - 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, 0, 19, 52, 1, - 0, 0, 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, 54, 21, 35, 1, - 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, 0, 0, 0, 59, - 0, 60, 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, 0, 0, 64, 0, - 0, 0, 65, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 68, 0, - 0, 69, 70, 0, 71, 72, 73, 74, 75, 76, 0, 0, 0, 77, 0, 0, - 0, 78, 79, 0, 0, 0, 0, 47, 0, 0, 0, 49, 0, 80, 0, 0, - 0, 62, 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, 0, 0, 83, 0, - 0, 19, 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, 1, 52, 15, 86, - 36, 10, 21, 87, 0, 55, 0, 0, 0, 0, 19, 10, 1, 0, 0, 0, - 0, 0, 88, 0, 0, 89, 0, 0, 88, 0, 0, 0, 0, 78, 0, 0, - 87, 9, 12, 4, 90, 8, 91, 47, 0, 58, 50, 0, 21, 1, 21, 92, - 93, 1, 1, 1, 1, 94, 95, 96, 97, 1, 98, 58, 81, 99,100, 4, - 58, 0, 0, 0, 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, 0, 61, - 0, 0,101,102, 0, 0,103, 0, 0, 1, 1, 50, 0, 0, 0, 38, - 0, 63, 0, 0, 0, 0, 0, 62, 0, 0,104, 68, 61, 0, 0, 0, - 78, 0, 0, 0,105,106, 58, 38, 81, 0, 0, 0, 0, 0, 0,107, - 1, 14, 4, 12, 84, 0, 0, 0, 0, 38, 87, 0, 0, 0, 0,108, - 0, 0,109, 61, 0,110, 0, 0, 0, 1, 0, 0, 0, 0, 49, 50, - 0, 0, 19, 58, 0, 0, 0, 51, 0,111, 14, 52,112, 41, 0, 0, - 62, 0, 0, 61, 0, 0,113, 0, 87, 0, 0, 0, 61, 62, 0, 0, - 62, 0, 89, 0, 0,113, 0, 0, 0, 0,114, 0, 0, 0, 78, 55, - 0, 38, 1, 58, 1, 58, 0, 0, 0, 0, 0, 88, 63, 89, 0, 0, - 115, 0, 0, 0, 55, 0, 0, 0, 0,115, 0, 0, 0, 0, 61, 0, - 0, 0, 0, 79, 0, 61, 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, - 79, 0, 0, 0, 8, 91, 0, 0, 1, 87, 0, 0,116, 0, 0, 0, - 0, 0, 0,117, 0,118,119,120,121, 0,104, 4,122, 49, 23, 0, - 0, 0, 38, 50, 38, 58, 0, 0, 1, 87, 1, 1, 1, 1, 39, 1, - 48,105, 87, 0, 0, 0, 0, 1, 0, 0, 0,123, 0, 0, 0,112, - 4,122, 0, 0, 0, 1,124, 0, 0, 0, 0, 0,230,230,230,230, - 230,232,220,220,220,220,232,216,220,220,220,220,220,202,202,220, - 220,220,220,202,202,220,220,220, 1, 1, 1, 1, 1,220,220,220, - 220,230,230,230,230,240,230,220,220,220,230,230,230,220,220, 0, - 230,230,230,220,220,220,220,230,232,220,220,230,233,234,234,233, - 234,234,233,230, 0, 0, 0,230, 0,220,230,230,230,230,220,230, - 230,230,222,220,230,230,220,220,230,222,228,230, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, 25, 0, - 230,220, 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, 28, 29, 30, 31, - 32, 33, 34,230,230,220,220,230,220,230,230,220, 35, 0, 0, 0, - 0, 0,230,230,230, 0, 0,230,230, 0,220,230,230,220, 0, 0, - 0, 36, 0, 0,230,220,230,230,220,220,230,220,220,230,220,230, - 220,230,230, 0, 0,220, 0, 0,230,230, 0,230, 0,230,230,230, - 230,230, 0, 0, 0,220,220,220,230,220,220,220,230,230, 0,220, - 27, 28, 29,230, 7, 0, 0, 0, 0, 9, 0, 0, 0,230,220,230, - 230, 0, 0, 0, 0, 0,230, 0, 0, 84, 91, 0, 0, 0, 0, 9, - 9, 0, 0, 0, 0, 0, 9, 0,103,103, 9, 0,107,107,107,107, - 118,118, 9, 0,122,122,122,122,220,220, 0, 0, 0,220, 0,220, - 0,216, 0, 0, 0,129,130, 0,132, 0, 0, 0, 0, 0,130,130, - 130,130, 0, 0,130, 0,230,230, 9, 0,230,230, 0, 0,220, 0, - 0, 0, 0, 7, 0, 9, 9, 0, 9, 9, 0, 0, 0,230, 0, 0, - 0,228, 0, 0, 0,222,230,220,220, 0, 0, 0,230, 0, 0,220, - 230,220, 0,220,230,230,230, 0, 0, 0, 9, 9, 0, 0, 7, 0, - 230, 0, 1, 1, 1, 0, 0, 0,230,234,214,220,202,230,230,230, - 230,230,232,228,228,220,218,230,233,220,230,220,230,230, 1, 1, - 1, 1, 1,230, 0, 1, 1,230,220,230, 1, 1, 0, 0,218,228, - 232,222,224,224, 0, 8, 8, 0, 0, 0, 0,220,230, 0,230,230, - 220, 0, 0,230, 0, 0, 26, 0, 0,220, 0,230,230, 1,220, 0, - 0,230,220, 0, 0, 0,220,220, 0, 0,230,220, 0, 9, 7, 0, - 0, 7, 9, 0, 0, 0, 9, 7, 6, 6, 0, 0, 0, 0, 1, 0, - 0,216,216, 1, 1, 1, 0, 0, 0,226,216,216,216,216,216, 0, - 220,220,220, 0,232,232,220,230,230,230, 7, 0, 16, 17, 17, 33, - 17, 49, 17, 17, 84, 97,135,145, 26, 17, 17, 17, 17, 17, 17, 17, + 0, 0, 57, 58, 0, 0, 0, 59, 60, 61, 62, 0, 0, 0, 0, 63, + 52, 0, 64, 65, 0, 0, 66, 0, 0, 0, 67, 68, 0, 0, 0, 69, + 0, 70, 71, 72, 73, 74, 1, 75, 0, 76, 77, 78, 0, 0, 79, 80, + 0, 0, 0, 81, 0, 0, 1, 1, 0, 0, 82, 0, 0, 83, 0, 0, + 0, 0, 79, 84, 0, 85, 0, 0, 0, 0, 0, 80, 86, 0, 87, 0, + 52, 0, 1, 80, 0, 0, 88, 0, 0, 89, 0, 0, 0, 0, 0, 90, + 57, 0, 0, 0, 0, 0, 0, 91, 92, 0, 0, 86, 0, 0, 33, 0, + 0, 93, 0, 0, 0, 0, 94, 0, 0, 0, 0, 49, 0, 0, 95, 0, + 0, 0, 0, 96, 97, 0, 0, 98, 0, 0, 99, 0, 0, 0,100, 0, + 0, 0,101, 0, 0, 0,102, 0, 0, 0, 0,103,104, 95, 0, 0, + 105, 0, 0, 0, 86, 0, 0,106, 0, 0, 0,107,108, 0, 0,109, + 110, 0, 0, 0, 0, 0, 0,111, 0, 0,112, 0, 0, 0, 0,113, + 33, 0,114,115,116, 57, 0, 0,117, 35, 0, 0,118, 0, 0, 0, + 119, 0, 0, 0, 0, 0, 0,120, 0, 0,121, 0, 0, 0, 0,122, + 90, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 52,123, 0, 0, 0, + 0,124, 0, 0,125, 0, 0, 0, 0,123, 0, 0,126, 0, 0, 0, + 0, 0, 81, 0, 0, 0, 0,127, 0, 0, 0,128, 0, 0, 0,129, + 0,130, 0, 0, 0, 0,131,132,133, 0,134, 0,135, 0, 0, 0, + 136,137,138, 0, 79, 0, 0, 0, 0, 0, 35, 0, 0, 0,139, 0, + 0, 0,140, 0, 0, 0,141, 0, 0, 0,142,143, 0,144, 0, 0, + 145, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, + 5, 6, 7, 4, 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, + 18, 1, 1, 1, 19, 1, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, + 25, 26, 27, 28, 29, 30, 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, + 34, 35, 1, 36, 37, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, + 42, 0, 0, 0, 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, + 21, 0, 0, 47, 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, + 0, 19, 52, 1, 0, 0, 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, + 54, 21, 35, 1, 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, + 0, 0, 0, 59, 0, 60, 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, + 0, 0, 64, 0, 0, 0, 65, 0, 0, 0, 66, 0, 0, 0, 67, 0, + 0, 0, 68, 0, 0, 69, 70, 0, 71, 72, 73, 74, 75, 76, 0, 0, + 0, 77, 0, 0, 0, 78, 79, 0, 0, 0, 0, 47, 0, 0, 0, 49, + 0, 80, 0, 0, 0, 62, 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, + 0, 0, 83, 0, 0, 19, 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, + 1, 52, 15, 86, 36, 10, 21, 1, 1, 1, 1, 41, 1, 21, 87, 0, + 0, 55, 0, 0, 0, 0, 19, 10, 1, 0, 0, 0, 0, 0, 88, 0, + 0, 89, 0, 0, 88, 0, 0, 0, 0, 78, 0, 0, 90, 9, 12, 4, + 91, 8, 92, 47, 0, 58, 50, 0, 21, 1, 21, 93, 94, 1, 1, 1, + 1, 95, 96, 97, 98, 1, 99, 58, 81,100,101, 4, 58, 0, 0, 0, + 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, 0, 61, 0, 0,102,103, + 0, 0,104, 0, 0, 1, 1, 50, 0, 0, 0, 38, 0, 63, 0, 0, + 0, 0, 0, 62, 0, 0,105, 68, 61, 0, 0, 0, 78, 0, 0, 0, + 106,107, 58, 38, 81, 0, 0, 0, 0, 0, 0,108, 1, 14, 4, 12, + 84, 0, 0, 0, 0, 38, 90, 0, 0, 0, 0,109, 0, 0,110, 61, + 0,111, 0, 0, 0, 1, 0, 0, 0, 0, 49, 50, 0, 0, 19, 58, + 0, 0,112, 51, 0,112, 14, 52,113, 41, 0, 0, 62, 0, 0, 61, + 0, 0,114, 0, 90, 0, 0, 0, 61, 62, 0, 0, 62, 0, 89, 0, + 0,114, 0, 0, 0, 0,115, 0, 0, 0, 78, 55, 0, 38, 1, 58, + 1, 58, 0, 0, 0, 0, 0, 88, 63, 89, 0, 0,116, 0, 0, 0, + 55, 0, 0, 0, 0,116, 0, 0, 0, 0, 61, 0, 0, 0, 0, 79, + 0, 61, 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, 79, 0, 0, 0, + 8, 92, 0, 0, 1, 90, 0, 0,117, 0, 0, 0, 0, 0, 0,118, + 0,119,120,121,122, 0,105, 4,123, 49, 23, 0, 0, 0, 38, 50, + 38, 58, 0, 0, 1, 90, 1, 1, 1, 1, 39, 1, 48,106, 90, 0, + 0, 0, 0, 1, 0, 0, 0,124, 0, 0, 0,113, 19, 59, 0, 38, + 0, 81, 0, 0, 4,123, 0, 0, 0, 1,125, 0, 0, 0, 0, 0, + 230,230,230,230,230,232,220,220,220,220,232,216,220,220,220,220, + 220,202,202,220,220,220,220,202,202,220,220,220, 1, 1, 1, 1, + 1,220,220,220,220,230,230,230,230,240,230,220,220,220,230,230, + 230,220,220, 0,230,230,230,220,220,220,220,230,232,220,220,230, + 233,234,234,233,234,234,233,230, 0, 0, 0,230, 0,220,230,230, + 230,230,220,230,230,230,222,220,230,230,220,220,230,222,228,230, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, + 0, 24, 25, 0,230,220, 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, + 28, 29, 30, 31, 32, 33, 34,230,230,220,220,230,220,230,230,220, + 35, 0, 0, 0, 0, 0,230,230,230, 0, 0,230,230, 0,220,230, + 230,220, 0, 0, 0, 36, 0, 0,230,220,230,230,220,220,230,220, + 220,230,220,230,220,230,230, 0, 0,220, 0, 0,230,230, 0,230, + 0,230,230,230,230,230, 0, 0, 0,220,220,220,230,220,220,220, + 230,230, 0,220, 27, 28, 29,230, 7, 0, 0, 0, 0, 9, 0, 0, + 0,230,220,230,230, 0, 0, 0, 0, 0,230, 0, 0, 84, 91, 0, + 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 9, 0,103,103, 9, 0, + 107,107,107,107,118,118, 9, 0,122,122,122,122,220,220, 0, 0, + 0,220, 0,220, 0,216, 0, 0, 0,129,130, 0,132, 0, 0, 0, + 0, 0,130,130,130,130, 0, 0,130, 0,230,230, 9, 0,230,230, + 0, 0,220, 0, 0, 0, 0, 7, 0, 9, 9, 0, 9, 9, 0, 0, + 0,230, 0, 0, 0,228, 0, 0, 0,222,230,220,220, 0, 0, 0, + 230, 0, 0,220,230,220, 0,220,230,230,230,234, 0, 0, 9, 9, + 0, 0, 7, 0,230,230,230, 0,230, 0, 1, 1, 1, 0, 0, 0, + 230,234,214,220,202,230,230,230,230,230,232,228,228,220,218,230, + 233,220,230,220,230,230, 1, 1, 1, 1, 1,230, 0, 1, 1,230, + 220,230, 1, 1, 0, 0,218,228,232,222,224,224, 0, 8, 8, 0, + 0, 0, 0,220,230, 0,230,230,220, 0, 0,230, 0, 0, 26, 0, + 0,220, 0,230,230, 1,220, 0, 0,230,220, 0, 0, 0,220,220, + 0, 0,230,220, 0, 9, 7, 0, 0, 7, 9, 0, 0, 0, 9, 7, + 6, 6, 0, 0, 0, 0, 1, 0, 0,216,216, 1, 1, 1, 0, 0, + 0,226,216,216,216,216,216, 0,220,220,220, 0,232,232,220,230, + 230,230, 7, 0, 16, 17, 17, 33, 17, 49, 17, 17, 84, 97,135,145, + 26, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,177, 0, 1, 2, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 3, 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 6, 7, 8, 3, - 3, 3, 3, 3, 9, 10, 11, 12, 13, 3, 3, 3, 3, 3, 3, 3, - 3, 14, 3, 15, 3, 3, 3, 3, 3, 3, 16, 17, 18, 19, 20, 21, - 3, 3, 3, 22, 23, 24, 3, 3, 3, 3, 3, 3, 25, 3, 3, 3, - 3, 3, 3, 3, 3, 26, 3, 3, 27, 28, 0, 1, 0, 0, 0, 0, - 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, - 0, 4, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 9, 0, 9, 0, 0, - 0, 0, 0, 0, 0, 10, 11, 12, 13, 0, 0, 14, 15, 16, 6, 0, - 17, 18, 19, 19, 19, 20, 21, 22, 23, 24, 19, 25, 0, 26, 27, 19, - 19, 28, 29, 30, 0, 31, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, - 0, 19, 28, 0, 32, 33, 9, 34, 35, 19, 0, 0, 36, 37, 38, 39, - 40, 19, 0, 41, 42, 43, 44, 31, 0, 1, 45, 42, 0, 0, 0, 0, - 0, 32, 14, 14, 0, 0, 0, 0, 14, 0, 0, 46, 47, 47, 47, 47, - 48, 49, 47, 47, 47, 47, 50, 51, 52, 53, 43, 21, 0, 0, 0, 0, - 0, 0, 0, 54, 6, 55, 0, 14, 19, 1, 0, 0, 0, 0, 56, 57, - 0, 0, 0, 0, 0, 19, 58, 31, 0, 0, 0, 0, 0, 0, 0, 59, - 14, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, - 61, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 3, - 0, 4, 5, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 1, 1, 0, - 0, 8, 9, 0, 8, 9, 0, 0, 0, 0, 8, 9, 10, 11, 12, 0, - 0, 0, 13, 0, 0, 0, 0, 14, 15, 16, 17, 0, 0, 0, 1, 0, - 0, 18, 19, 0, 0, 0, 20, 0, 0, 0, 1, 1, 1, 1, 0, 1, - 1, 1, 1, 1, 1, 1, 0, 8, 21, 9, 0, 0, 22, 0, 0, 0, - 0, 1, 0, 23, 24, 25, 0, 0, 26, 0, 0, 0, 8, 21, 27, 0, - 1, 0, 0, 1, 1, 1, 1, 0, 1, 28, 29, 30, 0, 31, 32, 20, - 1, 1, 0, 0, 0, 8, 21, 9, 1, 4, 5, 0, 0, 0, 33, 9, - 0, 1, 1, 1, 0, 8, 21, 21, 21, 21, 34, 1, 35, 21, 21, 21, - 9, 36, 0, 0, 37, 38, 1, 0, 39, 0, 0, 0, 1, 0, 1, 0, - 0, 0, 0, 8, 21, 9, 1, 0, 0, 0, 40, 0, 8, 21, 21, 21, - 21, 21, 21, 21, 21, 9, 0, 1, 1, 1, 1, 8, 21, 21, 21, 9, - 0, 0, 0, 41, 0, 42, 43, 0, 0, 0, 1, 44, 0, 0, 0, 45, - 8, 9, 1, 0, 0, 0, 8, 21, 21, 21, 9, 0, 1, 0, 1, 1, - 8, 21, 21, 9, 0, 4, 5, 8, 9, 1, 0, 0, 0, 1, 2, 3, - 4, 5, 5, 5, 5, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 9, 16, 17, 18, 9, 19, 20, 21, 22, 23, 24, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 25, 26, 27, 5, 28, 29, 5, 30, 31, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 32, 0, 0, 1, - 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 20, 20, 21, 22, 23, 24, 25, 26, 27, 28, 1, 29, 30, 31, - 32, 32, 33, 32, 32, 32, 34, 32, 32, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 46, 46, - 46, 46, 47, 48, 49, 50, 51, 52, 53, 54, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 44, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 95, - 95, 96, 97, 98, 56, 56, 56, 56, 56, 56, 56, 56, 56, 99,100,100, - 100,100,101,100,100,100,100,100,100,100,100,100,100,100,100,100, - 100,102,103,103,104, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,105, - 56, 56, 56, 56, 56, 56,106,106,107,108, 56,109,110,111,112,112, - 112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, - 112,112,112,112,112,113,112,112,112,114,115,116, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,117,118,119, - 120, 56, 56, 56, 56, 56, 56, 56, 56, 56,121, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,122, 32,123,124,125,126, - 127,128,129,130,131,132,133,133,134, 56, 56, 56, 56,135,136,137, - 138, 56,139,140, 56,141,142,143, 56, 56,144,145,146, 56,147,148, - 149, 32, 32, 32,150,151,152, 32,153,154, 56, 56, 56, 56, 44, 44, - 44, 44, 44, 44,155, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44,156,157, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,158, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44,159, 44, 44,160, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 44, 44,161, 56, 56, 56, 56, 56, 44, 44, - 44,162, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44,163, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,164,165, - 0, 1, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, - 19, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 0, 19, 0, - 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, - 26, 26, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, - 9, 9, 0, 9, 9, 9, 2, 2, 9, 9, 9, 9, 0, 9, 2, 2, - 2, 2, 9, 0, 9, 0, 9, 9, 9, 2, 9, 2, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 1, 6, 2, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 2, 4, 4, 4, 2, 2, 4, 4, 4, 2, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 2, - 2, 2, 2, 2, 2, 2, 14, 14, 14, 2, 2, 2, 2, 14, 14, 14, - 14, 14, 14, 2, 2, 2, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, - 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 0, 3, 3, 3, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 3, - 3, 3, 3, 3, 3, 3, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 2, 37, 37, 37, 37, 2, 2, 37, 37, 37, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 2, 2, 2, 2, 2, 2, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 2, 2, 64, 64, 64, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 2, 2, 90, 90, - 90, 90, 90, 90, 90, 2, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 2, 2, 95, 2, 37, 37, 37, 2, 2, 2, 2, 2, 3, 3, - 3, 3, 3, 3, 3, 2, 3, 3, 2, 2, 2, 2, 2, 3, 3, 3, - 0, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1, - 1, 1, 1, 7, 7, 7, 7, 7, 7, 7, 0, 0, 7, 7, 5, 5, - 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 2, - 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, - 5, 5, 5, 5, 5, 5, 5, 2, 5, 2, 2, 2, 5, 5, 5, 5, - 2, 2, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 2, 2, 2, - 2, 2, 2, 2, 2, 5, 2, 2, 2, 2, 5, 5, 2, 5, 5, 5, - 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 11, - 11, 11, 2, 11, 11, 11, 11, 11, 11, 2, 2, 2, 2, 11, 11, 2, - 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, - 11, 11, 11, 11, 11, 11, 11, 2, 11, 11, 2, 11, 11, 2, 11, 11, - 2, 2, 11, 2, 11, 11, 11, 2, 2, 11, 11, 11, 2, 2, 2, 11, - 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, 11, 2, 11, 2, 2, 2, - 2, 2, 2, 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, 2, 10, - 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, - 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, - 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 2, 10, 10, 10, 10, 10, - 2, 2, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, 2, 2, 10, 2, - 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 2, 2, 10, 10, 10, 10, - 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 2, 21, - 21, 21, 2, 21, 21, 21, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, - 2, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 2, - 21, 21, 21, 21, 21, 21, 21, 2, 21, 21, 2, 21, 21, 21, 21, 21, - 2, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, 2, 2, 2, 2, - 2, 2, 2, 21, 21, 21, 2, 2, 2, 2, 21, 21, 2, 21, 21, 21, - 21, 21, 2, 2, 21, 21, 2, 2, 22, 22, 2, 22, 22, 22, 22, 22, - 22, 2, 2, 2, 22, 22, 22, 2, 22, 22, 22, 22, 2, 2, 2, 22, - 22, 2, 22, 2, 22, 22, 2, 2, 2, 22, 22, 2, 2, 2, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 2, 2, 2, 2, 22, 22, 22, 2, - 2, 2, 2, 2, 2, 22, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, - 22, 2, 2, 2, 2, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 2, 23, 23, 23, 2, 23, 23, 23, 23, 23, 23, 23, 23, - 2, 2, 23, 23, 23, 23, 23, 2, 23, 23, 23, 23, 2, 2, 2, 2, - 2, 2, 2, 23, 23, 2, 23, 23, 23, 2, 2, 23, 2, 2, 23, 23, - 23, 23, 2, 2, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 2, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 16, - 2, 2, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 2, 2, 2, 2, - 2, 2, 2, 16, 16, 2, 16, 16, 16, 16, 2, 2, 16, 16, 2, 16, - 16, 16, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 2, 20, 20, 20, 2, 20, 20, 20, 20, 20, 20, 2, 2, - 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 2, 2, 20, 20, 2, 36, - 36, 36, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 2, 2, 2, 36, 36, 36, 36, 36, 36, 36, 36, - 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 36, 2, 2, 2, 2, - 36, 2, 2, 2, 2, 36, 36, 36, 36, 36, 36, 2, 36, 2, 2, 2, - 2, 2, 2, 2, 36, 36, 2, 2, 36, 36, 36, 2, 2, 2, 2, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 2, 2, 2, 2, 0, 24, 24, 24, 24, 2, 2, 2, 2, 2, 18, - 18, 2, 18, 2, 18, 18, 18, 18, 18, 2, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18, 18, - 18, 18, 18, 18, 2, 2, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18, - 18, 18, 18, 18, 18, 2, 18, 18, 2, 2, 18, 18, 18, 18, 25, 25, - 25, 25, 25, 25, 25, 25, 2, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 2, 2, 2, 25, 25, 25, 25, 25, 2, 25, 25, 25, 25, - 25, 25, 25, 0, 0, 0, 0, 25, 25, 2, 2, 2, 2, 2, 33, 33, - 33, 33, 33, 33, 33, 33, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 2, 8, 2, 2, 2, 2, 2, 8, 2, 2, 8, 8, - 8, 0, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 2, 30, 30, 30, 30, 2, 2, 30, 30, - 30, 30, 30, 30, 30, 2, 30, 30, 30, 2, 2, 30, 30, 30, 30, 30, - 30, 30, 30, 2, 2, 2, 30, 30, 2, 2, 2, 2, 2, 2, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 2, 2, 28, 28, - 28, 28, 28, 28, 28, 28, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 2, 2, 2, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 0, 0, 0, 35, 35, 35, 2, 2, 2, 2, 2, 2, 2, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 45, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 0, 0, 2, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 2, 2, 2, 2, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 2, 46, 46, 46, 2, 46, 46, 2, 2, 2, 2, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 2, 2, 31, 31, - 2, 2, 2, 2, 2, 2, 32, 32, 0, 0, 32, 0, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 2, 2, 2, 2, 2, 2, 32, 2, - 2, 2, 2, 2, 2, 2, 32, 32, 32, 2, 2, 2, 2, 2, 28, 28, - 28, 28, 28, 28, 2, 2, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 2, 48, 48, 48, 48, 2, 2, 2, 2, 48, 2, - 2, 2, 48, 48, 48, 48, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 2, 2, 52, 52, 52, 52, 52, 2, 2, 2, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 2, 2, 2, 2, 58, 58, - 2, 2, 2, 2, 2, 2, 58, 58, 58, 2, 2, 2, 58, 58, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 2, 2, 54, 54, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 2, 91, 91, - 91, 91, 91, 2, 2, 91, 91, 91, 2, 2, 2, 2, 2, 2, 91, 91, - 91, 91, 91, 91, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 2, 62, 62, 76, 76, - 76, 76, 76, 76, 76, 76, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 2, 2, 2, 2, 2, 2, 2, 2, 93, 93, 93, 93, 70, 70, - 70, 70, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 70, 70, 70, 70, - 2, 2, 2, 70, 70, 70, 73, 73, 73, 73, 73, 73, 73, 73, 6, 6, - 6, 2, 2, 2, 2, 2, 8, 8, 8, 2, 2, 8, 8, 8, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, - 0, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, - 9, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, 9, - 19, 19, 19, 19, 9, 9, 9, 9, 9, 19, 19, 19, 19, 19, 6, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 9, 9, - 9, 9, 9, 9, 2, 2, 2, 9, 2, 9, 2, 9, 2, 9, 9, 9, - 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 2, 2, 9, 9, 9, 9, - 9, 9, 2, 9, 9, 9, 2, 2, 9, 9, 9, 2, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 2, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 2, 0, 0, 0, 19, 2, 2, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 2, 19, 19, - 19, 19, 19, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, - 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 19, 0, - 0, 0, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 0, 0, - 0, 2, 2, 2, 2, 2, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, - 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 56, 56, - 56, 56, 56, 56, 56, 56, 55, 55, 55, 55, 2, 2, 2, 2, 2, 55, - 55, 55, 55, 55, 55, 55, 61, 61, 61, 61, 61, 61, 61, 61, 2, 2, - 2, 2, 2, 2, 2, 61, 61, 2, 2, 2, 2, 2, 2, 2, 0, 0, - 0, 0, 0, 0, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 13, 13, - 13, 13, 13, 13, 2, 2, 0, 0, 0, 0, 0, 13, 0, 13, 0, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 13, 13, - 13, 13, 0, 0, 0, 0, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 1, + 17, 17, 17,177, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 5, 3, + 3, 3, 3, 3, 6, 7, 8, 3, 3, 3, 3, 3, 9, 10, 11, 12, + 13, 3, 3, 3, 3, 3, 3, 3, 3, 14, 3, 15, 3, 3, 3, 3, + 3, 3, 16, 17, 18, 19, 20, 21, 3, 3, 3, 22, 23, 24, 3, 3, + 3, 3, 3, 3, 25, 3, 3, 3, 3, 3, 3, 3, 3, 26, 3, 3, + 27, 28, 0, 1, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 7, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, + 0, 0, 0, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, + 13, 0, 0, 14, 15, 16, 6, 0, 17, 18, 19, 19, 19, 20, 21, 22, + 23, 24, 19, 25, 0, 26, 27, 19, 19, 28, 29, 30, 0, 31, 0, 0, + 0, 8, 0, 0, 0, 0, 0, 0, 0, 19, 28, 0, 32, 33, 9, 34, + 35, 19, 0, 0, 36, 37, 38, 39, 40, 19, 0, 41, 42, 43, 44, 31, + 0, 1, 45, 42, 0, 0, 0, 0, 0, 32, 14, 14, 0, 0, 0, 0, + 14, 0, 0, 46, 47, 47, 47, 47, 48, 49, 47, 47, 47, 47, 50, 51, + 52, 53, 43, 21, 0, 0, 0, 0, 0, 0, 0, 54, 6, 55, 0, 14, + 19, 1, 0, 0, 0, 0, 56, 57, 0, 0, 0, 0, 0, 19, 58, 31, + 0, 0, 0, 0, 0, 0, 0, 59, 14, 0, 0, 0, 0, 1, 0, 2, + 0, 0, 0, 3, 0, 0, 0, 60, 61, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 2, 3, 0, 4, 5, 0, 0, 6, 0, 0, + 0, 7, 0, 0, 0, 1, 1, 0, 0, 8, 9, 0, 8, 9, 0, 0, + 0, 0, 8, 9, 10, 11, 12, 0, 0, 0, 13, 0, 0, 0, 0, 14, + 15, 16, 17, 0, 0, 0, 1, 0, 0, 18, 19, 0, 0, 0, 20, 0, + 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 8, + 21, 9, 0, 0, 22, 0, 0, 0, 0, 1, 0, 23, 24, 25, 0, 0, + 26, 0, 0, 0, 8, 21, 27, 0, 1, 0, 0, 1, 1, 1, 1, 0, + 1, 28, 29, 30, 0, 31, 32, 20, 1, 1, 0, 0, 0, 8, 21, 9, + 1, 4, 5, 0, 0, 0, 33, 9, 0, 1, 1, 1, 0, 8, 21, 21, + 21, 21, 34, 1, 35, 21, 21, 21, 9, 36, 0, 0, 37, 38, 1, 0, + 39, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 8, 21, 9, 1, 0, + 0, 0, 40, 0, 8, 21, 21, 21, 21, 21, 21, 21, 21, 9, 0, 1, + 1, 1, 1, 8, 21, 21, 21, 9, 0, 0, 0, 41, 0, 42, 43, 0, + 0, 0, 1, 44, 0, 0, 0, 45, 8, 9, 1, 0, 0, 0, 8, 21, + 21, 21, 9, 0, 1, 0, 1, 1, 8, 21, 21, 9, 0, 4, 5, 8, + 9, 1, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 9, 10, 11, 11, 11, 11, 12, 13, + 13, 13, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 13, 13, 13, + 24, 25, 26, 26, 26, 27, 13, 13, 13, 28, 29, 30, 13, 31, 32, 33, + 34, 35, 36, 37, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 38, 7, 7, 39, 7, 40, 7, 7, + 7, 41, 13, 42, 7, 7, 43, 7, 7, 7, 44, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 45, 0, 0, 1, 2, 2, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 33, 34, 35, 36, 37, 37, + 37, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 2, 2, 53, 54, 55, 56, 57, 58, 59, 59, 59, 59, 60, 59, + 59, 59, 59, 59, 59, 59, 61, 61, 59, 59, 59, 59, 62, 59, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 59, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 78, 69, 69, 69, 69, 79, 79, 79, 79, 79, 79, 79, 79, 79, 80, + 81, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 94, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 69, 69, 96, 97, 98, 99, 99, 99, + 100,101,102,103,104,105,106,107,108,109, 95,110,111,112,113,114, + 115,116,117,117,118,119,120,121,122,123,124,125,126,127,128,129, + 130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145, + 95,146,147,148,149, 95,150,151,152,153,154,155,156,157,158,159, + 160,161, 95,162,163,164,165,165,165,165,165,165,165,166,167,165, + 168, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95,169,170,170,170,170,170,170,170,170,171,170, + 170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, + 170,170,170,170,170,170,170,170,170,170,170,170,170,172,173,173, + 173,173,174, 95, 95, 95, 95, 95,175, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95,176,176,176,176,177,178,179,180, 95, 95, + 181, 95,182,183,184,185,186,186,186,186,186,186,186,186,186,186, + 186,186,186,186,186,186,186,186,186,186,186,186,187,187,187,188, + 189,190, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95,191,192,193,194,195,195,196, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,197,198, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 59,199, + 59, 59, 59,200,201,202, 59,203,204,205,206,207,208, 95,209,210, + 211, 59, 59,212, 59,213,214,214,214,214,214,215, 95, 95, 95, 95, + 95, 95, 95, 95,216, 95,217,218,219, 95, 95,220, 95, 95, 95,221, + 95,222, 95,223, 95,224,225,226,227, 95, 95, 95, 95, 95,228,229, + 230, 95,231,232, 95, 95,233,234, 59,235,236, 95, 59, 59, 59, 59, + 59, 59, 59,237, 59,238,239,240, 59, 59,241,242, 59,243, 95, 95, + 95, 95, 95, 95, 95, 95, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69,244, 69, 69,245, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69,246, 69, 69, 69, 69, 69, 69, 69, 69, 69,247, 69, 69, + 69, 69,248, 95, 95, 95, 69, 69, 69, 69,249, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 69, 69, 69, 69, 69, 69,250, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,251, 95, + 95, 95, 95, 95, 95, 95,252, 95,253,254, 0, 1, 2, 2, 0, 1, + 2, 2, 2, 3, 4, 5, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 0, 0, 0, 19, 0, 19, 0, 0, 0, 0, 0, + 26, 26, 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, 9, 9, 2, 2, + 9, 9, 9, 9, 0, 9, 2, 2, 2, 2, 9, 0, 9, 0, 9, 9, + 9, 2, 9, 2, 9, 9, 9, 9, 2, 9, 9, 9, 55, 55, 55, 55, + 55, 55, 6, 6, 6, 6, 6, 1, 1, 6, 2, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 2, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 2, 2, 2, 2, 14, 14, 2, 2, 2, 3, 3, 3, 3, 3, 0, + 3, 3, 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 1, 1, 1, + 3, 3, 1, 3, 3, 3, 37, 37, 37, 37, 37, 37, 2, 37, 37, 37, + 37, 2, 2, 37, 37, 37, 38, 38, 38, 38, 38, 38, 2, 2, 64, 64, + 64, 64, 64, 64, 64, 2, 2, 64, 64, 64, 90, 90, 90, 90, 90, 90, + 2, 2, 90, 90, 90, 2, 95, 95, 95, 95, 2, 2, 95, 2, 3, 3, + 2, 2, 2, 2, 2, 3, 3, 3, 0, 3, 7, 7, 7, 7, 7, 1, + 1, 1, 1, 7, 7, 7, 0, 0, 7, 7, 5, 5, 5, 5, 2, 5, + 5, 5, 5, 2, 2, 5, 5, 2, 5, 5, 5, 2, 5, 2, 2, 2, + 5, 5, 5, 5, 2, 2, 5, 5, 5, 2, 2, 2, 2, 5, 5, 5, + 2, 5, 2, 11, 11, 11, 11, 11, 11, 2, 2, 2, 2, 11, 11, 2, + 2, 11, 11, 11, 11, 11, 11, 2, 11, 11, 2, 11, 11, 2, 11, 11, + 2, 2, 2, 11, 2, 2, 11, 2, 11, 2, 2, 2, 11, 11, 2, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 2, 10, 10, 10, 10, + 2, 2, 10, 2, 2, 2, 2, 2, 10, 10, 2, 21, 21, 21, 21, 21, + 21, 21, 21, 2, 2, 21, 21, 2, 21, 21, 21, 21, 2, 2, 21, 21, + 2, 21, 2, 2, 21, 21, 2, 2, 22, 22, 2, 22, 22, 22, 22, 22, + 22, 2, 22, 2, 22, 22, 22, 22, 2, 2, 2, 22, 22, 2, 2, 2, + 2, 22, 22, 2, 2, 2, 22, 22, 22, 22, 23, 23, 23, 23, 23, 2, + 23, 23, 23, 23, 2, 2, 2, 23, 23, 2, 23, 23, 23, 2, 2, 2, + 23, 23, 2, 2, 2, 23, 16, 16, 16, 16, 16, 2, 16, 16, 2, 16, + 16, 16, 16, 16, 2, 2, 2, 16, 16, 2, 16, 16, 16, 2, 2, 2, + 16, 16, 20, 20, 20, 20, 20, 2, 20, 20, 2, 2, 20, 20, 2, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2, 36, 36, 36, 36, + 2, 36, 2, 36, 2, 2, 2, 2, 36, 2, 2, 2, 2, 36, 36, 2, + 36, 2, 36, 2, 2, 2, 2, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 2, 2, 2, 2, 0, 2, 18, 18, 2, 18, 2, 18, 18, 18, 18, + 18, 2, 18, 18, 18, 18, 2, 18, 2, 18, 18, 18, 2, 2, 18, 2, + 18, 2, 25, 25, 25, 25, 2, 25, 25, 25, 25, 2, 2, 2, 25, 2, + 25, 25, 25, 0, 0, 0, 0, 25, 25, 2, 33, 33, 33, 33, 8, 8, + 8, 8, 8, 8, 2, 8, 2, 8, 2, 2, 8, 8, 8, 0, 12, 12, + 12, 12, 30, 30, 30, 30, 30, 2, 30, 30, 30, 30, 2, 2, 30, 30, + 30, 2, 2, 30, 30, 30, 30, 2, 2, 2, 29, 29, 29, 29, 29, 29, + 2, 2, 28, 28, 28, 28, 34, 34, 34, 34, 34, 2, 2, 2, 35, 35, + 35, 35, 35, 35, 35, 0, 0, 0, 35, 35, 35, 2, 2, 2, 45, 45, + 45, 45, 45, 45, 2, 2, 2, 2, 2, 45, 44, 44, 44, 44, 44, 0, + 0, 2, 43, 43, 43, 43, 46, 46, 46, 46, 46, 2, 46, 46, 31, 31, + 31, 31, 31, 31, 2, 2, 32, 32, 0, 0, 32, 0, 32, 32, 32, 32, + 32, 32, 32, 32, 2, 2, 32, 2, 2, 2, 32, 32, 32, 2, 28, 28, + 2, 2, 48, 48, 48, 48, 48, 48, 48, 2, 48, 2, 2, 2, 52, 52, + 52, 52, 52, 52, 2, 2, 52, 2, 2, 2, 58, 58, 58, 58, 58, 58, + 2, 2, 58, 58, 58, 2, 2, 2, 58, 58, 54, 54, 54, 54, 2, 2, + 54, 54, 91, 91, 91, 91, 91, 91, 91, 2, 91, 2, 2, 91, 91, 91, + 2, 2, 1, 1, 2, 2, 62, 62, 62, 62, 62, 2, 62, 62, 76, 76, + 76, 76, 93, 93, 93, 93, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, + 2, 2, 2, 70, 70, 70, 73, 73, 73, 73, 6, 6, 6, 2, 8, 8, + 8, 2, 2, 8, 8, 8, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, + 0, 0, 0, 1, 0, 0, 1, 1, 0, 2, 19, 19, 9, 9, 9, 9, + 9, 6, 19, 9, 9, 9, 9, 9, 19, 19, 9, 9, 9, 19, 6, 19, + 19, 19, 19, 19, 19, 9, 9, 9, 2, 2, 2, 9, 2, 9, 2, 9, + 9, 9, 1, 1, 0, 0, 0, 2, 0, 0, 0, 19, 2, 2, 0, 0, + 0, 19, 0, 0, 0, 2, 19, 2, 2, 2, 0, 0, 2, 2, 1, 2, + 2, 2, 0, 0, 9, 0, 0, 0, 19, 19, 27, 27, 27, 27, 2, 2, + 0, 0, 56, 56, 56, 56, 2, 55, 55, 55, 61, 61, 61, 61, 2, 2, + 2, 61, 61, 2, 2, 2, 13, 13, 13, 13, 13, 13, 2, 13, 13, 13, + 2, 2, 0, 13, 0, 13, 0, 13, 13, 13, 13, 13, 1, 1, 1, 1, + 12, 12, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 1, 1, 0, 0, 15, 15, 15, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 17, 17, 17, 2, 2, - 2, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 2, 2, - 2, 2, 2, 2, 2, 0, 12, 12, 12, 12, 12, 12, 12, 0, 17, 17, - 17, 17, 17, 17, 17, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 2, 2, 2, 39, 39, 39, 39, 39, 39, 39, 2, 86, 86, - 86, 86, 86, 86, 86, 86, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, - 77, 77, 2, 2, 2, 2, 79, 79, 79, 79, 79, 79, 79, 79, 0, 0, - 19, 19, 19, 19, 19, 19, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 2, 2, 19, 19, 2, 19, 2, 19, 19, 19, 2, 2, - 19, 19, 19, 19, 19, 19, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 2, 2, 2, 65, 65, 65, 65, 65, 65, 65, 65, 75, 75, - 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 2, 2, 2, 2, - 2, 2, 2, 2, 75, 75, 75, 75, 2, 2, 2, 2, 2, 2, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 0, 69, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 74, 12, 12, 12, 12, 12, 2, 2, 2, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 2, 0, 84, 84, - 2, 2, 2, 2, 84, 84, 33, 33, 33, 33, 33, 33, 33, 2, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 2, 68, 68, - 68, 68, 68, 68, 2, 2, 68, 68, 2, 2, 68, 68, 68, 68, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 2, 2, 2, 2, 2, 2, 2, - 2, 92, 92, 92, 92, 92, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 2, 2, 30, 30, 30, 30, 30, 30, 2, 19, 19, - 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 19, 19, 19, 19, - 0, 0, 2, 2, 2, 2, 87, 87, 87, 87, 87, 87, 2, 2, 87, 87, - 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 2, 2, 2, 2, 2, 2, - 2, 12, 12, 12, 12, 12, 13, 13, 2, 2, 2, 2, 2, 2, 19, 19, - 19, 19, 19, 19, 19, 2, 2, 2, 2, 4, 4, 4, 4, 4, 2, 2, - 2, 2, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 14, 14, - 14, 14, 14, 2, 14, 2, 14, 14, 2, 14, 14, 2, 14, 14, 3, 3, - 3, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 0, 0, 2, 2, 3, 3, 3, 3, 3, 3, 2, 2, - 2, 2, 2, 2, 2, 3, 1, 1, 1, 1, 1, 1, 6, 6, 0, 0, - 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 3, 3, - 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 2, 2, 0, 2, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, - 17, 17, 17, 17, 0, 0, 2, 2, 12, 12, 12, 12, 12, 12, 2, 2, - 12, 12, 12, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 2, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 2, 49, 49, 49, 2, 49, 49, 2, 49, 49, 49, - 49, 49, 49, 49, 2, 2, 49, 49, 49, 2, 2, 2, 2, 2, 0, 0, - 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, - 0, 0, 0, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 2, 0, 0, - 0, 0, 0, 1, 2, 2, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 2, 2, 2, 67, 67, 67, 67, 67, 67, 67, 67, 67, 2, - 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 42, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, - 41, 2, 2, 2, 2, 2,118,118,118,118,118,118,118,118,118,118, - 118, 2, 2, 2, 2, 2, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 2, 53, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 2, 2, 2, 2, 59, 59, 59, 59, 59, 59, 2, 2, 40, 40, - 40, 40, 40, 40, 40, 40, 51, 51, 51, 51, 51, 51, 51, 51, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 2, 2, 50, 50, - 2, 2, 2, 2, 2, 2,135,135,135,135,135,135,135,135,135,135, - 135,135, 2, 2, 2, 2,106,106,106,106,106,106,106,106,104,104, - 104,104,104,104,104,104,104,104,104,104, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2,104,161,161,161,161,161,161,161,161,161,161, - 161, 2,161,161,161,161,161,161,161, 2,161,161, 2,161,161,161, - 2,161,161,161,161,161,161,161, 2,161,161, 2, 2, 2,170,170, - 170,170,170,170,170,170,170,170,170,170, 2, 2, 2, 2,110,110, - 110,110,110,110,110,110,110,110,110,110,110,110,110, 2,110,110, - 110,110,110,110, 2, 2, 19, 19, 19, 19, 19, 19, 2, 19, 19, 2, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 2, 2, 2, 2, 2, 47, 47, - 47, 47, 47, 47, 2, 2, 47, 2, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 2, 47, 47, 2, - 2, 2, 47, 2, 2, 47, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 2, 81,120,120,120,120,120,120,120,120,116,116, - 116,116,116,116,116,116,116,116,116,116,116,116,116, 2, 2, 2, - 2, 2, 2, 2, 2,116,128,128,128,128,128,128,128,128,128,128, - 128, 2,128,128, 2, 2, 2, 2, 2,128,128,128,128,128, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 2, 2, 2, 66, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 2, 2, 2, 2, 2, 72, 98, 98, - 98, 98, 98, 98, 98, 98, 97, 97, 97, 97, 97, 97, 97, 97, 2, 2, - 2, 2, 97, 97, 97, 97, 2, 2, 97, 97, 97, 97, 97, 97, 57, 57, - 57, 57, 2, 57, 57, 2, 2, 2, 2, 2, 57, 57, 57, 57, 57, 57, - 57, 57, 2, 57, 57, 57, 2, 57, 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 2, 2, 57, 57, - 57, 2, 2, 2, 2, 57, 57, 2, 2, 2, 2, 2, 2, 2, 88, 88, - 88, 88, 88, 88, 88, 88,117,117,117,117,117,117,117,117,112,112, - 112,112,112,112,112,112,112,112,112,112,112,112,112, 2, 2, 2, - 2,112,112,112,112,112, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 2, 2, 2, 78, 78, 78, 78, 78, 78, 78, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 2, 2, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 2, 2, 2, 2, 2,122,122, - 122,122,122,122,122,122,122,122, 2, 2, 2, 2, 2, 2, 2,122, - 122,122,122, 2, 2, 2, 2,122,122,122,122,122,122,122, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 2, 2, 2, 2, 2, 2, 2,130,130, - 130,130,130,130,130,130,130,130,130, 2, 2, 2, 2, 2, 2, 2, - 130,130,130,130,130,130,144,144,144,144,144,144,144,144,144,144, - 2, 2, 2, 2, 2, 2,165,165,165,165,165,165,165,165,165,165, - 165,165,165,165, 2, 2, 2,165,165,165,165,165,165,165, 2, 2, - 2, 2, 2, 2,165,165,156,156,156,156,156,156,156,156,156,156, - 2,156,156,156, 2, 2,156,156, 2, 2, 2, 2, 2, 2, 2, 2, - 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3,147,147, - 147,147,147,147,147,147,148,148,148,148,148,148,148,148,148,148, - 2, 2, 2, 2, 2, 2,158,158,158,158,158,158,158,158,158,158, - 2, 2, 2, 2, 2, 2,153,153,153,153,153,153,153,153,153,153, - 153,153, 2, 2, 2, 2,149,149,149,149,149,149,149,149,149,149, - 149,149,149,149,149, 2, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 2, 2, 2, 2, 94, 94, 94, 94, 94, 94, 2, 2, - 2, 2, 2, 2, 2, 94, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 85, 2, 2,101,101, - 101,101,101,101,101,101,101, 2, 2, 2, 2, 2, 2, 2,101,101, - 2, 2, 2, 2, 2, 2, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 2, 96, 96,111,111,111,111,111,111,111,111,111,111, - 111,111,111,111,111, 2,100,100,100,100,100,100,100,100, 2, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2,108,108, - 108,108,108,108,108,108,108,108, 2,108,108,108,108,108,108,108, - 2, 2, 2, 2, 2, 2,129,129,129,129,129,129,129, 2,129, 2, - 129,129,129,129, 2,129,129,129,129,129,129,129,129,129,129,129, - 129,129,129,129, 2,129,129,129, 2, 2, 2, 2, 2, 2,109,109, - 109,109,109,109,109,109,109,109,109, 2, 2, 2, 2, 2,109,109, - 2, 2, 2, 2, 2, 2,107,107,107,107, 2,107,107,107,107,107, - 107,107,107, 2, 2,107,107, 2, 2,107,107,107,107,107,107,107, - 107,107,107,107,107,107,107, 2,107,107,107,107,107,107,107, 2, - 107,107, 2,107,107,107,107,107, 2, 1,107,107,107,107,107, 2, - 2,107,107,107, 2, 2,107, 2, 2, 2, 2, 2, 2,107, 2, 2, - 2, 2, 2,107,107,107,107,107,107,107, 2, 2,107,107,107,107, - 107,107,107, 2, 2, 2,171,171,171,171,171,171,171,171,171,171, - 2,171, 2, 2,171, 2,171,171,171,171,171,171, 2,171,171, 2, - 171, 2, 2,171, 2,171,171,171,171, 2,171,171,171,171,171, 2, - 2, 2, 2, 2, 2, 2, 2,171,171, 2, 2, 2, 2, 2,137,137, - 137,137,137,137,137,137,137,137,137,137, 2,137,137,137,137,137, - 2, 2, 2, 2, 2, 2,124,124,124,124,124,124,124,124,124,124, - 2, 2, 2, 2, 2, 2,123,123,123,123,123,123,123,123,123,123, - 123,123,123,123, 2, 2,114,114,114,114,114,114,114,114,114,114, - 114,114,114, 2, 2, 2,114,114, 2, 2, 2, 2, 2, 2, 32, 32, - 32, 32, 32, 2, 2, 2,102,102,102,102,102,102,102,102,102,102, - 2, 2, 2, 2, 2, 2, 33, 33, 33, 33, 2, 2, 2, 2,126,126, - 126,126,126,126,126,126,126,126,126, 2, 2,126,126,126,126,126, - 126,126, 2, 2, 2, 2,126,126,126,126,126,126,126, 2,142,142, - 142,142,142,142,142,142,142,142,142,142, 2, 2, 2, 2,125,125, - 125,125,125,125,125,125,125,125,125, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2,125,154,154,154,154,154,154,154, 2, 2,154, - 2, 2,154,154,154,154,154,154,154,154, 2,154,154, 2,154,154, - 154,154,154,154,154,154,154,154,154,154,154,154, 2,154,154, 2, - 2,154,154,154,154,154,154,154, 2, 2, 2, 2, 2, 2,150,150, - 150,150,150,150,150,150, 2, 2,150,150,150,150,150,150,150,150, - 150,150,150, 2, 2, 2,141,141,141,141,141,141,141,141,140,140, - 140,140,140,140,140,140,140,140,140, 2, 2, 2, 2, 2,121,121, - 121,121,121,121,121,121,121, 2, 2, 2, 2, 2, 2, 2, 7, 7, - 2, 2, 2, 2, 2, 2,169,169,169,169,169,169,169,169,169,169, - 2, 2, 2, 2, 2, 2,133,133,133,133,133,133,133,133,133, 2, - 133,133,133,133,133,133,133,133,133,133,133,133,133, 2,133,133, - 133,133,133,133, 2, 2,133,133,133,133,133, 2, 2, 2,134,134, - 134,134,134,134,134,134, 2, 2,134,134,134,134,134,134, 2,134, - 134,134,134,134,134,134,134,134,134,134,134,134,134, 2,138,138, - 138,138,138,138,138, 2,138,138, 2,138,138,138,138,138,138,138, - 138,138,138,138,138,138, 2, 2,138, 2,138,138, 2,138,138,138, - 2, 2, 2, 2, 2, 2,143,143,143,143,143,143, 2,143,143, 2, - 143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, - 143,143,143,143,143, 2,143,143, 2,143,143,143,143,143,143, 2, - 2, 2, 2, 2, 2, 2,143,143, 2, 2, 2, 2, 2, 2,145,145, - 145,145,145,145,145,145,145, 2, 2, 2, 2, 2, 2, 2,163,163, - 163,163,163,163,163,163,163, 2,163,163,163,163,163,163,163,163, - 163, 2, 2, 2,163,163,163,163,163, 2, 2, 2, 2, 2, 86, 2, - 2, 2, 2, 2, 2, 2, 22, 22, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 22, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 2, 2, 2, 2, 2, 2, 63, 63, 63, 63, 63, 63, 63, 2, 63, 63, - 63, 63, 63, 2, 2, 2, 63, 63, 63, 63, 2, 2, 2, 2,157,157, - 157,157,157,157,157,157,157,157,157, 2, 2, 2, 2, 2, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 2, 2, 80, 80, - 80, 2, 2, 2, 2, 2,127,127,127,127,127,127,127,127,127,127, - 127,127,127,127,127, 2,166,166,166,166,166,166,166,166,166,166, - 2, 2, 2, 2, 2, 2, 79, 2, 2, 2, 2, 2, 2, 2,115,115, - 115,115,115,115,115,115,115,115,115,115,115,115,115, 2,115,115, - 2, 2, 2, 2,115,115,159,159,159,159,159,159,159,159,159,159, - 159,159,159,159,159, 2,159,159, 2, 2, 2, 2, 2, 2,103,103, - 103,103,103,103,103,103,103,103,103,103,103,103, 2, 2,119,119, - 119,119,119,119,119,119,119,119,119,119,119,119, 2, 2,119,119, - 2,119,119,119,119,119, 2, 2, 2, 2, 2,119,119,119,167,167, - 167,167,167,167,167,167,167,167, 2, 2, 2, 2, 2, 2,146,146, - 146,146,146,146,146,146,146,146,146, 2, 2, 2, 2, 2, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 2, 2, 2, 2, 99, 2, 2, - 2, 2, 2, 2, 2, 99,136,139, 13, 13,155, 2, 2, 2,136,136, - 136,136,136,136,136,136,155,155,155,155,155,155,155,155,155,155, - 155,155,155,155, 2, 2, 2, 2, 2, 2, 2, 2, 2,155,136, 2, - 2, 2, 2, 2, 2, 2, 17, 17, 17, 17, 2, 17, 17, 17, 17, 17, - 17, 17, 2, 17, 17, 2, 17, 15, 15, 15, 15, 15, 15, 15, 17, 17, - 17, 2, 2, 2, 2, 2, 2, 2, 15, 2, 2, 2, 2, 2, 15, 15, - 15, 2, 2, 17, 2, 2, 2, 2, 2, 2, 17, 17, 17, 17,139,139, - 139,139,139,139,139,139,139,139,139,139, 2, 2, 2, 2,105,105, - 105,105,105,105,105,105,105,105,105, 2, 2, 2, 2, 2,105,105, - 105,105,105, 2, 2, 2,105, 2, 2, 2, 2, 2, 2, 2,105,105, - 2, 2,105,105,105,105, 1, 1, 1, 1, 1, 1, 2, 2, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 2, 2, - 0, 2, 2, 0, 0, 2, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, - 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, - 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, - 0, 0, 0, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, - 0, 0, 0, 0, 0, 0,131,131,131,131,131,131,131,131,131,131, - 131,131, 2, 2, 2, 2, 2, 2, 2,131,131,131,131,131, 2,131, - 131,131,131,131,131,131, 2, 2, 2, 2, 2, 19, 19, 19, 56, 56, - 56, 56, 56, 56, 56, 2, 56, 2, 2, 56, 56, 56, 56, 56, 56, 56, - 2, 56, 56, 2, 56, 56, 56, 56, 56, 2, 2, 2, 2, 2, 6, 6, - 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6,151,151, - 151,151,151,151,151,151,151,151,151,151,151, 2, 2, 2,151,151, - 151,151,151,151, 2, 2,151,151, 2, 2, 2, 2,151,151,160,160, - 160,160,160,160,160,160,160,160,160,160,160,160,160, 2,152,152, - 152,152,152,152,152,152,152,152, 2, 2, 2, 2, 2,152,164,164, - 164,164,164,164,164,164,164,164, 2, 2, 2, 2, 2, 2,168,168, - 168,168,168,168,168,168,168,168,168, 2, 2, 2, 2,168, 30, 30, - 30, 30, 2, 30, 30, 2,113,113,113,113,113,113,113,113,113,113, - 113,113,113, 2, 2,113,113,113,113,113,113,113,113, 2,132,132, - 132,132,132,132,132,132,132,132,132,132, 2, 2, 2, 2,132,132, - 2, 2, 2, 2,132,132, 3, 3, 3, 3, 2, 3, 3, 3, 2, 3, - 3, 2, 3, 2, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 2, 2, 2, 2, 2, 2, - 3, 2, 2, 2, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 2, 3, - 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 3, - 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 3, - 3, 3, 2, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 0, 0, 15, 0, 0, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, - 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 0, 13, 2, - 2, 2, 2, 2, 2, 2, 13, 13, 13, 2, 2, 2, 2, 2, 2, 0, - 2, 2, 2, 2, 2, 2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 9, 9, 9, 10, 9, 11, 12, 13, 9, 9, 9, 14, 9, 9, 15, 9, + 17, 0, 2, 26, 26, 26, 26, 26, 26, 26, 2, 12, 12, 12, 12, 12, + 12, 2, 12, 12, 12, 0, 39, 39, 39, 39, 39, 2, 2, 2, 39, 39, + 39, 2, 86, 86, 86, 86, 77, 77, 77, 77, 79, 79, 79, 79, 2, 19, + 19, 19, 60, 60, 60, 60, 60, 2, 2, 2, 65, 65, 65, 65, 75, 75, + 75, 75, 75, 75, 2, 2, 2, 2, 75, 75, 69, 69, 69, 69, 69, 69, + 0, 69, 74, 74, 74, 74, 2, 2, 2, 74, 12, 2, 2, 2, 84, 84, + 84, 84, 84, 84, 2, 0, 84, 84, 2, 2, 2, 2, 84, 84, 33, 33, + 33, 2, 68, 68, 68, 68, 68, 68, 68, 2, 68, 68, 2, 2, 92, 92, + 92, 92, 92, 92, 92, 2, 2, 2, 2, 92, 87, 87, 87, 87, 87, 87, + 87, 2, 19, 9, 19, 19, 19, 19, 0, 0, 87, 87, 2, 2, 2, 2, + 2, 12, 19, 19, 19, 2, 2, 2, 2, 4, 14, 2, 14, 2, 14, 14, + 2, 14, 14, 2, 14, 14, 3, 3, 0, 0, 1, 1, 6, 6, 3, 2, + 3, 3, 3, 2, 2, 0, 2, 0, 0, 0, 0, 0, 17, 17, 17, 17, + 0, 0, 2, 2, 12, 12, 49, 49, 49, 49, 2, 49, 49, 49, 49, 49, + 49, 2, 49, 49, 2, 49, 49, 49, 2, 2, 0, 2, 2, 2, 9, 2, + 2, 2, 0, 1, 2, 2, 71, 71, 71, 71, 71, 2, 2, 2, 67, 67, + 67, 67, 67, 2, 2, 2, 42, 42, 42, 42, 2, 42, 42, 42, 41, 41, + 41, 41, 41, 41, 41, 2,118,118,118,118,118,118,118, 2, 53, 53, + 53, 53, 53, 53, 2, 53, 59, 59, 59, 59, 59, 59, 2, 2, 40, 40, + 40, 40, 51, 51, 51, 51, 50, 50, 50, 50, 50, 50, 2, 2,135,135, + 135,135,106,106,106,106,104,104,104,104, 2, 2, 2,104,161,161, + 161,161,161,161,161, 2,161,161, 2,161,161, 2, 2, 2,170,170, + 170,170,110,110,110,110,110,110,110, 2,110,110, 2, 2, 19, 19, + 2, 19, 19, 2, 19, 19, 47, 47, 47, 47, 47, 47, 2, 2, 47, 2, + 47, 47, 47, 47, 2, 47, 47, 2, 2, 2, 47, 2, 2, 47, 81, 81, + 81, 81, 81, 81, 2, 81,120,120,120,120,116,116,116,116,116,116, + 116, 2, 2, 2, 2,116,128,128,128,128,128,128,128, 2,128,128, + 2, 2, 2, 2, 2,128, 66, 66, 66, 66, 2, 2, 2, 66, 72, 72, + 72, 72, 72, 72, 2, 2, 2, 2, 2, 72,173,173,173,173,173,173, + 2, 2, 98, 98, 98, 98, 97, 97, 97, 97, 2, 2, 97, 97, 57, 57, + 57, 57, 2, 57, 57, 2, 2, 57, 57, 57, 57, 57, 2, 2, 57, 57, + 57, 2, 2, 2, 2, 57, 57, 2, 2, 2, 88, 88, 88, 88,117,117, + 117,117,112,112,112,112,112,112,112, 2, 2, 2, 2,112, 78, 78, + 78, 78, 78, 78, 2, 2, 2, 78, 78, 78, 83, 83, 83, 83, 83, 83, + 2, 2, 82, 82, 82, 82, 82, 82, 82, 2,122,122,122,122,122,122, + 2, 2, 2,122,122,122,122, 2, 2, 2, 89, 89, 89, 89, 89, 2, + 2, 2,130,130,130,130,130,130,130, 2, 2, 2,130,130,144,144, + 144,144,144,144, 2, 2,165,165,165,165,165,165, 2, 2, 2,165, + 165,165, 2, 2,165,165, 3, 3, 3, 2,156,156,156,156,156,156, + 2,156,156,156, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2,147,147, + 147,147,148,148,148,148,148,148, 2, 2,158,158,158,158,158,158, + 2, 2,153,153,153,153,149,149,149,149,149,149,149, 2, 94, 94, + 94, 94, 94, 94, 2, 2, 2, 2, 94, 94, 2, 2, 2, 94, 85, 85, + 85, 85, 85, 85, 85, 2, 2, 85, 2, 2,101,101,101,101,101, 2, + 2, 2,101,101, 2, 2, 96, 96, 96, 96, 96, 2, 96, 96,111,111, + 111,111,111,111,111, 2,100,100,100,100,108,108,108,108,108,108, + 2,108,108,108, 2, 2,129,129,129,129,129,129,129, 2,129, 2, + 129,129,129,129, 2,129,129,129, 2, 2,109,109,109,109,109,109, + 109, 2,109,109, 2, 2,107,107,107,107, 2,107,107,107,107, 2, + 2,107,107, 2,107,107,107,107, 2, 1,107,107, 2, 2,107, 2, + 2, 2, 2, 2, 2,107, 2, 2,107,107,171,171,171,171,171,171, + 2,171, 2, 2,171, 2,171, 2,171, 2, 2,171, 2,171,171,171, + 171, 2,171, 2, 2, 2, 2,171,171, 2,137,137,137,137, 2,137, + 137,137,137,137, 2, 2,124,124,124,124,124,124, 2, 2,123,123, + 123,123,123,123, 2, 2,114,114,114,114,114, 2, 2, 2,114,114, + 2, 2,102,102,102,102,102,102, 2, 2,126,126,126,126,126,126, + 126, 2, 2,126,126,126,142,142,142,142,125,125,125,125,125,125, + 125, 2, 2, 2, 2,125,154,154,154,154,154,154,154, 2, 2,154, + 2, 2, 2,154,154, 2,154,154, 2,154,154, 2, 2,154,154,154, + 2, 2,150,150,150,150, 2, 2,150,150,150, 2, 2, 2,141,141, + 141,141,140,140,140,140,140,140,140, 2,121,121,121,121,121, 2, + 2, 2, 7, 7, 2, 2,169,169,169,169,169,169, 2, 2,133,133, + 133,133,133, 2,133,133,133,133,133, 2,133,133, 2, 2,133, 2, + 2, 2,134,134,134,134, 2, 2,134,134, 2,134,134,134,134,134, + 134, 2,138,138,138,138,138,138,138, 2,138,138, 2,138, 2, 2, + 138, 2,138,138, 2, 2,143,143,143,143,143,143, 2,143,143, 2, + 143,143,143,143,143, 2,143, 2, 2, 2,143,143, 2, 2,175,175, + 175,175,175,175, 2, 2,145,145,145,145,145, 2, 2, 2,163,163, + 163,163,163, 2,163,163,163,163,163, 2, 2, 2,163,163, 86, 2, + 2, 2, 63, 63, 63, 63, 63, 63, 2, 2, 63, 63, 63, 2, 63, 2, + 2, 2,157,157,157,157,157,157,157, 2, 80, 80, 80, 80, 80, 80, + 2, 2, 80, 80, 80, 2,127,127,127,127,127,127,127, 2,166,166, + 166,166,166,166, 2, 2, 79, 2, 2, 2,115,115,115,115,115,115, + 115, 2,115,115, 2, 2, 2, 2,115,115,159,159,159,159,159,159, + 159, 2,159,159, 2, 2,103,103,103,103,103,103, 2, 2,119,119, + 119,119,119,119, 2, 2,119,119, 2,119, 2,119,119,119,167,167, + 167,167,167,167, 2, 2,146,146,146,146,146,146,146, 2,172,172, + 172,172,172, 2, 2,172, 99, 99, 99, 99, 99, 99, 99, 2, 2, 2, + 2, 99,136,139, 13, 13,155, 2, 2, 2, 13, 13, 13, 2,136,136, + 136,136,155,155,155,155,155,155, 2, 2, 2, 2, 2,155,136,136, + 136, 2, 2, 17, 17, 17, 2, 17, 17, 2, 17, 15, 15, 15, 17, 17, + 17, 2, 2, 2, 15, 2, 2, 17, 2, 2,139,139,139,139,105,105, + 105,105,105,105,105, 2,105, 2, 2, 2,105,105, 2, 2, 1, 1, + 1, 2, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 2, 2, + 0, 2, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 2,131,131, + 131,131, 2, 2, 2,131, 2,131,131,131, 56, 56, 56, 2, 56, 2, + 2, 56, 56, 56, 2, 56, 56, 2, 56, 56, 6, 6, 2, 2, 2, 2, + 2, 6,151,151,151,151,151, 2, 2, 2,151,151, 2, 2, 2, 2, + 151,151,160,160,160,160,160,160,160, 2,152,152,152,152,152,152, + 2, 2, 2, 2, 2,152,164,164,164,164,164,164, 2, 2,168,168, + 168,168,168,168,168, 2, 2, 2, 2,168,174,174,174,174,174,174, + 174, 2,174,174, 2, 2, 2, 2,174,174, 2, 30, 30, 2,113,113, + 113,113,113, 2, 2,113,113,113,113, 2,132,132,132,132,132,132, + 2, 2, 2, 2,132,132, 2, 3, 3, 3, 2, 3, 3, 2, 3, 2, + 2, 3, 2, 3, 2, 3, 2, 2, 3, 2, 3, 2, 3, 2, 3, 3, + 2, 3, 15, 0, 0, 2, 0, 2, 2, 0, 13, 2, 2, 2, 2, 0, + 2, 2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 10, + 9, 11, 12, 13, 9, 9, 9, 14, 9, 9, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 16, 17, 9, 9, 9, 9, 18, 9, 9, 9, 9, 9, 19, 20, - 21, 9, 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 23, 9, 9, 9, 9, 9, 24, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 16, 17, + 9, 9, 9, 9, 18, 9, 9, 9, 9, 9, 19, 20, 21, 9, 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 25, 9, + 9, 9, 23, 9, 9, 9, 9, 9, 24, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 25, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -3933,67 +3605,65 @@ _hb_ucd_u8[17524] = 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 24, 25, 26, 27, 28, - 29, 30, 0, 0, 31, 32, 0, 33, 0, 34, 0, 35, 0, 0, 0, 0, - 36, 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 26, 27, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 23, 0, 0, 24, 25, 26, 27, 28, 29, 30, 0, 0, + 31, 32, 0, 33, 0, 34, 0, 35, 0, 0, 0, 0, 36, 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 43, 44, 0, 45, 0, 0, 0, 0, 0, 0, - 46, 47, 0, 0, 0, 0, 0, 48, 0, 49, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 50, 51, 0, 0, 0, 52, 0, 0, - 53, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, - 55, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, - 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 58, 59, 60, 61, 62, 63, 64, 65, - 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 43, 44, 0, 45, 0, 0, 0, 0, 0, 0, 46, 47, 0, 0, + 0, 0, 0, 48, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 50, 51, 0, 0, 0, 52, 0, 0, 53, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, + 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 58, 59, 60, 61, 62, 63, 64, 65, 0, 0, 0, 0, + 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 67, 68, 0, 69, 70, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99,100,101,102,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,104, 0, 0, 0, 0, 0, 0,105,106, 0, - 107, 0, 0, 0,108, 0,109, 0,110, 0,111,112,113, 0,114, 0, - 0, 0,115, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 67, 68, 0, 69, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102, + 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,104, 0, 0, 0, 0, 0, 0,105,106, 0,107, 0, 0, 0, + 108, 0,109, 0,110, 0,111,112,113, 0,114, 0, 0, 0,115, 0, + 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,118,119,120,121, 0,122,123,124, - 125,126, 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,128,129,130,131,132,133,134,135,136,137,138,139, - 140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155, - 156,157, 0, 0, 0,158,159,160,161, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,118,119,120,121, 0,122,123,124,125,126, 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 162, 0,163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,164,165, 0, - 0, 0, 0, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, + 144,145,146,147,148,149,150,151,152,153,154,155,156,157, 0, 0, + 0,158,159,160,161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,167, 0, 0, 0,168,169, 0, 0, - 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,171, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,172, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,162, 0,163, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,164,165, 0, 0, 0, 0, 0, + 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,173, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,167, 0, 0, 0,168,169, 0, 0,170, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,171, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,174, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,175, 0, 0, 0, 0, 0, + 0, 0,174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,176,177, 0, 0, 0, 0,178, - 179, 0, 0, 0,180,181,182,183,184,185,186,187,188,189,190,191, - 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, - 208,209,210,211,212,213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 2, 3, 4, + 0, 0, 0, 0, 0,176,177, 0, 0, 0, 0,178,179, 0, 0, 0, + 180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195, + 196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211, + 212,213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, }; -static const uint16_t -_hb_ucd_u16[9668] = +static const uint16_t _hb_ucd_u16[10904]= { 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12, 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23, @@ -4020,23 +3690,23 @@ _hb_ucd_u16[9668] = 48, 184, 48, 185, 48, 186, 187, 188, 48, 48, 48, 189, 190, 191, 192, 193, 194, 192, 48, 48, 195, 48, 48, 196, 197, 48, 198, 48, 48, 48, 48, 199, 48, 200, 201, 202, 203, 48, 204, 205, 48, 48, 206, 48, 207, 208, 209, 209, - 48, 210, 48, 48, 48, 211, 212, 213, 192, 192, 214, 215, 216, 140, 140, 140, - 217, 48, 48, 218, 219, 160, 220, 221, 222, 48, 223, 64, 48, 48, 224, 225, - 48, 48, 226, 227, 228, 64, 48, 229, 230, 9, 9, 231, 232, 233, 234, 235, - 11, 11, 236, 27, 27, 27, 237, 238, 11, 239, 27, 27, 32, 32, 32, 32, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 240, 13, 13, 13, 13, 13, 13, - 241, 242, 241, 241, 242, 243, 241, 244, 245, 245, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, 271, 272, 272, 273, 274, 275, 209, 276, 277, 209, 278, - 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, - 280, 209, 281, 209, 209, 209, 209, 282, 209, 283, 279, 284, 209, 285, 286, 209, - 209, 209, 176, 140, 287, 140, 271, 271, 271, 288, 209, 209, 209, 209, 289, 271, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 290, 291, 209, 209, 292, - 209, 209, 209, 209, 209, 209, 293, 209, 209, 209, 209, 209, 209, 209, 209, 209, - 209, 209, 209, 209, 209, 209, 294, 295, 271, 296, 209, 209, 297, 279, 298, 279, + 48, 210, 48, 48, 48, 211, 212, 213, 192, 192, 214, 215, 32, 216, 217, 140, + 218, 48, 48, 219, 220, 160, 221, 222, 223, 48, 224, 64, 48, 48, 225, 226, + 48, 48, 227, 228, 229, 64, 48, 230, 231, 9, 9, 232, 233, 234, 235, 236, + 11, 11, 237, 27, 27, 27, 238, 239, 11, 240, 27, 27, 32, 32, 32, 32, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 241, 13, 13, 13, 13, 13, 13, + 242, 243, 242, 242, 243, 244, 242, 245, 246, 246, 246, 247, 248, 249, 250, 251, + 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 273, 274, 275, 276, 209, 277, 278, 209, 279, + 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, + 281, 209, 282, 209, 209, 209, 209, 283, 209, 284, 280, 285, 209, 286, 287, 209, + 209, 209, 176, 140, 288, 140, 272, 272, 272, 289, 209, 209, 209, 209, 290, 272, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 291, 292, 209, 209, 293, + 209, 209, 209, 209, 209, 209, 294, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 209, 209, 209, 209, 209, 209, 295, 296, 272, 297, 209, 209, 298, 280, 299, 280, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, - 279, 279, 279, 279, 279, 279, 279, 279, 299, 300, 279, 279, 279, 301, 279, 302, - 209, 209, 209, 279, 303, 209, 209, 304, 209, 305, 209, 209, 209, 209, 209, 209, + 280, 280, 280, 280, 280, 280, 280, 280, 300, 301, 280, 280, 280, 302, 280, 303, + 209, 209, 209, 280, 304, 209, 209, 305, 209, 209, 209, 209, 209, 209, 209, 209, 9, 9, 9, 11, 11, 11, 306, 307, 13, 13, 13, 13, 13, 13, 308, 309, 11, 11, 310, 48, 48, 48, 311, 312, 48, 313, 314, 314, 314, 314, 32, 32, 315, 316, 317, 318, 319, 320, 140, 140, 209, 321, 209, 209, 209, 209, 209, 322, @@ -4046,7 +3716,7 @@ _hb_ucd_u16[9668] = 209, 333, 334, 209, 335, 336, 209, 209, 334, 209, 209, 336, 209, 209, 209, 209, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 209, 209, 209, 209, 48, 337, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 151, 209, 209, 209, 338, 48, 48, 229, + 48, 48, 48, 48, 48, 48, 48, 48, 151, 209, 209, 209, 338, 48, 48, 230, 339, 48, 340, 140, 13, 13, 341, 342, 13, 343, 48, 48, 48, 48, 344, 345, 31, 346, 347, 348, 13, 13, 13, 349, 350, 351, 352, 353, 354, 355, 140, 356, 357, 48, 358, 359, 48, 48, 48, 360, 361, 48, 48, 362, 363, 192, 32, 364, @@ -4062,1560 +3732,407 @@ _hb_ucd_u16[9668] = 32, 404, 32, 405, 406, 407, 408, 409, 48, 48, 48, 48, 48, 48, 48, 410, 411, 2, 3, 4, 5, 412, 413, 414, 48, 415, 48, 200, 416, 417, 418, 419, 420, 48, 172, 421, 204, 204, 140, 140, 48, 48, 48, 48, 48, 48, 48, 71, - 422, 271, 271, 423, 272, 272, 272, 424, 425, 426, 427, 140, 140, 209, 209, 428, + 422, 272, 272, 423, 273, 273, 273, 424, 425, 426, 427, 140, 140, 209, 209, 428, 140, 140, 140, 140, 140, 140, 140, 140, 48, 151, 48, 48, 48, 100, 429, 430, 48, 48, 431, 48, 432, 48, 48, 433, 48, 434, 48, 48, 435, 436, 140, 140, 9, 9, 437, 11, 11, 48, 48, 48, 48, 204, 192, 9, 9, 438, 11, 439, 48, 48, 440, 48, 48, 48, 441, 442, 442, 443, 444, 445, 48, 48, 48, 388, 48, 48, 48, 313, 48, 199, 440, 140, 446, 27, 27, 447, 140, 140, 140, 140, 448, 48, 48, 449, 48, 450, 48, 451, 48, 200, 452, 140, 140, 140, 48, 453, - 48, 454, 48, 455, 140, 140, 140, 140, 48, 48, 48, 456, 271, 457, 271, 271, + 48, 454, 48, 455, 48, 207, 140, 140, 48, 48, 48, 456, 272, 457, 272, 272, 458, 459, 48, 460, 461, 462, 48, 463, 48, 464, 140, 140, 465, 48, 466, 467, 48, 48, 48, 468, 48, 469, 48, 470, 48, 471, 472, 140, 140, 140, 140, 140, 48, 48, 48, 48, 196, 140, 140, 140, 9, 9, 9, 473, 11, 11, 11, 474, 48, 48, 475, 192, 476, 9, 477, 11, 478, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 271, 479, 48, 48, 480, 481, 482, 140, 140, 483, - 48, 464, 484, 48, 62, 485, 140, 48, 486, 140, 140, 48, 487, 140, 48, 313, - 488, 48, 48, 489, 490, 457, 491, 492, 222, 48, 48, 493, 494, 48, 196, 192, - 495, 48, 496, 497, 498, 48, 48, 499, 222, 48, 48, 500, 501, 502, 503, 504, - 48, 97, 505, 506, 507, 140, 140, 140, 508, 509, 510, 48, 48, 511, 512, 192, - 513, 83, 84, 514, 515, 516, 517, 518, 519, 48, 48, 520, 521, 522, 523, 140, - 48, 48, 48, 524, 525, 526, 481, 140, 48, 48, 48, 527, 528, 192, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 529, 530, 531, 532, 140, 140, - 48, 48, 48, 533, 534, 192, 535, 140, 48, 48, 536, 537, 192, 538, 539, 140, - 48, 540, 541, 542, 313, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 48, 505, 543, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 544, - 545, 546, 48, 547, 548, 192, 140, 140, 140, 140, 549, 48, 48, 550, 551, 140, - 552, 48, 48, 553, 554, 555, 48, 48, 556, 557, 558, 48, 48, 48, 48, 196, - 559, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 560, 192, - 84, 48, 529, 561, 562, 148, 175, 563, 48, 564, 565, 566, 140, 140, 140, 140, - 567, 48, 48, 568, 569, 192, 570, 48, 571, 572, 192, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 573, - 574, 115, 48, 575, 576, 577, 140, 140, 140, 140, 140, 100, 271, 578, 579, 580, + 140, 140, 140, 140, 140, 140, 272, 479, 48, 48, 480, 481, 482, 483, 140, 484, + 48, 464, 485, 48, 62, 486, 140, 48, 487, 140, 140, 48, 488, 140, 48, 313, + 489, 48, 48, 490, 491, 457, 492, 493, 223, 48, 48, 494, 495, 48, 196, 192, + 496, 48, 497, 498, 499, 48, 48, 500, 223, 48, 48, 501, 502, 503, 504, 505, + 48, 97, 506, 507, 508, 140, 140, 140, 509, 510, 511, 48, 48, 512, 513, 192, + 514, 83, 84, 515, 516, 517, 518, 519, 520, 48, 48, 521, 522, 523, 524, 140, + 48, 48, 48, 525, 526, 527, 481, 140, 48, 48, 48, 528, 529, 192, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 530, 531, 532, 533, 140, 140, + 48, 48, 48, 534, 535, 192, 536, 140, 48, 48, 537, 538, 192, 539, 540, 140, + 48, 541, 542, 543, 313, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 506, 544, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 545, + 546, 547, 48, 548, 549, 192, 140, 140, 140, 140, 550, 48, 48, 551, 552, 140, + 553, 48, 48, 554, 555, 556, 48, 48, 557, 558, 559, 48, 48, 48, 48, 196, + 560, 140, 140, 140, 140, 140, 561, 140, 140, 140, 140, 140, 48, 48, 562, 192, + 84, 48, 530, 563, 564, 148, 175, 565, 48, 566, 567, 568, 140, 140, 140, 140, + 569, 48, 48, 570, 571, 192, 572, 48, 573, 574, 192, 48, 48, 575, 192, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 576, + 577, 115, 48, 578, 579, 580, 140, 140, 140, 140, 140, 100, 272, 581, 582, 583, 48, 48, 48, 48, 48, 48, 48, 48, 48, 207, 140, 140, 140, 140, 140, 140, - 272, 272, 272, 272, 272, 272, 581, 582, 48, 48, 48, 48, 48, 48, 48, 48, + 273, 273, 273, 273, 273, 273, 584, 585, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 388, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 583, - 48, 48, 48, 584, 585, 586, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 586, + 48, 48, 48, 587, 588, 589, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 71, 48, 48, 48, 48, 313, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 587, 588, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 48, 48, 196, 48, 200, 370, 48, 48, 48, 48, 200, 192, 48, 204, 589, - 48, 48, 48, 590, 591, 592, 593, 594, 48, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 595, 48, 596, 192, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 9, 9, 11, 11, 271, 597, 140, 140, 140, 140, 140, 140, - 48, 48, 48, 48, 598, 599, 600, 600, 601, 602, 140, 140, 140, 140, 603, 604, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 440, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 199, 140, 605, - 196, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 606, - 48, 48, 607, 608, 140, 609, 610, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 590, 591, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 196, 48, 200, 370, 48, 48, 48, 48, 200, 192, 48, 204, 592, + 48, 48, 48, 593, 594, 595, 596, 597, 48, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 598, 48, 599, 192, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 9, 9, 11, 11, 272, 600, 9, 601, 11, 602, 140, 140, + 48, 48, 48, 48, 603, 604, 605, 605, 606, 607, 140, 140, 140, 140, 608, 609, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 199, 140, 610, + 48, 200, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 48, 611, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 612, + 48, 48, 611, 613, 140, 614, 615, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 206, - 48, 48, 48, 48, 48, 48, 71, 151, 196, 611, 612, 140, 140, 140, 140, 140, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 192, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 322, 140, 140, 140, 140, - 32, 32, 613, 32, 614, 209, 209, 209, 209, 209, 209, 209, 322, 140, 140, 140, + 48, 48, 48, 48, 48, 48, 71, 151, 196, 616, 617, 140, 140, 140, 140, 140, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 618, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 619, 209, 427, 209, 620, + 32, 32, 216, 32, 621, 209, 209, 209, 209, 209, 209, 209, 322, 140, 140, 140, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 323, - 209, 209, 615, 209, 209, 209, 616, 617, 618, 209, 619, 209, 209, 209, 287, 140, - 209, 209, 209, 209, 620, 140, 140, 140, 140, 140, 140, 140, 271, 621, 271, 621, - 209, 209, 209, 209, 209, 338, 271, 461, 140, 140, 140, 140, 140, 140, 140, 140, - 9, 622, 11, 623, 624, 625, 241, 9, 626, 627, 628, 629, 630, 9, 622, 11, - 631, 632, 11, 633, 634, 635, 636, 9, 637, 11, 9, 622, 11, 623, 624, 11, - 241, 9, 626, 636, 9, 637, 11, 9, 622, 11, 638, 9, 639, 640, 641, 642, - 11, 643, 9, 644, 645, 646, 647, 11, 648, 9, 649, 11, 650, 538, 538, 538, - 32, 32, 32, 651, 32, 32, 652, 653, 654, 655, 45, 140, 140, 140, 140, 140, - 656, 657, 658, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 659, 660, 661, 27, 27, 27, 662, 140, 663, 140, 140, 140, 140, 140, 140, 140, - 48, 48, 151, 664, 665, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 666, 140, 48, 48, 667, 668, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 669, 192, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 587, 670, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 671, 200, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 672, 614, 140, 140, - 9, 9, 626, 11, 673, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 503, 271, 271, 674, 675, 140, 140, 140, 140, - 503, 271, 676, 677, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 678, 48, 679, 680, 681, 682, 683, 684, 685, 206, 686, 206, 140, 140, 140, 687, - 209, 209, 688, 209, 209, 209, 209, 209, 209, 322, 333, 689, 689, 689, 209, 323, - 690, 209, 209, 209, 209, 209, 209, 209, 209, 209, 691, 140, 140, 140, 692, 209, - 693, 209, 209, 688, 694, 695, 323, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 696, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 697, 426, 426, - 209, 209, 209, 209, 209, 209, 209, 698, 209, 209, 209, 209, 209, 176, 688, 427, - 688, 209, 209, 209, 699, 176, 209, 209, 699, 209, 691, 688, 695, 140, 140, 140, - 209, 209, 209, 209, 209, 322, 691, 426, 700, 209, 209, 209, 701, 702, 176, 694, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 703, 209, 209, 209, 209, 209, 192, + 209, 209, 622, 209, 209, 209, 623, 624, 625, 209, 626, 209, 209, 209, 288, 140, + 209, 209, 209, 209, 627, 140, 140, 140, 140, 140, 140, 140, 272, 628, 272, 628, + 209, 209, 209, 209, 209, 338, 272, 461, 140, 140, 140, 140, 140, 140, 140, 140, + 9, 629, 11, 630, 631, 632, 242, 9, 633, 634, 635, 636, 637, 9, 629, 11, + 638, 639, 11, 640, 641, 642, 643, 9, 644, 11, 9, 629, 11, 630, 631, 11, + 242, 9, 633, 643, 9, 644, 11, 9, 629, 11, 645, 9, 646, 647, 648, 649, + 11, 650, 9, 651, 652, 653, 654, 11, 655, 9, 656, 11, 657, 539, 539, 539, + 32, 32, 32, 658, 32, 32, 659, 660, 661, 662, 45, 140, 140, 140, 140, 140, + 663, 664, 665, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 666, 667, 668, 27, 27, 27, 669, 140, 670, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 151, 671, 672, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 673, 140, 48, 48, 674, 675, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 676, 192, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 590, 677, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 200, 678, 679, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 680, 200, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 681, 621, 140, 140, + 9, 9, 633, 11, 682, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 504, 272, 272, 683, 684, 140, 140, 140, 140, + 504, 272, 685, 686, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 687, 48, 688, 689, 690, 691, 692, 693, 694, 206, 695, 206, 140, 140, 140, 696, + 209, 209, 697, 209, 209, 209, 209, 209, 209, 322, 333, 698, 698, 698, 209, 323, + 699, 209, 209, 209, 209, 209, 209, 209, 209, 209, 700, 140, 140, 140, 701, 209, + 702, 209, 209, 697, 703, 704, 323, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 705, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 706, 426, 426, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 176, 697, 427, + 697, 209, 209, 209, 707, 176, 209, 209, 707, 209, 700, 697, 704, 708, 140, 140, + 209, 209, 209, 209, 209, 707, 700, 426, 709, 209, 209, 209, 710, 711, 712, 703, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 713, 209, 209, 209, 209, 209, 714, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, - 48, 48, 48, 207, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 481, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 100, 48, 48, 48, 48, 48, 48, 204, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 204, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 71, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, 140, 140, 140, - 704, 140, 584, 584, 584, 584, 584, 584, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 48, 48, 48, 48, 207, 140, 140, 140, 140, 140, 140, 140, 140, + 715, 140, 587, 587, 587, 587, 587, 587, 140, 140, 140, 140, 140, 140, 140, 140, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 140, - 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 705, - 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 706, - 0, 0, 1, 1, 0, 2, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 5, 0, 6, 7, 7, 7, 8, 9, 10, 11, 12, - 13, 13, 13, 13, 14, 13, 13, 13, 13, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 23, 23, 26, 23, 27, 28, 29, 23, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 23, 23, 39, 40, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 85, 82, 86, 86, 87, 88, 89, 90, 91, 82, - 92, 92, 92, 92, 92, 93, 94, 95, 96, 96, 96, 96, 96, 96, 96, 96, - 97, 97, 98, 97, 99, 100, 101, 97, 102, 97, 103, 104, 105, 106, 106, 107, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 109, 110, 110, 111, - 112, 113, 114, 115, 116, 116, 117, 118, 119, 120, 120, 121, 120, 122, 108, 123, - 124, 125, 126, 127, 128, 129, 130, 116, 131, 132, 133, 134, 135, 136, 137, 82, - 138, 138, 139, 138, 140, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, - 4, 151, 152, 153, 4, 154, 7, 7, 155, 11, 156, 157, 11, 158, 159, 160, - 161, 0, 0, 162, 163, 0, 164, 165, 0, 166, 167, 4, 168, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 169, 170, 0, 0, 0, 0, 0, - 171, 171, 171, 171, 171, 171, 171, 171, 0, 0, 0, 172, 173, 0, 0, 0, - 174, 174, 174, 4, 175, 175, 175, 176, 93, 177, 178, 179, 180, 181, 181, 13, - 0, 0, 182, 82, 183, 184, 184, 185, 184, 184, 184, 184, 184, 184, 186, 187, - 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 96, 96, 198, 199, 0, 200, - 201, 0, 0, 202, 0, 0, 203, 204, 194, 194, 205, 0, 0, 0, 0, 0, - 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 0, 0, - 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 207, 206, 208, 209, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 211, 13, 13, 13, 212, 212, 213, - 0, 214, 4, 4, 215, 4, 216, 217, 218, 219, 220, 221, 222, 222, 223, 40, - 224, 225, 226, 227, 228, 228, 229, 230, 231, 232, 233, 92, 234, 234, 235, 236, - 237, 238, 239, 240, 106, 106, 241, 242, 96, 96, 96, 96, 96, 243, 244, 245, - 82, 82, 82, 82, 82, 82, 82, 82, 184, 184, 184, 246, 184, 184, 247, 82, - 248, 249, 250, 23, 23, 23, 251, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 252, 23, 23, 253, 23, 254, 255, 256, 257, 258, 259, 23, 23, 23, 260, - 261, 1, 1, 262, 263, 201, 264, 265, 266, 267, 268, 82, 269, 269, 269, 270, - 271, 272, 11, 11, 273, 274, 187, 275, 82, 82, 82, 82, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 82, 287, 287, 288, 289, 290, 291, 292, 293, - 294, 295, 296, 297, 298, 299, 300, 301, 302, 302, 302, 302, 302, 302, 302, 302, - 302, 303, 304, 305, 306, 307, 82, 82, 308, 309, 310, 311, 312, 313, 82, 314, - 315, 316, 82, 82, 317, 318, 319, 320, 321, 322, 323, 324, 325, 82, 326, 327, - 328, 329, 330, 331, 332, 333, 82, 82, 334, 334, 335, 82, 336, 337, 336, 338, - 339, 340, 341, 342, 343, 82, 82, 82, 82, 82, 82, 344, 345, 346, 347, 348, - 349, 350, 351, 352, 353, 354, 355, 356, 357, 357, 358, 359, 360, 360, 361, 362, - 363, 364, 365, 366, 367, 367, 367, 368, 369, 370, 371, 82, 372, 373, 374, 375, - 376, 377, 378, 379, 380, 381, 382, 383, 384, 384, 385, 386, 387, 387, 388, 82, - 82, 82, 82, 82, 389, 390, 391, 82, 392, 392, 393, 394, 395, 396, 397, 398, - 399, 400, 401, 82, 82, 82, 82, 82, 402, 403, 82, 82, 82, 404, 404, 405, - 406, 407, 408, 82, 82, 409, 410, 411, 412, 412, 413, 414, 414, 415, 416, 417, - 418, 82, 82, 82, 82, 82, 419, 420, 421, 422, 423, 424, 425, 426, 82, 82, - 427, 428, 429, 430, 431, 432, 82, 82, 82, 82, 82, 82, 82, 82, 82, 433, - 434, 435, 436, 82, 82, 437, 438, 439, 440, 440, 440, 440, 440, 440, 440, 440, - 440, 440, 440, 440, 441, 82, 82, 82, 440, 440, 440, 442, 440, 440, 440, 440, - 440, 440, 443, 82, 82, 82, 82, 82, 82, 82, 82, 82, 444, 445, 445, 446, - 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 448, 447, 447, 447, 447, 447, - 447, 447, 447, 447, 447, 447, 447, 449, 450, 450, 450, 450, 450, 450, 450, 450, - 450, 450, 451, 82, 82, 82, 82, 82, 452, 453, 82, 82, 82, 82, 82, 82, - 212, 212, 212, 212, 212, 212, 212, 212, 212, 454, 455, 456, 457, 458, 459, 460, - 461, 461, 462, 463, 464, 82, 82, 82, 82, 82, 465, 466, 82, 82, 82, 82, - 82, 82, 467, 467, 468, 82, 82, 82, 469, 469, 470, 469, 471, 82, 82, 472, - 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 474, - 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 476, 477, - 478, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 479, - 480, 191, 191, 191, 191, 191, 191, 191, 191, 481, 482, 483, 484, 484, 484, 484, - 484, 484, 484, 484, 484, 484, 484, 485, 486, 486, 486, 487, 488, 489, 82, 82, - 0, 0, 0, 0, 0, 0, 0, 490, 0, 0, 0, 0, 0, 491, 82, 82, - 7, 492, 493, 0, 0, 0, 489, 82, 0, 0, 0, 0, 0, 0, 0, 494, - 0, 495, 0, 496, 497, 498, 0, 170, 11, 11, 499, 82, 82, 82, 491, 491, - 0, 0, 500, 501, 82, 82, 82, 82, 0, 0, 502, 0, 503, 504, 505, 0, - 506, 507, 508, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 509, 0, 0, - 0, 0, 0, 0, 0, 0, 510, 0, 511, 511, 511, 511, 511, 511, 511, 511, - 511, 511, 511, 511, 512, 513, 82, 82, 514, 515, 82, 82, 82, 82, 82, 82, - 516, 517, 13, 518, 519, 82, 82, 82, 520, 521, 522, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 523, 524, 525, 526, 82, 82, 82, 82, 82, 82, 527, 528, - 82, 82, 82, 82, 82, 82, 529, 530, 82, 82, 82, 82, 82, 82, 82, 531, - 532, 532, 532, 532, 532, 532, 533, 82, 534, 534, 535, 82, 82, 82, 82, 82, - 82, 82, 82, 536, 0, 537, 82, 82, 261, 182, 82, 82, 82, 82, 82, 82, - 538, 539, 540, 541, 542, 543, 82, 544, 0, 545, 0, 0, 491, 546, 547, 494, - 0, 0, 0, 0, 0, 548, 82, 549, 550, 551, 552, 553, 82, 82, 82, 82, - 0, 0, 0, 0, 0, 0, 554, 555, 0, 0, 0, 556, 0, 0, 490, 557, - 545, 0, 558, 0, 559, 560, 561, 82, 0, 0, 491, 562, 563, 0, 564, 565, - 0, 0, 0, 0, 258, 0, 0, 490, 184, 184, 184, 184, 184, 184, 184, 82, - 184, 247, 184, 184, 184, 184, 184, 184, 566, 184, 184, 184, 184, 184, 184, 184, - 184, 184, 184, 184, 184, 567, 184, 184, 184, 184, 184, 184, 184, 184, 184, 568, - 184, 184, 566, 82, 82, 82, 82, 82, 566, 82, 82, 82, 82, 82, 82, 82, - 184, 184, 569, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 570, 82, 82, - 571, 0, 0, 0, 82, 82, 82, 82, 7, 7, 7, 7, 7, 7, 7, 572, - 0, 0, 0, 0, 1, 2, 2, 3, 0, 4, 0, 4, 2, 2, 5, 2, - 2, 2, 2, 2, 2, 2, 2, 6, 7, 8, 0, 0, 9, 9, 9, 9, - 9, 9, 10, 11, 12, 13, 14, 14, 15, 14, 14, 14, 14, 14, 14, 14, - 16, 17, 14, 14, 18, 18, 18, 18, 19, 18, 18, 18, 18, 18, 20, 21, - 21, 21, 22, 20, 21, 21, 21, 21, 21, 23, 24, 25, 25, 25, 25, 25, - 25, 26, 25, 25, 25, 27, 28, 26, 29, 30, 31, 32, 31, 31, 31, 31, - 33, 34, 35, 31, 31, 31, 36, 31, 31, 31, 31, 29, 37, 38, 37, 37, - 37, 37, 37, 37, 37, 39, 31, 31, 40, 40, 40, 40, 40, 40, 41, 26, - 42, 42, 42, 42, 42, 42, 42, 43, 44, 44, 44, 44, 44, 45, 44, 46, - 47, 47, 47, 48, 37, 49, 31, 31, 31, 50, 51, 31, 52, 31, 31, 31, - 53, 53, 53, 53, 53, 53, 54, 53, 55, 53, 53, 53, 56, 57, 58, 59, - 59, 60, 61, 62, 57, 63, 64, 65, 66, 59, 59, 67, 68, 69, 70, 71, - 71, 72, 73, 74, 69, 75, 76, 77, 78, 71, 79, 26, 80, 81, 82, 83, - 83, 84, 85, 86, 81, 87, 88, 26, 89, 83, 90, 91, 92, 93, 94, 95, - 95, 96, 97, 98, 93, 99, 100, 101, 102, 95, 95, 26, 103, 104, 105, 106, - 107, 104, 108, 109, 104, 105, 110, 26, 111, 108, 108, 112, 113, 114, 115, 113, - 113, 115, 113, 116, 114, 117, 118, 119, 120, 113, 121, 113, 122, 123, 124, 122, - 122, 124, 125, 126, 123, 127, 128, 128, 129, 122, 130, 26, 131, 132, 133, 131, - 131, 131, 131, 131, 132, 133, 134, 131, 135, 131, 131, 131, 136, 137, 138, 139, - 137, 137, 140, 141, 138, 142, 143, 137, 144, 137, 145, 26, 146, 147, 147, 147, - 147, 147, 147, 148, 147, 147, 147, 149, 26, 26, 26, 26, 150, 151, 152, 152, - 153, 152, 152, 154, 155, 156, 152, 157, 158, 158, 158, 158, 158, 159, 158, 158, - 158, 160, 159, 158, 158, 158, 158, 159, 158, 158, 158, 161, 158, 161, 162, 163, - 164, 164, 164, 164, 165, 165, 165, 165, 166, 167, 165, 165, 165, 165, 165, 168, - 169, 169, 169, 169, 170, 170, 170, 170, 170, 171, 172, 171, 170, 171, 170, 170, - 170, 170, 171, 172, 171, 170, 172, 170, 170, 170, 171, 170, 170, 170, 170, 173, - 170, 170, 170, 174, 170, 170, 170, 175, 176, 176, 176, 176, 176, 176, 177, 177, - 178, 178, 178, 178, 179, 179, 179, 180, 181, 181, 181, 181, 181, 182, 181, 183, - 184, 184, 185, 186, 187, 187, 188, 26, 189, 189, 190, 26, 191, 192, 193, 26, - 194, 194, 194, 194, 194, 194, 194, 195, 194, 196, 194, 196, 197, 198, 198, 199, - 198, 198, 198, 198, 198, 198, 198, 200, 198, 201, 178, 178, 178, 178, 202, 26, - 203, 203, 203, 204, 203, 205, 203, 205, 206, 203, 207, 207, 207, 208, 209, 26, - 210, 210, 210, 210, 210, 211, 210, 210, 210, 212, 210, 213, 214, 214, 214, 215, - 216, 216, 216, 216, 216, 216, 216, 217, 216, 216, 216, 218, 216, 219, 216, 219, - 216, 220, 9, 9, 9, 221, 26, 26, 222, 222, 222, 222, 222, 223, 222, 222, - 224, 224, 224, 224, 225, 225, 225, 225, 225, 225, 226, 227, 228, 228, 228, 228, - 228, 228, 228, 229, 228, 230, 231, 231, 231, 231, 231, 231, 18, 232, 165, 165, - 165, 165, 165, 233, 224, 26, 234, 9, 235, 236, 237, 238, 239, 240, 2, 2, - 2, 2, 2, 241, 242, 243, 2, 244, 2, 2, 2, 245, 14, 14, 246, 246, - 246, 246, 14, 247, 14, 14, 14, 246, 14, 14, 248, 14, 248, 14, 249, 250, - 14, 14, 251, 252, 0, 253, 0, 0, 254, 0, 255, 256, 0, 257, 2, 258, - 259, 26, 9, 9, 9, 9, 260, 26, 261, 262, 4, 0, 0, 263, 0, 0, - 2, 264, 0, 0, 0, 265, 26, 26, 0, 266, 26, 26, 267, 267, 267, 267, - 0, 0, 268, 0, 0, 0, 269, 0, 270, 270, 270, 270, 17, 17, 17, 17, - 17, 17, 271, 272, 166, 167, 273, 273, 273, 273, 273, 273, 273, 274, 275, 274, - 170, 170, 172, 26, 172, 172, 172, 172, 0, 0, 0, 276, 277, 277, 277, 278, - 277, 277, 277, 277, 277, 277, 279, 26, 277, 277, 280, 26, 26, 26, 0, 0, - 281, 0, 0, 0, 282, 283, 0, 284, 285, 286, 286, 286, 286, 286, 286, 286, - 286, 286, 287, 288, 289, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 291, - 292, 293, 293, 293, 293, 293, 294, 169, 169, 295, 0, 0, 293, 293, 293, 293, - 276, 296, 290, 290, 169, 169, 169, 295, 169, 169, 169, 297, 0, 0, 290, 290, - 290, 290, 290, 298, 290, 290, 290, 0, 299, 299, 299, 299, 299, 300, 299, 299, - 301, 26, 302, 302, 302, 302, 302, 302, 303, 303, 303, 303, 303, 304, 26, 26, - 305, 305, 305, 305, 305, 305, 305, 26, 306, 2, 2, 2, 2, 307, 2, 2, - 2, 308, 309, 258, 26, 26, 310, 2, 311, 311, 311, 311, 311, 312, 0, 265, - 313, 313, 313, 313, 313, 313, 313, 26, 314, 314, 314, 314, 315, 316, 314, 317, - 318, 318, 318, 318, 318, 319, 320, 320, 320, 320, 321, 322, 169, 169, 169, 323, - 324, 324, 324, 324, 324, 325, 324, 326, 164, 164, 164, 327, 328, 328, 328, 328, - 328, 328, 329, 26, 328, 330, 328, 331, 332, 332, 332, 332, 333, 26, 26, 334, - 335, 335, 336, 26, 337, 337, 337, 26, 172, 172, 2, 2, 2, 2, 2, 338, - 339, 340, 176, 176, 335, 335, 335, 335, 335, 341, 335, 342, 343, 26, 169, 169, - 295, 344, 169, 169, 169, 169, 169, 343, 277, 280, 277, 277, 277, 277, 277, 345, - 346, 26, 347, 348, 25, 25, 349, 350, 351, 25, 31, 31, 352, 26, 353, 31, - 31, 31, 31, 354, 31, 31, 355, 31, 31, 356, 26, 26, 26, 26, 31, 31, - 9, 9, 0, 265, 9, 357, 0, 0, 0, 0, 358, 0, 257, 359, 360, 31, - 31, 31, 31, 361, 362, 0, 0, 0, 363, 290, 289, 290, 290, 290, 290, 364, - 365, 365, 365, 366, 257, 257, 26, 367, 368, 369, 368, 368, 370, 368, 368, 371, - 368, 372, 368, 372, 368, 368, 368, 368, 368, 368, 368, 373, 374, 0, 0, 0, - 0, 0, 375, 0, 14, 252, 0, 376, 377, 26, 26, 26, 0, 0, 0, 378, - 379, 379, 379, 380, 381, 381, 381, 381, 381, 381, 382, 26, 383, 0, 0, 359, - 384, 384, 384, 384, 385, 386, 387, 387, 387, 388, 389, 389, 389, 389, 389, 390, - 391, 391, 391, 392, 393, 393, 393, 393, 394, 393, 395, 26, 396, 396, 396, 396, - 396, 396, 397, 397, 397, 397, 397, 397, 398, 398, 398, 399, 398, 400, 401, 401, - 401, 401, 402, 401, 401, 401, 401, 402, 403, 403, 403, 403, 403, 26, 404, 404, - 404, 404, 404, 404, 405, 406, 407, 408, 407, 408, 409, 407, 410, 407, 410, 411, - 412, 412, 412, 412, 412, 412, 413, 26, 414, 414, 414, 414, 414, 414, 415, 26, - 414, 414, 416, 26, 414, 26, 26, 26, 417, 2, 2, 2, 2, 2, 418, 419, - 420, 421, 422, 422, 422, 422, 423, 424, 425, 425, 426, 425, 427, 427, 427, 427, - 428, 428, 428, 429, 430, 428, 26, 26, 431, 431, 432, 433, 434, 434, 434, 435, - 436, 436, 436, 437, 438, 438, 438, 438, 439, 439, 439, 440, 439, 439, 441, 439, - 439, 439, 439, 439, 442, 443, 444, 445, 446, 446, 447, 448, 446, 449, 446, 449, - 450, 450, 450, 450, 451, 451, 451, 451, 452, 452, 452, 452, 453, 454, 453, 26, - 455, 455, 455, 455, 455, 455, 456, 457, 458, 458, 459, 458, 460, 460, 461, 460, - 462, 462, 463, 464, 26, 465, 26, 26, 466, 466, 466, 466, 466, 467, 26, 26, - 468, 468, 468, 468, 468, 468, 469, 26, 468, 468, 469, 470, 471, 471, 471, 471, - 471, 26, 471, 472, 473, 473, 473, 473, 474, 475, 473, 473, 474, 476, 26, 26, - 31, 31, 31, 50, 477, 477, 477, 477, 477, 478, 479, 26, 480, 26, 26, 26, - 26, 26, 26, 481, 482, 482, 482, 482, 482, 26, 483, 483, 483, 483, 483, 484, - 26, 26, 485, 485, 485, 486, 26, 26, 26, 26, 487, 487, 487, 488, 26, 26, - 489, 489, 490, 26, 491, 491, 491, 491, 491, 492, 493, 491, 491, 491, 492, 494, - 495, 495, 495, 495, 496, 497, 498, 498, 498, 499, 498, 500, 501, 501, 501, 501, - 501, 501, 502, 501, 501, 26, 503, 503, 503, 503, 504, 26, 505, 505, 505, 505, - 506, 137, 507, 26, 508, 508, 509, 508, 508, 508, 508, 508, 510, 26, 26, 26, - 511, 512, 513, 514, 513, 515, 516, 516, 516, 516, 516, 516, 516, 517, 516, 518, - 519, 520, 521, 522, 522, 523, 524, 525, 520, 526, 527, 528, 529, 530, 530, 26, - 531, 532, 531, 531, 531, 531, 533, 531, 534, 535, 533, 536, 537, 26, 26, 26, - 538, 538, 538, 538, 538, 538, 538, 539, 540, 26, 26, 26, 541, 541, 541, 541, - 541, 26, 541, 542, 543, 543, 543, 543, 543, 543, 544, 543, 543, 543, 543, 544, - 545, 545, 545, 545, 546, 26, 545, 547, 198, 548, 26, 26, 549, 549, 549, 549, - 549, 549, 549, 550, 549, 550, 164, 164, 551, 26, 26, 26, 552, 552, 552, 553, - 552, 554, 552, 552, 555, 26, 26, 26, 556, 556, 556, 556, 556, 556, 556, 557, - 558, 558, 558, 558, 558, 558, 559, 560, 561, 562, 563, 564, 564, 564, 565, 566, - 561, 26, 564, 567, 568, 569, 568, 568, 568, 568, 568, 569, 570, 26, 26, 26, - 571, 571, 571, 571, 571, 26, 572, 572, 572, 572, 572, 572, 573, 26, 178, 178, - 574, 574, 574, 574, 574, 574, 574, 575, 53, 576, 26, 26, 577, 577, 577, 577, - 578, 26, 577, 578, 579, 580, 579, 579, 579, 579, 581, 579, 582, 26, 579, 579, - 579, 583, 584, 584, 584, 584, 585, 584, 584, 586, 587, 26, 588, 589, 590, 590, - 590, 590, 588, 591, 590, 26, 590, 592, 593, 594, 595, 595, 595, 596, 597, 598, - 595, 599, 26, 26, 600, 600, 600, 601, 602, 602, 603, 602, 602, 602, 602, 604, - 602, 602, 602, 605, 26, 26, 606, 26, 108, 108, 108, 108, 108, 108, 607, 608, - 609, 609, 609, 609, 609, 609, 609, 610, 609, 611, 612, 26, 613, 26, 26, 26, - 26, 26, 614, 614, 614, 614, 614, 614, 614, 614, 615, 26, 616, 616, 616, 616, - 616, 616, 617, 26, 616, 616, 616, 618, 619, 619, 619, 619, 620, 26, 26, 26, - 621, 621, 621, 621, 621, 621, 621, 622, 305, 305, 305, 623, 624, 624, 624, 625, - 624, 626, 627, 627, 627, 627, 627, 627, 627, 627, 627, 628, 627, 629, 630, 630, - 630, 631, 631, 26, 632, 632, 632, 632, 633, 26, 632, 634, 634, 632, 632, 635, - 632, 632, 26, 26, 636, 636, 636, 636, 636, 636, 636, 637, 638, 638, 638, 638, - 638, 638, 638, 639, 640, 640, 640, 640, 640, 641, 640, 640, 640, 642, 640, 640, - 643, 26, 345, 26, 644, 644, 644, 644, 644, 644, 644, 26, 645, 645, 645, 645, - 645, 645, 646, 26, 26, 26, 26, 647, 644, 648, 26, 26, 26, 26, 649, 650, - 651, 286, 286, 286, 652, 26, 653, 26, 26, 26, 654, 26, 655, 26, 656, 656, - 656, 656, 656, 656, 656, 656, 656, 657, 658, 658, 658, 658, 658, 659, 658, 660, - 658, 661, 658, 662, 359, 26, 26, 26, 0, 0, 0, 265, 0, 0, 359, 26, - 9, 663, 9, 9, 221, 26, 0, 0, 0, 0, 276, 26, 257, 362, 0, 0, - 664, 665, 0, 666, 667, 668, 0, 0, 0, 669, 0, 0, 246, 26, 26, 26, - 0, 0, 257, 26, 0, 0, 0, 259, 0, 0, 254, 0, 0, 0, 0, 254, - 670, 671, 0, 672, 673, 0, 0, 0, 269, 674, 254, 254, 0, 0, 0, 675, - 676, 677, 678, 0, 276, 0, 0, 0, 0, 268, 0, 0, 679, 679, 679, 679, - 679, 680, 26, 681, 682, 679, 26, 26, 2, 2, 2, 346, 683, 419, 26, 26, - 684, 270, 270, 685, 686, 687, 18, 18, 18, 688, 26, 26, 26, 689, 26, 26, - 690, 690, 690, 690, 690, 691, 690, 692, 690, 693, 26, 26, 26, 26, 694, 694, - 694, 695, 26, 26, 696, 696, 696, 696, 696, 696, 696, 697, 26, 26, 698, 698, - 698, 698, 698, 699, 26, 26, 700, 700, 700, 700, 700, 701, 172, 702, 170, 172, - 703, 703, 703, 703, 704, 703, 705, 26, 706, 706, 706, 706, 706, 707, 706, 708, - 26, 26, 362, 0, 0, 0, 376, 26, 709, 31, 31, 31, 710, 711, 712, 713, - 714, 715, 710, 716, 710, 712, 712, 717, 31, 718, 31, 719, 720, 718, 31, 719, - 26, 26, 721, 26, 0, 359, 0, 0, 0, 257, 362, 0, 362, 0, 362, 0, - 0, 276, 26, 26, 722, 0, 0, 0, 723, 26, 0, 0, 0, 0, 0, 359, - 0, 259, 265, 26, 276, 26, 26, 26, 0, 0, 0, 724, 0, 376, 0, 376, - 0, 0, 257, 725, 0, 359, 259, 26, 0, 26, 0, 265, 0, 26, 0, 0, - 0, 276, 0, 359, 265, 26, 26, 26, 0, 276, 0, 376, 0, 726, 0, 0, - 257, 722, 0, 727, 0, 265, 0, 259, 277, 277, 277, 280, 345, 26, 277, 277, - 728, 26, 277, 277, 277, 729, 277, 277, 277, 277, 26, 26, 730, 26, 26, 26, - 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962, 969, 970, 971, 976, - 1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0, 0,1080,1081,1082, - 1086,1110, 0, 0,1124,1125,1126,1127,1131,1133, 0,1147,1154,1155,1156,1161, - 1187,1188,1189,1193, 0,1219,1226,1227,1228,1229,1233, 0, 0,1267,1268,1269, - 1273,1298, 0,1303, 943,1128, 944,1129, 954,1139, 958,1143, 959,1144, 960,1145, - 961,1146, 964,1149, 0, 0, 973,1158, 974,1159, 975,1160, 983,1168, 978,1163, - 988,1173, 990,1175, 991,1176, 993,1178, 994,1179, 0, 0,1004,1190,1005,1191, - 1006,1192,1014,1199,1007, 0, 0, 0,1016,1201,1020,1206, 0,1022,1208,1025, - 1211,1023,1209, 0, 0, 0, 0,1032,1218,1037,1223,1035,1221, 0, 0, 0, - 1044,1230,1045,1231,1049,1235, 0, 0,1058,1244,1064,1250,1060,1246,1066,1252, - 1067,1253,1072,1258,1069,1255,1077,1264,1074,1261, 0, 0,1083,1270,1084,1271, - 1085,1272,1088,1275,1089,1276,1096,1283,1103,1290,1111,1299,1115,1118,1307,1120, - 1309,1121,1310, 0,1053,1239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1093,1280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 949,1134,1010,1195,1050,1236,1090,1277,1341,1368,1340,1367,1342,1369,1339, - 1366, 0,1320,1347,1418,1419,1323,1350, 0, 0, 992,1177,1018,1204,1055,1241, - 1416,1417,1415,1424,1202, 0, 0, 0, 987,1172, 0, 0,1031,1217,1321,1348, - 1322,1349,1338,1365, 950,1135, 951,1136, 979,1164, 980,1165,1011,1196,1012,1197, - 1051,1237,1052,1238,1061,1247,1062,1248,1091,1278,1092,1279,1071,1257,1076,1263, - 0, 0, 997,1182, 0, 0, 0, 0, 0, 0, 945,1130, 982,1167,1337,1364, - 1335,1362,1046,1232,1422,1423,1113,1301, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 8, 9, 0, 10,1425, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, 0,1314,1427, 5,1434,1438,1443, 0, - 1450, 0,1455,1461,1514, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1446,1458, - 1468,1476,1480,1486,1517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1489,1503, - 1494,1500,1508, 0, 0, 0, 0,1520,1521, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1526,1528, 0,1525, 0, 0, 0,1522, 0, 0, 0, 0, - 1536,1532,1539, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1534, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1556, 0, 0, - 0, 0, 0, 0,1548,1550, 0,1547, 0, 0, 0,1567, 0, 0, 0, 0, - 1558,1554,1561, 0, 0, 0, 0, 0, 0, 0,1568,1569, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1529,1551, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1523,1545,1524,1546, 0, 0,1527,1549, 0, 0,1570,1571, - 1530,1552,1531,1553, 0, 0,1533,1555,1535,1557,1537,1559, 0, 0,1572,1573, - 1544,1566,1538,1560,1540,1562,1541,1563,1542,1564, 0, 0,1543,1565, 0, 0, - 0, 0, 0, 0, 0, 0,1606,1607,1609,1608,1610, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1613, 0,1611, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,1612, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1620, 0, 0, - 0, 0, 0, 0, 0,1623, 0, 0,1624, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1614,1615,1616,1617, - 1618,1619,1621,1622, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1628, - 1629, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1625,1626, 0,1627, 0, 0, 0,1634, 0, 0,1635, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1630,1631,1632, - 0, 0,1633, 0, 0, 0, 0, 0, 0, 0, 0, 0,1639, 0, 0,1638, - 1640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1636,1637, 0, 0, 0, 0, 0, 0,1641, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1642,1644, - 1643, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1645, 0, 0, 0, - 0, 0, 0, 0,1646, 0, 0, 0, 0, 0, 0,1648,1649, 0,1647,1650, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1651,1653, - 1652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1654, 0, - 1655,1657,1656, 0, 0, 0, 0,1659, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1660, 0, 0, 0, 0,1661, 0, 0, 0, 0,1662, 0, 0, 0, 0, - 1663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1658, 0, 0, - 0, 0, 0, 0, 0, 0, 0,1664, 0,1665,1673, 0,1674, 0, 0, 0, - 0, 0, 0, 0, 0,1666, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,1668, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1669, 0, 0, 0, 0,1670, 0, 0, 0, 0,1671, 0, 0, 0, 0, - 1672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1667, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1675, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1676, 0,1677, 0,1678, 0, - 1679, 0,1680, 0, 0, 0,1681, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1682, - 0,1683, 0, 0,1684,1685, 0,1686, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 953,1138, 955,1140, 956,1141, 957,1142,1324,1351, 963,1148, - 965,1150, 968,1153, 966,1151, 967,1152,1378,1380,1379,1381, 984,1169, 985,1170, - 1420,1421, 986,1171, 989,1174, 995,1180, 998,1183, 996,1181, 999,1184,1000,1185, - 1015,1200,1329,1356,1017,1203,1019,1205,1021,1207,1024,1210,1687,1688,1027,1213, - 1026,1212,1028,1214,1029,1215,1030,1216,1034,1220,1036,1222,1039,1225,1038,1224, - 1334,1361,1336,1363,1382,1384,1383,1385,1056,1242,1057,1243,1059,1245,1063,1249, - 1689,1690,1065,1251,1068,1254,1070,1256,1386,1387,1388,1389,1691,1692,1073,1259, - 1075,1262,1079,1266,1078,1265,1095,1282,1098,1285,1097,1284,1390,1391,1392,1393, - 1099,1286,1100,1287,1101,1288,1102,1289,1105,1292,1104,1291,1106,1294,1107,1295, - 1108,1296,1114,1302,1119,1308,1122,1311,1123,1312,1186,1260,1293,1305, 0,1394, - 0, 0, 0, 0, 952,1137, 947,1132,1317,1344,1316,1343,1319,1346,1318,1345, - 1693,1695,1371,1375,1370,1374,1373,1377,1372,1376,1694,1696, 981,1166, 977,1162, - 972,1157,1326,1353,1325,1352,1328,1355,1327,1354,1697,1698,1009,1194,1013,1198, - 1054,1240,1048,1234,1331,1358,1330,1357,1333,1360,1332,1359,1699,1700,1396,1401, - 1395,1400,1398,1403,1397,1402,1399,1404,1094,1281,1087,1274,1406,1411,1405,1410, - 1408,1413,1407,1412,1409,1414,1109,1297,1117,1306,1116,1304,1112,1300, 0, 0, - 0, 0, 0, 0,1471,1472,1701,1705,1702,1706,1703,1707,1430,1431,1715,1719, - 1716,1720,1717,1721,1477,1478,1729,1731,1730,1732, 0, 0,1435,1436,1733,1735, - 1734,1736, 0, 0,1481,1482,1737,1741,1738,1742,1739,1743,1439,1440,1751,1755, - 1752,1756,1753,1757,1490,1491,1765,1768,1766,1769,1767,1770,1447,1448,1771,1774, - 1772,1775,1773,1776,1495,1496,1777,1779,1778,1780, 0, 0,1451,1452,1781,1783, - 1782,1784, 0, 0,1504,1505,1785,1788,1786,1789,1787,1790, 0,1459, 0,1791, - 0,1792, 0,1793,1509,1510,1794,1798,1795,1799,1796,1800,1462,1463,1808,1812, - 1809,1813,1810,1814,1467, 21,1475, 22,1479, 23,1485, 24,1493, 27,1499, 28, - 1507, 29, 0, 0,1704,1708,1709,1710,1711,1712,1713,1714,1718,1722,1723,1724, - 1725,1726,1727,1728,1740,1744,1745,1746,1747,1748,1749,1750,1754,1758,1759,1760, - 1761,1762,1763,1764,1797,1801,1802,1803,1804,1805,1806,1807,1811,1815,1816,1817, - 1818,1819,1820,1821,1470,1469,1822,1474,1465, 0,1473,1825,1429,1428,1426, 12, - 1432, 0, 26, 0, 0,1315,1823,1484,1466, 0,1483,1829,1433, 13,1437, 14, - 1441,1826,1827,1828,1488,1487,1513, 19, 0, 0,1492,1515,1445,1444,1442, 15, - 0,1831,1832,1833,1502,1501,1516, 25,1497,1498,1506,1518,1457,1456,1454, 17, - 1453,1313, 11, 3, 0, 0,1824,1512,1519, 0,1511,1830,1449, 16,1460, 18, - 1464, 4, 0, 0, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 2, 6, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1834,1835, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1836, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1837,1839,1838, 0, 0, 0, 0,1840, 0, 0, 0, 0,1841, 0, 0, - 1842, 0, 0, 0, 0, 0, 0, 0,1843, 0,1844, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1845, 0, 0,1846, 0, 0,1847, 0,1848, 0, 0, - 0, 0, 0, 0, 937, 0,1850, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1849, 936, 938,1851,1852, 0, 0,1853,1854, 0, 0,1855,1856, 0, 0, - 0, 0, 0, 0,1857,1858, 0, 0,1861,1862, 0, 0,1863,1864, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1867,1868,1869,1870,1859,1860,1865,1866, 0, 0, 0, 0, 0, 0,1871,1872, - 1873,1874, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 33, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1877, 0,1878, 0,1879, 0,1880, 0,1881, 0,1882, 0,1883, 0,1884, 0, - 1885, 0,1886, 0,1887, 0,1888, 0, 0,1889, 0,1890, 0,1891, 0, 0, - 0, 0, 0, 0,1892,1893, 0,1894,1895, 0,1896,1897, 0,1898,1899, 0, - 1900,1901, 0, 0, 0, 0, 0, 0,1876, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1902, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1904, 0,1905, 0,1906, 0,1907, 0,1908, 0,1909, 0,1910, 0,1911, 0, - 1912, 0,1913, 0,1914, 0,1915, 0, 0,1916, 0,1917, 0,1918, 0, 0, - 0, 0, 0, 0,1919,1920, 0,1921,1922, 0,1923,1924, 0,1925,1926, 0, - 1927,1928, 0, 0, 0, 0, 0, 0,1903, 0, 0,1929,1930,1931,1932, 0, - 0, 0,1933, 0, 710, 385, 724, 715, 455, 103, 186, 825, 825, 242, 751, 205, - 241, 336, 524, 601, 663, 676, 688, 738, 411, 434, 474, 500, 649, 746, 799, 108, - 180, 416, 482, 662, 810, 275, 462, 658, 692, 344, 618, 679, 293, 388, 440, 492, - 740, 116, 146, 168, 368, 414, 481, 527, 606, 660, 665, 722, 781, 803, 809, 538, - 553, 588, 642, 758, 811, 701, 233, 299, 573, 612, 487, 540, 714, 779, 232, 267, - 412, 445, 457, 585, 594, 766, 167, 613, 149, 148, 560, 589, 648, 768, 708, 345, - 411, 704, 105, 259, 313, 496, 518, 174, 542, 120, 307, 101, 430, 372, 584, 183, - 228, 529, 650, 697, 424, 732, 428, 349, 632, 355, 517, 110, 135, 147, 403, 580, - 624, 700, 750, 170, 193, 245, 297, 374, 463, 543, 763, 801, 812, 815, 162, 384, - 420, 730, 287, 330, 337, 366, 459, 476, 509, 558, 591, 610, 726, 652, 734, 759, - 154, 163, 198, 473, 683, 697, 292, 311, 353, 423, 572, 494, 113, 217, 259, 280, - 314, 499, 506, 603, 608, 752, 778, 782, 788, 117, 557, 748, 774, 320, 109, 126, - 260, 265, 373, 411, 479, 523, 655, 737, 823, 380, 765, 161, 395, 398, 438, 451, - 502, 516, 537, 583, 791, 136, 340, 769, 122, 273, 446, 727, 305, 322, 400, 496, - 771, 155, 190, 269, 377, 391, 406, 432, 501, 519, 599, 684, 687, 749, 776, 175, - 452, 191, 480, 510, 659, 772, 805, 813, 397, 444, 619, 566, 568, 575, 491, 471, - 707, 111, 636, 156, 153, 288, 346, 578, 256, 435, 383, 729, 680, 767, 694, 295, - 128, 210, 0, 0, 227, 0, 379, 0, 0, 150, 493, 525, 544, 551, 552, 556, - 783, 576, 604, 0, 661, 0, 703, 0, 0, 735, 743, 0, 0, 0, 793, 794, - 795, 808, 741, 773, 118, 127, 130, 166, 169, 177, 207, 213, 215, 226, 229, 268, - 270, 317, 327, 329, 335, 369, 375, 381, 404, 441, 448, 458, 477, 484, 503, 539, - 545, 547, 546, 548, 549, 550, 554, 555, 561, 564, 569, 591, 593, 595, 598, 607, - 620, 625, 625, 651, 690, 695, 705, 706, 716, 717, 733, 735, 777, 786, 790, 315, - 869, 623, 0, 0, 102, 145, 134, 115, 129, 138, 165, 171, 207, 202, 206, 212, - 227, 231, 240, 243, 250, 254, 294, 296, 303, 308, 319, 325, 321, 329, 326, 335, - 341, 357, 360, 362, 370, 379, 388, 389, 393, 421, 424, 438, 456, 454, 458, 465, - 477, 535, 485, 490, 493, 507, 512, 514, 521, 522, 525, 526, 528, 533, 532, 541, - 565, 569, 574, 586, 591, 597, 607, 637, 647, 674, 691, 693, 695, 698, 703, 699, - 705, 704, 702, 706, 709, 717, 728, 736, 747, 754, 770, 777, 783, 784, 786, 787, - 790, 802, 825, 848, 847, 857, 55, 65, 66, 883, 892, 916, 822, 824, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1586, 0,1605, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1602,1603, - 1934,1935,1574,1575,1576,1577,1579,1580,1581,1583,1584, 0,1585,1587,1588,1589, - 1591, 0,1592, 0,1593,1594, 0,1595,1596, 0,1598,1599,1600,1601,1604,1582, - 1578,1590,1597, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1936, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1937, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1938, 0, - 1939, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1940, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1941,1942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1943, - 1944, 0, 0, 0, 0, 0, 0,1945, 0,1946, 0, 0, 0, 0, 0, 0, - 0, 0,1947, 0, 0,1948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1950, 0,1949,1951, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1953, - 1952, 0,1954, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1955,1956, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1957, 0, 0, 0, - 0, 0, 0, 0, 0,1958,1961,1959,1965,1960,1962,1964,1963, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1967,1966,1968, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1969,1970,1971,1972,1973,1974,1975, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1976, - 1977,1978,1980,1979,1981, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 106, 104, 107, 826, 114, 118, 119, 121, 123, 124, 127, 125, - 34, 830, 130, 131, 132, 137, 827, 35, 133, 139, 829, 142, 143, 112, 144, 145, - 924, 151, 152, 37, 157, 158, 159, 160, 38, 165, 166, 169, 171, 172, 173, 174, - 176, 177, 178, 179, 181, 182, 182, 182, 833, 468, 184, 185, 834, 187, 188, 189, - 196, 192, 194, 195, 197, 199, 200, 201, 203, 204, 204, 206, 208, 209, 211, 218, - 213, 219, 214, 216, 153, 234, 221, 222, 223, 220, 225, 224, 230, 835, 235, 236, - 237, 238, 239, 244, 836, 837, 247, 248, 249, 246, 251, 39, 40, 253, 255, 255, - 838, 257, 258, 259, 261, 839, 262, 263, 301, 264, 41, 266, 270, 272, 271, 841, - 274, 842, 277, 276, 278, 281, 282, 42, 283, 284, 285, 286, 43, 843, 44, 289, - 290, 291, 293, 934, 298, 845, 845, 621, 300, 300, 45, 852, 894, 302, 304, 46, - 306, 309, 310, 312, 316, 48, 47, 317, 846, 318, 323, 324, 325, 324, 328, 329, - 333, 331, 332, 334, 335, 336, 338, 339, 342, 343, 347, 351, 849, 350, 348, 352, - 354, 359, 850, 361, 358, 356, 49, 363, 365, 367, 364, 50, 369, 371, 851, 376, - 386, 378, 53, 381, 52, 51, 140, 141, 387, 382, 614, 78, 388, 389, 390, 394, - 392, 856, 54, 399, 396, 402, 404, 858, 405, 401, 407, 55, 408, 409, 410, 413, - 859, 415, 56, 417, 860, 418, 57, 419, 422, 424, 425, 861, 840, 862, 426, 863, - 429, 431, 427, 433, 437, 441, 438, 439, 442, 443, 864, 436, 449, 450, 58, 454, - 453, 865, 447, 460, 866, 867, 461, 466, 465, 464, 59, 467, 470, 469, 472, 828, - 475, 868, 478, 870, 483, 485, 486, 871, 488, 489, 872, 873, 495, 497, 60, 498, - 61, 61, 504, 505, 507, 508, 511, 62, 513, 874, 515, 875, 518, 844, 520, 876, - 877, 878, 63, 64, 528, 880, 879, 881, 882, 530, 531, 531, 533, 66, 534, 67, - 68, 884, 536, 538, 541, 69, 885, 549, 886, 887, 556, 559, 70, 561, 562, 563, - 888, 889, 889, 567, 71, 890, 570, 571, 72, 891, 577, 73, 581, 579, 582, 893, - 587, 74, 590, 592, 596, 75, 895, 896, 76, 897, 600, 898, 602, 605, 607, 899, - 900, 609, 901, 611, 853, 77, 615, 616, 79, 617, 252, 902, 903, 854, 855, 621, - 622, 731, 80, 627, 626, 628, 164, 629, 630, 631, 633, 904, 632, 634, 639, 640, - 635, 641, 646, 651, 638, 643, 644, 645, 905, 907, 906, 81, 653, 654, 656, 911, - 657, 908, 82, 83, 909, 910, 84, 664, 665, 666, 667, 669, 668, 671, 670, 674, - 672, 673, 675, 85, 677, 678, 86, 681, 682, 912, 685, 686, 87, 689, 36, 913, - 914, 88, 89, 696, 702, 709, 711, 915, 712, 713, 718, 719, 917, 831, 721, 720, - 723, 832, 725, 728, 918, 919, 739, 742, 744, 920, 745, 753, 756, 757, 755, 760, - 761, 921, 762, 90, 764, 922, 91, 775, 279, 780, 923, 925, 92, 93, 785, 926, - 94, 927, 787, 787, 789, 928, 792, 95, 796, 797, 798, 800, 96, 929, 802, 804, - 806, 97, 98, 807, 930, 99, 931, 932, 933, 814, 100, 816, 817, 818, 819, 820, - 821, 935, 0, 0, -}; -static const int16_t -_hb_ucd_i16[92] = -{ - 0, 0, 1, -1, 2, 0, -2, 0, 0, 2, 0, -2, 0, 16, 0, -16, - 0, 1, -1, 0, 3, 3, 3, -3, -3, -3, 0, 2016, 0, 2527, 1923, 1914, - 1918, 0, 2250, 0, 0, 138, 0, 7, -7, 0, -1, 1, 1824, 0, 2104, 0, - 2108, 2106, 0, 2106, 1316, 0, -1, -138, 8, 8, 8, 0, 7, 7, -8, -8, - -8, -7,-1316, 1, -1, 3, -3, 1, 0,-1914,-1918, 0, 0,-1923,-1824, 0, - 0,-2016,-2104, 0, 0,-2106,-2108,-2106,-2250, 0,-2527, 0, -}; - -static inline uint_fast8_t -_hb_ucd_gc (unsigned u) -{ - return u<1114110u?_hb_ucd_u8[6472+(((_hb_ucd_u8[816+(((_hb_ucd_u16[((_hb_ucd_u8[272+(((_hb_ucd_u8[u>>1>>3>>4>>4])<<4)+((u>>1>>3>>4)&15u))])<<4)+((u>>1>>3)&15u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; -} -static inline uint_fast8_t -_hb_ucd_ccc (unsigned u) -{ - return u<125259u?_hb_ucd_u8[8504+(((_hb_ucd_u8[7936+(((_hb_ucd_u8[7460+(((_hb_ucd_u8[7100+(((_hb_ucd_u8[6854+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; -} -static inline unsigned -_hb_ucd_b4 (const uint8_t* a, unsigned i) -{ - return (a[i>>1]>>((i&1u)<<2))&15u; -} -static inline int_fast16_t -_hb_ucd_bmg (unsigned u) -{ - return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9396+(((_hb_ucd_u8[9164+(((_hb_ucd_u8[9068+(((_hb_ucd_b4(9004+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0; -} -static inline uint_fast8_t -_hb_ucd_sc (unsigned u) -{ - return u<918000u?_hb_ucd_u8[10398+(((_hb_ucd_u16[3952+(((_hb_ucd_u16[2624+(((_hb_ucd_u8[9870+(((_hb_ucd_u8[9644+(u>>3>>2>>3>>4)])<<4)+((u>>3>>2>>3)&15u))])<<3)+((u>>3>>2)&7u))])<<2)+((u>>3)&3u))])<<3)+((u)&7u))]:2; -} -static inline uint_fast16_t -_hb_ucd_dm (unsigned u) -{ - return u<195102u?_hb_ucd_u16[6244+(((_hb_ucd_u8[16628+(((_hb_ucd_u8[16246+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; -} - - -#else - -static const uint8_t -_hb_ucd_u8[13730] = -{ - 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 9, 10, 7, 7, 7, 7, 7, 11, 12, 12, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 7, 21, 22, 22, 22, 23, 24, 7, 7, - 7, 25, 22, 22, 22, 26, 27, 28, 22, 29, 30, 31, 32, 33, 34, 35, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 21, 22, 36, - 7, 7, 7, 7, 37, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 38, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 34, 34, 34, 35, 36, 37, 34, 34, 34, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 62, 63, 64, 65, 66, 67, 68, 69, 67, 70, 71, - 67, 67, 62, 72, 62, 62, 73, 67, 74, 75, 76, 77, 78, 67, 67, 67, - 79, 80, 34, 81, 82, 83, 67, 67, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 84, 34, 34, 34, 34, - 85, 34, 34, 34, 34, 34, 34, 34, 34, 86, 34, 34, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 34, 34, 34, 34, 34, 34, 34, 34, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, - 100,100, 34, 34, 34, 34,101,102, 34, 34,103,104,105,106,107,108, - 34, 34,109,110,111,112,113,114,115,116,117,118, 34, 34, 34,119, - 120,121,122,123,124,125,126,127, 34,128,129,130,131,132,133,134, - 135,136,137,138,139,140,141,142,143,144,111,145,146,147,148,111, - 149,150,151,152,153,154,155,156,157,158,159,160,111,161,162,163, - 34, 34, 34, 34, 34, 34, 34, 34,164, 34, 34,111,111,111,111,111, - 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,165, - 34, 34, 34, 34, 34, 34, 34, 34,166, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111, - 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, - 111,111,167,111,111,111,111,111,111,111,111,111,111,111,111,111, - 34, 34, 34, 34,168,169,170, 34,111,111,171,111,172,173,174,175, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111, - 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,119, - 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111, - 111,111,111,111,111,111,111,111, 34,176,111,111,111,111,111,111, - 111,111,111,111,111,111,111,111, 67,177, 67, 67, 67, 67,178, 67, - 67, 67,179,180,181,131, 65,111,182,183,184,185,186,187,188,189, - 67, 67, 67, 67,190,191,111,111,111,111,111,111,111,111,192,111, - 193,194,195,111,111,196,111,111,111,197,111,198,111,111,111, 34, - 34,199,200,111,111,111,111,111,131,201,202,111, 34,203,111,111, - 67, 67,204, 67, 67,111, 67,205, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67,177,111,111,111,111,111,111,111,111, - 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111,111, - 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111, - 206,111,194,194,111,111,111,111,111,111,111,111,111,111,111,111, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2, - 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 17, 18, 19, 1, 20, 20, 21, 22, 23, 24, 25, - 26, 27, 15, 2, 28, 29, 27, 30, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 31, 11, 11, 11, 32, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 33, 16, 16, 16, 16, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 34, 34, 34, 34, 34, 34, 34, 34, 16, 32, 32, 32, - 32, 32, 32, 32, 11, 34, 34, 16, 34, 32, 32, 11, 34, 11, 16, 11, - 11, 34, 32, 11, 32, 16, 11, 34, 32, 32, 32, 11, 34, 16, 32, 11, - 34, 11, 34, 34, 32, 35, 32, 16, 36, 36, 37, 34, 38, 37, 34, 34, - 34, 34, 34, 34, 34, 34, 16, 32, 34, 38, 32, 11, 32, 32, 32, 32, - 32, 32, 16, 16, 16, 11, 34, 32, 34, 34, 11, 32, 32, 32, 32, 32, - 16, 16, 39, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 41, 41, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, - 40, 40, 42, 41, 41, 41, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, - 43, 43, 43, 43, 43, 43, 43, 43, 32, 32, 42, 32, 16, 44, 16, 10, - 41, 41, 41, 45, 11, 11, 11, 11, 34, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34, - 16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 46, 34, 32, 34, 11, - 32, 47, 43, 43, 48, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16, - 11, 11, 11, 11, 49, 2, 2, 2, 16, 16, 16, 16, 50, 51, 52, 53, - 54, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 55, - 56, 57, 43, 56, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 58, 2, 2, 2, 2, 2, 2, 59, 59, 59, 8, 9, 60, 2, 61, - 43, 43, 43, 43, 43, 57, 62, 2, 63, 36, 36, 36, 36, 64, 43, 43, - 7, 7, 7, 7, 7, 2, 2, 36, 65, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 66, 43, 43, 43, 67, 47, 43, 43, 68, 69, 70, 43, 43, 36, - 7, 7, 7, 7, 7, 36, 71, 72, 2, 2, 2, 2, 2, 2, 2, 73, - 64, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 65, 36, - 36, 36, 36, 43, 43, 43, 43, 43, 7, 7, 7, 7, 7, 36, 36, 36, - 36, 36, 36, 36, 36, 64, 43, 43, 43, 43, 40, 21, 2, 40, 69, 20, - 36, 36, 36, 43, 43, 69, 43, 43, 43, 43, 69, 43, 69, 43, 43, 43, - 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 36, 36, 64, 43, 43, 2, - 36, 36, 36, 36, 74, 36, 36, 36, 59, 59, 59, 75, 43, 43, 43, 43, - 36, 36, 36, 36, 76, 43, 43, 43, 43, 75, 43, 43, 43, 43, 43, 43, - 43, 77, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 77, 65, 78, - 79, 43, 43, 43, 77, 78, 79, 78, 64, 43, 43, 43, 36, 36, 36, 36, - 36, 43, 2, 7, 7, 7, 7, 7, 80, 36, 36, 36, 36, 36, 36, 36, - 64, 78, 81, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 65, 78, - 79, 43, 43, 77, 78, 78, 79, 36, 36, 36, 36, 82, 78, 78, 36, 36, - 36, 43, 43, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 53, 58, 43, - 43, 77, 81, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 78, - 79, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 65, 36, 36, 36, - 36, 36, 36, 7, 7, 7, 7, 7, 43, 36, 64, 2, 2, 2, 2, 2, - 79, 43, 43, 43, 77, 78, 79, 43, 60, 20, 20, 20, 83, 43, 43, 43, - 43, 78, 81, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 65, 79, - 79, 43, 43, 77, 78, 78, 79, 43, 43, 43, 43, 77, 78, 78, 36, 36, - 72, 27, 27, 27, 27, 27, 27, 27, 43, 65, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 78, 77, 78, 78, 78, 78, 78, 79, 43, - 36, 36, 36, 82, 78, 78, 78, 78, 78, 78, 78, 7, 7, 7, 7, 7, - 27, 84, 61, 61, 53, 61, 61, 61, 77, 78, 65, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 65, 43, 77, 78, 78, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 36, 36, 36, 36, 7, 7, 7, 85, 27, 27, 27, 84, - 64, 78, 66, 36, 36, 36, 36, 36, 78, 78, 78, 77, 78, 78, 43, 43, - 43, 43, 77, 78, 78, 78, 81, 36, 86, 82, 78, 78, 78, 78, 78, 78, - 43, 78, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 64, 65, 78, - 79, 43, 43, 78, 78, 78, 79, 71, 61, 61, 36, 82, 27, 27, 27, 87, - 27, 27, 27, 27, 84, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 77, - 78, 43, 43, 43, 78, 78, 78, 78, 7, 78, 2, 2, 2, 2, 2, 2, - 64, 36, 43, 43, 43, 43, 43, 88, 36, 36, 36, 69, 43, 43, 43, 57, - 7, 7, 7, 7, 7, 2, 2, 2, 64, 36, 43, 43, 43, 43, 65, 36, - 36, 36, 36, 40, 43, 43, 43, 43, 7, 7, 7, 7, 7, 7, 36, 36, - 71, 61, 2, 2, 2, 2, 2, 2, 2, 89, 89, 61, 43, 61, 61, 61, - 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 47, 47, 47, 4, 4, 78, - 64, 43, 43, 43, 43, 43, 43, 77, 43, 43, 57, 43, 36, 36, 64, 43, - 43, 43, 43, 43, 43, 43, 43, 61, 61, 61, 61, 70, 61, 61, 61, 61, - 2, 2, 89, 61, 21, 2, 2, 2, 36, 36, 36, 36, 36, 82, 79, 43, - 77, 43, 43, 43, 79, 77, 79, 65, 36, 36, 36, 78, 43, 36, 36, 43, - 65, 78, 81, 82, 78, 78, 78, 36, 64, 43, 65, 36, 36, 36, 36, 36, - 36, 77, 79, 77, 78, 78, 79, 82, 7, 7, 7, 7, 7, 78, 79, 61, - 16, 16, 16, 16, 16, 50, 44, 16, 36, 36, 36, 36, 36, 36, 64, 43, - 2, 2, 2, 2, 90, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 61, 61, 61, 61, 61, 61, 61, 61, 11, 11, 11, 11, 16, 16, 16, 16, - 91, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 71, 66, - 92, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 93, 94, 94, - 36, 36, 36, 36, 36, 58, 2, 95, 96, 36, 36, 36, 36, 36, 36, 36, - 36, 43, 77, 78, 78, 78, 78, 81, 36, 43, 97, 2, 2, 2, 2, 2, - 36, 43, 43, 43, 43, 43, 43, 43, 36, 36, 43, 79, 43, 43, 43, 78, - 78, 78, 78, 77, 79, 43, 43, 43, 43, 43, 2, 80, 2, 60, 64, 43, - 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 98, 2, 56, 43, 75, - 36, 76, 36, 36, 36, 36, 36, 36, 36, 36, 64, 65, 36, 36, 36, 36, - 36, 36, 36, 36, 64, 36, 36, 36, 43, 77, 78, 79, 77, 78, 78, 78, - 78, 77, 78, 78, 79, 43, 43, 43, 61, 61, 2, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 27, 27, 61, 36, 36, 36, 64, 77, 79, 43, 2, - 36, 36, 82, 77, 43, 43, 43, 43, 77, 77, 79, 43, 43, 43, 77, 78, - 78, 79, 43, 43, 43, 43, 43, 43, 2, 2, 2, 80, 2, 2, 2, 2, - 43, 43, 43, 43, 43, 43, 43, 99, 43, 43, 81, 36, 36, 36, 36, 36, - 36, 36, 77, 43, 43, 77, 77, 78, 78, 77, 81, 36, 36, 36, 36, 2, - 89, 61, 61, 61, 61, 47, 43, 43, 43, 43, 61, 61, 61, 61, 21, 2, - 43, 81, 36, 36, 36, 36, 36, 36, 82, 43, 43, 78, 43, 79, 43, 36, - 36, 36, 36, 77, 43, 78, 79, 79, 43, 78, 78, 78, 78, 78, 2, 2, - 36, 36, 78, 78, 78, 78, 43, 43, 43, 43, 78, 43, 43, 57, 2, 2, - 7, 7, 7, 7, 7, 7, 86, 36, 36, 36, 36, 36, 40, 40, 40, 2, - 16, 16, 16, 16, 34, 16, 16, 16, 43, 57, 43, 43, 43, 43, 43, 43, - 77, 43, 43, 43, 65, 36, 64, 36, 36, 36, 65, 82, 43, 36, 36, 36, - 16, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 44, 16, 16, - 16, 16, 16, 16, 44, 16, 16, 16, 16, 16, 16, 16, 16,100, 40, 40, - 32, 32, 32, 16, 16, 16, 16, 32, 16, 16, 16, 16, 11, 11, 11, 11, - 16, 16, 16, 16, 34, 11, 11, 11, 16, 16, 16, 16,101,101,101,101, - 16, 16, 16, 16, 11, 11,102,103, 41, 16, 16, 16, 11, 11,102, 41, - 16, 16, 16, 16, 11, 11,104, 41,105,105,105,105,105,106, 59, 59, - 51, 51, 51, 2,107,108,107,108, 2, 2, 2, 2,109, 59, 59,110, - 2, 2, 2, 2,111,112, 2,113,114, 2,115,116, 2, 2, 2, 2, - 2, 9,114, 2, 2, 2, 2,117, 59, 59, 59, 59, 59, 59, 59, 59, - 118, 40, 27, 27, 27, 8,115,119, 27, 27, 27, 27, 27, 8,115, 94, - 20, 20, 20, 20, 20, 20, 20, 20, 43, 43, 43, 43, 43, 43,120, 48, - 99, 48, 99, 43, 43, 43, 43, 43, 61,121, 61,122, 61, 34, 11, 16, - 11, 32,122, 61, 46, 11, 11, 61, 61, 61,121,121,121, 11, 11,123, - 11, 11, 35, 36, 39, 61, 16, 11, 8, 8, 46, 16, 16, 26, 61,124, - 95, 95, 95, 95, 95, 95, 95, 95, 95,125,126, 95,127, 61, 61, 61, - 8, 8,128, 61, 61, 8, 61, 61,128, 26, 61,128, 61, 61, 61,128, - 61, 61, 61, 61, 61, 61, 61, 8, 61,128,128, 61, 61, 61, 61, 61, - 61, 61, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 61, 61, 61, 61, 4, 4, 61, 61, 8, 61, 61, 61,129,130, 61, 61, - 61, 61, 61, 61, 61, 61,128, 61, 61, 61, 61, 61, 61, 26, 8, 8, - 8, 8, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 8, 8, - 8, 61, 61, 61, 61, 61, 61, 61, 27, 27, 27, 27, 27, 27, 61, 61, - 61, 61, 61, 61, 61, 27, 27, 27, 61, 61, 61, 26, 61, 61, 61, 61, - 26, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 8, 8, 8, 8, - 61, 61, 61, 61, 61, 61, 61, 26, 61, 61, 61, 61, 4, 4, 4, 4, - 4, 4, 4, 27, 27, 27, 27, 27, 27, 27, 61, 61, 61, 61, 61, 61, - 8, 8,115,131, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, - 8,115,132,132,132,132,132,132,132,132,132,132,131, 8, 8, 8, - 8, 8, 8, 8, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, - 8, 8,128, 26, 8, 8,128, 61, 32, 11, 32, 34, 34, 34, 34, 11, - 32, 32, 34, 16, 16, 16, 40, 11, 32, 32,124, 61, 61,122, 34,133, - 43, 32, 16, 16, 50, 2, 90, 2, 36, 36, 36, 36, 36, 36, 36, 76, - 2, 2, 2, 2, 2, 2, 2, 56, 2,107,107, 2,111,112,107, 2, - 2, 2, 2, 6, 2, 98,107, 2,107, 4, 4, 4, 4, 2, 2, 80, - 2, 2, 2, 2, 2, 51, 2, 2, 98,134, 2, 2, 2, 2, 2, 2, - 61, 2,135,132,132,132,136, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 1, 2,137,138, 4, 4, 4, 4, 4, 61, 4, 4, 4, 4,139, 94, - 140, 95, 95, 95, 95, 43, 43, 78,141, 40, 40, 61, 95,142, 58, 61, - 72, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 64,143,144, 63, - 36, 36, 36, 36, 36, 58, 40, 63, 61, 27, 27, 61, 61, 61, 61, 61, - 27, 27, 27, 27, 27, 61, 61, 61, 61, 61, 61, 61, 27, 27, 27, 27, - 145, 27, 27, 27, 27, 27, 27, 27, 36, 36, 76, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36,146, 2, 32, 32, 32, 32, 32, 32, 32, 64, - 48,147, 43, 43, 43, 43, 43, 80, 32, 32, 32, 32, 32, 32, 40, 43, - 36, 36, 36, 95, 95, 95, 95, 95, 43, 2, 2, 2, 2, 2, 2, 2, - 41, 41, 41,144, 40, 40, 40, 40, 41, 32, 32, 32, 32, 32, 32, 32, - 16, 32, 32, 32, 32, 32, 32, 32, 44, 16, 16, 16, 34, 34, 34, 32, - 32, 32, 32, 32, 42,148, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 11, 11, 32, 11, 11, 32, 32, 32, 32, 32, 32, - 32, 32, 11, 11, 34, 34, 32, 16, 32, 16, 16, 32, 32, 32, 11, 11, - 11, 40,149, 35, 40, 35, 36, 36, 36, 65, 36, 65, 36, 64, 36, 36, - 36, 82, 79, 77, 61, 61, 43, 43, 27, 27, 27, 61,150, 61, 61, 61, - 36, 36, 2, 2, 2, 2, 2, 2, 78, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 78, 78, 78, 78, 78, 78, 78, 78, 43, 43, 43, 43, 43, 2, - 43, 36, 36, 36, 2, 66, 66, 64, 36, 36, 36, 43, 43, 43, 43, 2, - 36, 36, 36, 64, 43, 43, 43, 43, 43, 78, 78, 78, 78, 78, 78, 97, - 36, 64, 78, 43, 43, 78, 43, 78, 97, 2, 2, 2, 2, 2, 2, 80, - 7, 7, 7, 7, 7, 7, 7, 2, 36, 36, 64, 63, 36, 36, 36, 36, - 36, 36, 36, 36, 64, 43, 43, 77, 79, 77, 79, 43, 43, 43, 43, 43, - 36, 64, 36, 36, 36, 36, 77, 78, 7, 7, 7, 7, 7, 7, 2, 2, - 63, 36, 36, 71, 61, 82, 77, 36, 65, 43, 65, 64, 65, 36, 36, 43, - 36, 36, 36, 36, 36, 36, 76, 2, 36, 36, 36, 36, 36, 82, 43, 78, - 2, 76,151, 43, 43, 43, 43, 43, 16, 16, 16, 16, 16,103, 40, 40, - 16, 16, 16, 16,100, 41, 41, 41, 36, 82, 79, 78, 77, 97, 79, 43, - 152,152,152,152,152,152,152,152,153,153,153,153,153,153,153,153, - 16, 16, 16, 16, 16, 16, 35, 65, 36, 36, 36, 36,154, 36, 36, 36, - 36, 41, 41, 41, 41, 41, 41, 41, 41, 74, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36,132, 36, 36, 36, 36, 36, 36, 36, 71, - 36, 36, 36, 36, 36, 36,150, 61, 2, 2, 2,135,116, 2, 2, 2, - 6,155,156,132,132,132,132,132,132,132,116,135,116, 2,113,157, - 2, 2, 2, 2,139,132,132,116, 2,158, 8, 8, 60, 2, 2, 2, - 36, 36, 36, 36, 36, 36, 36,159, 2, 2, 3, 2, 4, 5, 6, 2, - 16, 16, 16, 16, 16, 17, 18,115,116, 4, 2, 36, 36, 36, 36, 36, - 63, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 40, - 20,160, 53, 20, 26, 8,128, 61, 61, 61, 61, 61,161, 59, 61, 61, - 2, 2, 2, 90, 27, 27, 27, 27, 27, 27, 27, 84, 61, 61, 61, 61, - 95, 95,127, 27, 84, 61, 61, 61, 61, 61, 61, 61, 61, 27, 61, 61, - 61, 61, 61, 61, 61, 61, 47, 43,162,162,162,162,162,162,162,162, - 163, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 87, 36, - 138, 36, 36, 36, 36, 95, 95, 95, 36, 36, 36, 36, 36, 36, 36, 58, - 164, 95, 95, 95, 95, 95, 95, 95, 11, 11, 11, 32, 16, 16, 16, 16, - 36, 36, 36, 58, 27, 27, 27, 27, 36, 36, 36, 71,145, 27, 27, 27, - 36, 36, 36,165, 27, 27, 27, 27, 36, 36, 36, 36, 36,165, 27, 27, - 36, 36, 36, 27, 27, 27, 27, 30, 36, 36, 36, 36, 36, 36, 27, 36, - 64, 43, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 43, 43, 43, 43, - 36, 36, 36, 36, 36, 36,165, 30, 36, 36, 36, 36, 36, 36,165, 27, - 36, 36, 36, 36, 72, 36, 36, 36, 36, 36, 64, 43, 43,163, 27, 27, - 36, 36, 36, 36, 58, 2, 2, 2, 36, 36, 36, 36, 27, 27, 27, 27, - 16, 16, 16, 16, 16, 27, 27, 27, 36, 36, 43, 43, 43, 43, 43, 43, - 7, 7, 7, 7, 7, 36, 36, 63, 11, 11, 11, 11,166, 43, 43,141, - 16, 16, 16, 16, 16, 16, 16, 8, 36, 36, 36, 36, 36, 64,167, 51, - 36, 36, 36, 36, 36, 36, 43, 43, 27, 27, 27, 87, 36, 36, 36, 36, - 163, 27, 30, 2, 2, 2, 2, 2, 36, 43, 43, 2, 2, 2, 2, 2, - 36, 36,165, 27, 27, 27, 27, 27, 79, 81, 36, 36, 36, 36, 36, 36, - 43, 43, 43, 57, 2, 2, 2, 2, 2, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 7, 7, 7, 7, 7, 65, 64, 65, 36, 36, 36, 36, 64, - 78, 79, 43, 77, 79, 57, 73, 2, 2, 43, 43, 43, 43, 43, 67, 59, - 36, 36, 36, 64, 43, 43, 79, 43, 43, 43, 43, 7, 7, 7, 7, 7, - 2, 2, 82, 81, 36, 36, 36, 36, 36, 64, 2, 36, 36, 36, 36, 36, - 36, 82, 78, 43, 43, 43, 43, 77, 81, 36, 58, 2, 56, 43, 57, 79, - 7, 7, 7, 7, 7, 58, 58, 2, 90, 27, 27, 27, 27, 27, 27, 27, - 36, 36, 36, 36, 36, 36, 78, 79, 43, 78, 77, 43, 2, 2, 2, 65, - 36, 36, 36, 36, 36, 36, 36, 64, 77, 78, 78, 78, 78, 78, 78, 78, - 36, 36, 36, 82, 78, 78, 81, 36, 36, 78, 78, 43, 43, 43, 43, 43, - 36, 36, 36, 36, 78, 79, 43, 43, 43, 78, 78, 78, 78, 78, 78, 77, - 65, 65, 2, 2, 2, 2, 2, 2, 56, 43, 43, 43, 43, 43, 43, 43, - 36, 36, 82, 78, 43, 43, 43, 43, 78, 43, 77, 65, 36, 58, 2, 2, - 7, 7, 7, 7, 7, 2, 2, 65, 78, 79, 43, 43, 77, 77, 78, 79, - 77, 43, 36, 66, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 82, - 78, 43, 43, 43, 78, 78, 43, 79, 57, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 36, 36, 43, 43, 78, 79, 43, 43, 43, 77, 79, 79, - 57, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 64, 79, 78, - 43, 43, 43, 79, 58, 2, 2, 2, 36, 36, 36, 36, 36, 36, 64, 79, - 78, 43, 43, 79, 43, 43, 43, 43, 7, 7, 7, 7, 7, 27, 2, 89, - 43, 43, 43, 43, 79, 57, 2, 2, 27, 27, 27, 27, 27, 27, 27, 87, - 78, 78, 78, 78, 78, 79, 77, 65, 81, 79, 2, 2, 2, 2, 2, 2, - 82, 78, 43, 43, 43, 43, 78, 78, 65, 66, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 64, 43, 43, 43, 43, 65, 36, 36, - 36, 64, 43, 43, 77, 64, 43, 57, 2, 2, 2, 56, 43, 43, 43, 43, - 64, 43, 43, 77, 79, 43, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, - 43, 43, 43, 77, 43, 2, 66, 2, 58, 2, 2, 2, 2, 2, 2, 2, - 43, 43, 43, 43, 43, 43, 43, 79, 2, 36, 36, 36, 36, 36, 36, 36, - 43, 43, 43, 43, 77, 43, 43, 43, 77, 43, 79, 43, 43, 43, 43, 43, - 43, 43, 43, 64, 43, 43, 43, 43, 36, 36, 36, 36, 36, 78, 78, 78, - 43, 77, 79, 79, 36, 36, 36, 36, 36, 64, 77, 97, 2, 2, 2, 2, - 43, 82, 36, 36, 36, 36, 36, 36, 36, 36, 78, 43, 43, 43, 43, 78, - 77, 57, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 43, 43, 43, - 27, 27, 84, 61, 61, 61, 53, 20,150, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 21, 65, 36, 36, 64, 43, 43, 43, 43, - 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 78, 79, 43, - 43, 43, 57, 2, 2, 2, 2, 2, 43, 43, 43, 57, 2, 2, 61, 61, - 40, 40, 89, 61, 61, 61, 61, 61, 7, 7, 7, 7, 7,168, 27, 27, - 27, 87, 36, 36, 36, 36, 36, 36, 40, 63, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 76,146, 2, 27, 27, 27, 30, 2, 2, 2, 2, - 82, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 79, - 43, 68, 40, 40, 40, 40, 40, 40, 40, 80, 43, 43, 43, 43, 43, 43, - 36, 36, 36, 36, 36, 36, 47, 57, 61, 61,169, 79, 43, 61,169, 78, - 78,170, 59, 59, 59, 75, 43, 43, 43, 70, 47, 43, 43, 43, 61, 61, - 61, 61, 61, 61, 61, 43, 43, 61, 61, 43, 70, 61, 61, 61, 61, 61, - 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 16, 11, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, - 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, - 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, - 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, - 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 32, 16, 7, - 43, 43, 43, 70, 61, 47, 43, 43, 43, 43, 43, 43, 43, 43, 70, 61, - 61, 61, 47, 61, 61, 61, 61, 61, 61, 61, 70, 21, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 56, 43, 43, 16, 16, 16, 16, 16, 39, 16, 16, - 43, 43, 43, 68, 40, 40, 40, 40, 7, 7, 7, 7, 7, 7, 7, 71, - 7, 7, 7, 7, 7, 7, 7,171, 36, 36, 36, 36, 36, 76, 43, 43, - 172, 7, 7, 7, 7, 7, 7, 85, 16, 16, 43, 43, 43, 68, 40, 40, - 27, 27, 27, 27, 27, 27,145, 27,173, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27,145, 27, 27, 27, 27, 27, 27, 84, 61, - 61, 61, 61, 61, 61, 25, 41, 41, 0, 0, 29, 21, 21, 21, 23, 21, - 22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21, 9, 9, 9, - 9, 22, 21, 18, 24, 16, 24, 5, 5, 5, 5, 22, 25, 18, 25, 0, - 23, 23, 26, 21, 24, 26, 7, 20, 25, 1, 26, 24, 26, 25, 15, 15, - 24, 15, 7, 19, 15, 21, 9, 25, 9, 5, 5, 25, 5, 9, 5, 7, - 7, 7, 9, 8, 8, 5, 7, 5, 6, 6, 24, 24, 6, 24, 12, 12, - 6, 5, 9, 21, 25, 9, 26, 12, 11, 11, 9, 6, 5, 21, 17, 17, - 17, 26, 26, 23, 23, 12, 17, 12, 21, 12, 12, 21, 7, 21, 1, 1, - 21, 23, 26, 26, 1, 21, 6, 7, 7, 12, 12, 7, 21, 7, 12, 1, - 12, 6, 6, 12, 12, 26, 7, 26, 26, 7, 21, 1, 24, 7, 1, 12, - 7, 6, 12, 10, 10, 10, 10, 12, 21, 6, 10, 7, 7, 10, 23, 7, - 15, 26, 13, 21, 13, 7, 15, 7, 12, 23, 21, 26, 21, 15, 17, 7, - 29, 7, 7, 22, 18, 18, 14, 14, 14, 7, 10, 21, 17, 21, 11, 12, - 5, 6, 8, 8, 8, 24, 5, 24, 9, 24, 29, 29, 29, 1, 20, 19, - 22, 20, 27, 28, 1, 29, 21, 20, 19, 21, 21, 16, 16, 21, 25, 22, - 18, 21, 21, 29, 15, 6, 18, 6, 12, 11, 9, 26, 26, 9, 26, 5, - 5, 26, 14, 9, 5, 14, 14, 15, 25, 26, 26, 22, 18, 26, 18, 25, - 18, 22, 5, 12, 22, 21, 21, 22, 18, 17, 26, 6, 7, 14, 17, 22, - 26, 14, 17, 6, 14, 6, 12, 24, 24, 6, 26, 15, 6, 21, 11, 21, - 24, 9, 6, 9, 23, 26, 6, 10, 4, 4, 3, 3, 7, 25, 17, 16, - 16, 22, 16, 16, 25, 17, 7, 1, 25, 24, 26, 1, 2, 2, 12, 15, - 21, 14, 7, 15, 9, 12, 12, 17, 13, 15, 26, 10, 10, 1, 13, 23, - 7, 13, 23, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, - 11, 12, 13, 0, 14, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 20, 0, 21, 22, 23, 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 35, 0, 0, 0, 0, 36, 0, 37, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 40, 0, 0, - 0, 0, 0, 0, 41, 42, 43, 0, 44, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 3, 0, 0, 0, - 4, 5, 6, 7, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, 16, 17, - 16, 18, 16, 19, 16, 19, 16, 19, 0, 19, 16, 20, 16, 19, 21, 19, - 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 32, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 34, 0, - 0, 35, 0, 0, 36, 0, 37, 0, 0, 0, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 49, 0, 0, - 0, 0, 0, 0, 0, 50, 0, 51, 0, 52, 53, 0, 54, 0, 0, 0, - 0, 0, 0, 55, 56, 57, 0, 0, 0, 0, 58, 0, 0, 59, 60, 61, - 62, 63, 0, 0, 64, 65, 0, 0, 0, 66, 0, 0, 0, 0, 67, 0, - 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 69, 0, 0, 0, 70, 0, 71, 0, 0, 72, 0, 0, 73, 0, 0, - 0, 0, 0, 0, 0, 0, 74, 75, 0, 0, 0, 0, 76, 77, 0, 78, - 79, 0, 0, 80, 81, 0, 82, 62, 0, 83, 84, 0, 0, 85, 86, 87, - 0, 88, 0, 89, 0, 90, 0, 0, 51, 91, 51, 0, 92, 0, 93, 0, - 0, 0, 81, 0, 0, 0, 94, 95, 0, 96, 97, 98, 99, 0, 0, 0, - 0, 0, 51, 0, 0, 0, 0,100,101, 0, 0, 0, 0, 0, 0,102, - 0, 0, 0, 0, 0, 0,103, 0, 0, 0, 0, 0, 0,104,105, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,106, 0, 0,107, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,108,109, 0, 0,110, 0, 0, 0, 0, - 0, 0,111, 0,112, 0,105, 0, 0, 0, 0, 0,113,114, 0, 0, - 0, 0, 0, 0, 0,115, 0, 0, 0,116, 0, 0, 0,117, 0,118, - 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, 8, 0, - 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, 0, 13, 0, 0, 14, 15, - 0, 16, 0, 17, 18, 0, 0, 19, 0, 20, 21, 0, 0, 0, 0, 0, - 22, 23, 0, 24, 25, 0, 0, 26, 0, 0, 0, 27, 0, 0, 28, 29, - 30, 31, 0, 0, 0, 32, 33, 34, 0, 0, 33, 0, 0, 35, 33, 0, - 0, 0, 33, 36, 0, 0, 0, 0, 0, 37, 38, 0, 0, 0, 0, 0, - 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, 43, - 0, 44, 0, 0, 0, 45, 46, 0, 0, 0, 47, 0, 0, 0, 0, 0, - 0, 48, 49, 0, 0, 0, 0, 50, 0, 0, 0, 51, 0, 52, 0, 53, - 0, 0, 0, 0, 54, 0, 0, 0, 0, 55, 0, 56, 0, 0, 0, 0, - 57, 58, 0, 0, 0, 59, 60, 0, 0, 0, 0, 0, 0, 61, 52, 0, - 62, 63, 0, 0, 64, 0, 0, 0, 65, 66, 0, 0, 0, 67, 0, 68, - 69, 70, 71, 72, 1, 73, 0, 74, 75, 76, 0, 0, 77, 78, 0, 0, - 0, 79, 0, 0, 1, 1, 0, 0, 80, 0, 0, 81, 0, 0, 0, 0, - 77, 82, 0, 83, 0, 0, 0, 0, 0, 78, 84, 0, 85, 0, 52, 0, - 1, 78, 0, 0, 86, 0, 0, 87, 0, 0, 0, 0, 0, 88, 57, 0, - 0, 0, 0, 0, 0, 89, 90, 0, 0, 84, 0, 0, 33, 0, 0, 91, - 0, 0, 0, 0, 92, 0, 0, 0, 0, 49, 0, 0, 93, 0, 0, 0, - 0, 94, 95, 0, 0, 96, 0, 0, 97, 0, 0, 0, 98, 0, 0, 0, - 99, 0, 0, 0,100, 0, 0, 0, 0,101,102, 93, 0, 0,103, 0, - 0, 0, 84, 0, 0,104, 0, 0, 0,105,106, 0, 0,107,108, 0, - 0, 0, 0, 0, 0,109, 0, 0,110, 0, 0, 0, 0,111, 33, 0, - 112,113,114, 57, 0, 0,115, 35, 0, 0,116, 0, 0, 0,117, 0, - 0, 0, 0, 0, 0,118, 0, 0,119, 0, 0, 0, 0,120, 88, 0, - 0, 0, 0, 0, 57, 0, 0, 0, 0, 52,121, 0, 0, 0, 0,122, - 0, 0,123, 0, 0, 0, 0,121, 0, 0,124, 0, 0, 0, 0, 0, - 79, 0, 0, 0, 0,125, 0, 0, 0,126, 0, 0, 0,127, 0,128, - 0, 0, 0, 0,129,130,131, 0,132, 0,133, 0, 0, 0,134,135, - 136, 0, 77, 0, 0, 0, 0, 0, 35, 0, 0, 0,137, 0, 0, 0, - 138, 0, 0, 0,139, 0, 0,140, 0, 0,141, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 4, 4, 8, - 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, 18, 1, 1, 1, 19, 1, - 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, 25, 26, 27, 28, 29, 30, - 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, 34, 35, 1, 36, 37, 0, - 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, 42, 0, 0, 0, 43, 36, - 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, 21, 0, 0, 47, 0, 38, - 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, 0, 19, 52, 1, 0, 0, - 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, 54, 21, 35, 1, 0, 0, - 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, 0, 0, 0, 59, 0, 60, - 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, 0, 0, 64, 0, 0, 0, - 65, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 69, - 70, 0, 71, 72, 73, 74, 75, 76, 0, 0, 0, 77, 0, 0, 0, 78, - 79, 0, 0, 0, 0, 47, 0, 0, 0, 49, 0, 80, 0, 0, 0, 62, - 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, 0, 0, 83, 0, 0, 19, - 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, 1, 52, 15, 86, 36, 10, - 21, 87, 0, 55, 0, 0, 0, 0, 19, 10, 1, 0, 0, 0, 0, 0, - 88, 0, 0, 89, 0, 0, 88, 0, 0, 0, 0, 78, 0, 0, 87, 9, - 12, 4, 90, 8, 91, 47, 0, 58, 50, 0, 21, 1, 21, 92, 93, 1, - 1, 1, 1, 94, 95, 96, 97, 1, 98, 58, 81, 99,100, 4, 58, 0, - 0, 0, 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, 0, 61, 0, 0, - 101,102, 0, 0,103, 0, 0, 1, 1, 50, 0, 0, 0, 38, 0, 63, - 0, 0, 0, 0, 0, 62, 0, 0,104, 68, 61, 0, 0, 0, 78, 0, - 0, 0,105,106, 58, 38, 81, 0, 0, 0, 0, 0, 0,107, 1, 14, - 4, 12, 84, 0, 0, 0, 0, 38, 87, 0, 0, 0, 0,108, 0, 0, - 109, 61, 0,110, 0, 0, 0, 1, 0, 0, 0, 0, 49, 50, 0, 0, - 19, 58, 0, 0, 0, 51, 0,111, 14, 52,112, 41, 0, 0, 62, 0, - 0, 61, 0, 0,113, 0, 87, 0, 0, 0, 61, 62, 0, 0, 62, 0, - 89, 0, 0,113, 0, 0, 0, 0,114, 0, 0, 0, 78, 55, 0, 38, - 1, 58, 1, 58, 0, 0, 0, 0, 0, 88, 63, 89, 0, 0,115, 0, - 0, 0, 55, 0, 0, 0, 0,115, 0, 0, 0, 0, 61, 0, 0, 0, - 0, 79, 0, 61, 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, 79, 0, - 0, 0, 8, 91, 0, 0, 1, 87, 0, 0,116, 0, 0, 0, 0, 0, - 0,117, 0,118,119,120,121, 0,104, 4,122, 49, 23, 0, 0, 0, - 38, 50, 38, 58, 0, 0, 1, 87, 1, 1, 1, 1, 39, 1, 48,105, - 87, 0, 0, 0, 0, 1, 0, 0, 0,123, 0, 0, 0,112, 4,122, - 0, 0, 0, 1,124, 0, 0, 0, 0, 0,230,230,230,230,230,232, - 220,220,220,220,232,216,220,220,220,220,220,202,202,220,220,220, - 220,202,202,220,220,220, 1, 1, 1, 1, 1,220,220,220,220,230, - 230,230,230,240,230,220,220,220,230,230,230,220,220, 0,230,230, - 230,220,220,220,220,230,232,220,220,230,233,234,234,233,234,234, - 233,230, 0, 0, 0,230, 0,220,230,230,230,230,220,230,230,230, - 222,220,230,230,220,220,230,222,228,230, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, 25, 0,230,220, - 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, 28, 29, 30, 31, 32, 33, - 34,230,230,220,220,230,220,230,230,220, 35, 0, 0, 0, 0, 0, - 230,230,230, 0, 0,230,230, 0,220,230,230,220, 0, 0, 0, 36, - 0, 0,230,220,230,230,220,220,230,220,220,230,220,230,220,230, - 230, 0, 0,220, 0, 0,230,230, 0,230, 0,230,230,230,230,230, - 0, 0, 0,220,220,220,230,220,220,220,230,230, 0,220, 27, 28, - 29,230, 7, 0, 0, 0, 0, 9, 0, 0, 0,230,220,230,230, 0, - 0, 0, 0, 0,230, 0, 0, 84, 91, 0, 0, 0, 0, 9, 9, 0, - 0, 0, 0, 0, 9, 0,103,103, 9, 0,107,107,107,107,118,118, - 9, 0,122,122,122,122,220,220, 0, 0, 0,220, 0,220, 0,216, - 0, 0, 0,129,130, 0,132, 0, 0, 0, 0, 0,130,130,130,130, - 0, 0,130, 0,230,230, 9, 0,230,230, 0, 0,220, 0, 0, 0, - 0, 7, 0, 9, 9, 0, 9, 9, 0, 0, 0,230, 0, 0, 0,228, - 0, 0, 0,222,230,220,220, 0, 0, 0,230, 0, 0,220,230,220, - 0,220,230,230,230, 0, 0, 0, 9, 9, 0, 0, 7, 0,230, 0, - 1, 1, 1, 0, 0, 0,230,234,214,220,202,230,230,230,230,230, - 232,228,228,220,218,230,233,220,230,220,230,230, 1, 1, 1, 1, - 1,230, 0, 1, 1,230,220,230, 1, 1, 0, 0,218,228,232,222, - 224,224, 0, 8, 8, 0, 0, 0, 0,220,230, 0,230,230,220, 0, - 0,230, 0, 0, 26, 0, 0,220, 0,230,230, 1,220, 0, 0,230, - 220, 0, 0, 0,220,220, 0, 0,230,220, 0, 9, 7, 0, 0, 7, - 9, 0, 0, 0, 9, 7, 6, 6, 0, 0, 0, 0, 1, 0, 0,216, - 216, 1, 1, 1, 0, 0, 0,226,216,216,216,216,216, 0,220,220, - 220, 0,232,232,220,230,230,230, 7, 0, 16, 17, 17, 33, 17, 49, - 17, 17, 84, 97,135,145, 26, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17,177, 0, 1, 2, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, - 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 6, 7, 8, 3, 3, 3, - 3, 3, 9, 10, 11, 12, 13, 3, 3, 3, 3, 3, 3, 3, 3, 14, - 3, 15, 3, 3, 3, 3, 3, 3, 16, 17, 18, 19, 20, 21, 3, 3, - 3, 22, 23, 24, 3, 3, 3, 3, 3, 3, 25, 3, 3, 3, 3, 3, - 3, 3, 3, 26, 3, 3, 27, 28, 0, 1, 0, 0, 0, 0, 0, 1, - 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, - 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 6, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 8, 9, 0, 0, 0, 0, 0, 0, 9, 0, 9, 0, 0, 0, 0, - 0, 0, 0, 10, 11, 12, 13, 0, 0, 14, 15, 16, 6, 0, 17, 18, - 19, 19, 19, 20, 21, 22, 23, 24, 19, 25, 0, 26, 27, 19, 19, 28, - 29, 30, 0, 31, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 19, - 28, 0, 32, 33, 9, 34, 35, 19, 0, 0, 36, 37, 38, 39, 40, 19, - 0, 41, 42, 43, 44, 31, 0, 1, 45, 42, 0, 0, 0, 0, 0, 32, - 14, 14, 0, 0, 0, 0, 14, 0, 0, 46, 47, 47, 47, 47, 48, 49, - 47, 47, 47, 47, 50, 51, 52, 53, 43, 21, 0, 0, 0, 0, 0, 0, - 0, 54, 6, 55, 0, 14, 19, 1, 0, 0, 0, 0, 56, 57, 0, 0, - 0, 0, 0, 19, 58, 31, 0, 0, 0, 0, 0, 0, 0, 59, 14, 0, - 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, 61, 0, - 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 3, 0, 4, - 5, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 1, 1, 0, 0, 8, - 9, 0, 8, 9, 0, 0, 0, 0, 8, 9, 10, 11, 12, 0, 0, 0, - 13, 0, 0, 0, 0, 14, 15, 16, 17, 0, 0, 0, 1, 0, 0, 18, - 19, 0, 0, 0, 20, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, - 1, 1, 1, 1, 0, 8, 21, 9, 0, 0, 22, 0, 0, 0, 0, 1, - 0, 23, 24, 25, 0, 0, 26, 0, 0, 0, 8, 21, 27, 0, 1, 0, - 0, 1, 1, 1, 1, 0, 1, 28, 29, 30, 0, 31, 32, 20, 1, 1, - 0, 0, 0, 8, 21, 9, 1, 4, 5, 0, 0, 0, 33, 9, 0, 1, - 1, 1, 0, 8, 21, 21, 21, 21, 34, 1, 35, 21, 21, 21, 9, 36, - 0, 0, 37, 38, 1, 0, 39, 0, 0, 0, 1, 0, 1, 0, 0, 0, - 0, 8, 21, 9, 1, 0, 0, 0, 40, 0, 8, 21, 21, 21, 21, 21, - 21, 21, 21, 9, 0, 1, 1, 1, 1, 8, 21, 21, 21, 9, 0, 0, - 0, 41, 0, 42, 43, 0, 0, 0, 1, 44, 0, 0, 0, 45, 8, 9, - 1, 0, 0, 0, 8, 21, 21, 21, 9, 0, 1, 0, 1, 1, 8, 21, - 21, 9, 0, 4, 5, 8, 9, 1, 0, 0, 0, 1, 2, 3, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 3, 3, 3, 3, 3, 3, - 3, 15, 3, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 0, 0, 1, 2, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 17, 17, - 18, 17, 19, 20, 21, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 24, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 25, 25, 26, 27, - 28, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 52, 53, 31, - 31, 31, 31, 54, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 56, 57, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 58, 31, 31, 31, - 59, 60, 61, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 63, 64, 65, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 66, 67, 68, 31, 31, 31, 31, 69, 31, 31, 31, 31, 31, - 31, 31, 17, 70, 71, 72, 17, 17, 73, 74, 31, 75, 76, 77, 78, 79, - 80, 31, 81, 82, 17, 83, 17, 17, 17, 17, 31, 31, 23, 23, 23, 23, - 23, 23, 23, 84, 31, 31, 31, 31, 23, 84, 31, 31, 23, 23, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 85, 0, 0, 1, - 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, - 4, 4, 4, 4, 4, 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 11, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 19, 27, - 28, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, - 37, 37, 38, 38, 39, 40, 41, 41, 42, 42, 42, 43, 44, 44, 45, 46, - 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, 49, 50, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 51, - 60, 61, 62, 63, 64, 65, 66, 7, 67, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 7, 4, 4, 4, 4, 77, 77, 77, 77, 78, 79, 80, 81, - 82, 83, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 85, 85, - 0, 0, 0, 0, 86, 87, 88, 88, 89, 90, 48, 91, 0, 0, 92, 92, - 92, 92, 92, 93, 94, 95, 96, 97, 98, 47, 99,100,101,102, 0,103, - 104,105, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 0,106,106,106,106,106,106,106,106,106,106,106,107, - 108,108,108,108,108, 11,109,110,111, 4,112, 4,113,114,115,116, - 117,118,119,120,121,122,123,124,125,126, 50,127, 47, 47, 47, 47, - 47, 47, 47, 47,128,128,128,128,128,128,128,128,128,128,128,128, - 92, 92, 92, 92, 92, 92, 92, 92,129,130, 19, 19, 19, 19, 19, 19, - 131, 19, 19, 19,132,133, 19,134,135,136,137,101,138,138,138,138, - 0, 77,139,140,128,128,141,142,143,144,145,146,147,148,149,150, - 151,152,153,154,155,155,155,155,155,155, 4, 4,156,157,158,159, - 160,161,162,163,164,165,166,167,168,169,170,170,171,171,172,172, - 173,174,174,174, 19, 19,175,176,177,178,179,180,181,181,182,183, - 184,185,186,187,188,188,189,190,191,192,193,193,194,194,195,195, - 128,128,196,196,197,198,199,200,201,201,128,128,202,202,203,203, - 204,204,205,205,206,207,208,209, 28, 28,210,210,211,212,213,213, - 214,215,216,216,128,128,217,217,218,218,219, 34,220,220,220,220, - 220,220,220,220,220,220,220,220,220,220,128,128,128,128,128,128, - 128,128,221,221,222,222,222,222,222,222,222,222,223,223,223,223, - 223,223,223,223,223,223,128,128,128,128,128,128,128,128,128,128, - 224,224,128,128,110,110,110,110,110,110,110,110,110,225,226,227, - 228,228,228,228,128,128,128,128,229,229,128,128,230,230,230,230, - 231,231,231,232,233,233,233,233,233,233,233,233,233,233,233,233, - 234,234,234,234,234,234,234,234,233,233,128,128,128,128,128,128, - 128,128,104,104,235,236,236,236,237,238,239,239,239,239,239,239, - 128,128,128,128,240,240,241, 0,128,128,128,128, 0, 0, 0, 0, - 7,242, 0, 0, 0, 0, 0, 0, 0,243,244, 0, 77, 77, 0, 0, - 0, 0,128,128,245,245,245,245,245,245,245,245,245,245,245,245, - 128,128,128,128,128,128,128,128, 4, 4,128,128,246, 11, 11, 11, - 247,247,128,128,128,128,248,249,128,128,128,128,128,128,250,250, - 128,128,251,251,128,128,128,128,128,128, 48, 48,252,252,252,252, - 253,253,128,128, 0, 0, 0, 0, 0, 0,128,128, 19, 19, 19, 19, - 128,128,128,128,254, 0,128,128, 0, 0, 0, 0, 92, 92,128,128, - 128,128,128,128, 0, 0,128,128, 7, 7, 7, 7, 0, 0, 0, 0, - 1, 2, 1, 2, 0, 0, 3, 3, 4, 5, 4, 5, 4, 4, 4, 4, - 4, 4, 4, 6, 0, 0, 7, 0, 8, 8, 8, 8, 8, 8, 8, 9, - 10, 11, 11, 11, 11, 11, 12, 11, 13, 13, 13, 13, 14, 13, 13, 13, - 13, 13, 13, 15, 16, 16, 16, 16, 16, 17, 18, 18, 18, 18, 18, 18, - 19, 20, 21, 21, 22, 23, 21, 24, 21, 21, 21, 21, 21, 25, 21, 21, - 26, 26, 26, 26, 26, 21, 21, 21, 27, 27, 27, 27, 28, 28, 28, 28, - 29, 29, 29, 29, 30, 30, 26, 21, 21, 21, 31, 21, 32, 32, 32, 32, - 32, 33, 34, 32, 35, 35, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37, - 38, 38, 38, 38, 39, 39, 39, 39, 40, 40, 40, 40, 41, 41, 41, 41, - 42, 42, 42, 42, 43, 43, 43, 43, 44, 44, 44, 45, 44, 44, 44, 44, - 46, 46, 46, 46, 47, 47, 47, 47, 47, 48, 47, 47, 49, 49, 49, 49, - 49, 49, 50, 50, 50, 50, 50, 51, 52, 52, 52, 52, 53, 53, 53, 53, - 53, 53, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 56, 56, 57, 57, - 57, 57, 58, 57, 59, 59, 60, 61, 62, 62, 63, 63, 64, 64, 64, 64, - 65, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 55, 67, 67, 67, 67, - 67, 68, 68, 68, 69, 69, 69, 69, 69, 69, 64, 64, 70, 70, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 8, 72, 72, 72, 72, 73, 73, 73, 73, - 74, 74, 74, 74, 75, 75, 75, 75, 75, 76, 76, 76, 13, 50, 50, 50, - 73, 77, 78, 79, 4, 4, 80, 4, 4, 81, 82, 83, 4, 4, 4, 84, - 11, 11, 11, 11, 85, 0, 0, 0, 0, 0, 0, 86, 0, 4, 0, 0, - 0, 8, 8, 8, 0, 0, 87, 88, 89, 0, 4, 4, 6, 0, 0, 0, - 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 4, 4, 92, 92, 92, 92, - 50, 50, 50, 93, 93, 93, 93, 93, 53, 53, 13, 13, 94, 94, 94, 94, - 94, 94, 94, 0, 95, 0, 96, 97, 98, 99, 99, 99, 99,100,101,102, - 102,102,102,103,104,104,104,105, 52, 0,104,104, 0, 0, 0,102, - 52, 52, 0, 0, 0, 0, 52,106, 0,102,102,107,102,102,102,102, - 102,108, 0, 0,109,109,109,109,109,110,110,110,111,111,111,111, - 13, 13,112,112,112,112,112,112, 0, 0,113, 4,114, 4, 4, 4, - 115,115,115, 0,116,116,116,116,117,117,117,117,117,117, 32, 32, - 118,118,119,120,120,120, 52, 52,121,121,121,121,122,121, 49, 49, - 123,123,123,123,123,123, 49, 49,124,124,124,124,124,124,125,125, - 53, 53, 53, 4, 4,126,127, 54,125,125,125,125,128,128,128,128, - 4,129, 18, 18, 18, 21, 21, 21, 21, 21, 21,130, 8, 0,131, 0, - 0, 0, 0, 21, 21, 21, 21,132, 0, 0, 1, 2, 1, 2,133,101, - 102,134, 52, 52,135,135,135,135, 11, 0, 11, 11, 11, 0, 0,136, - 137,137,138,138,138,138,139, 0,140,140,140,141,141,142,142,142, - 143,143,144,144,144,144,144,144,145,145,145,145,145,146,146,146, - 147,147,147,148,148,148,148,148,149,149,149,150,150,150,150,151, - 151,151,151,151,152,152,152,152,153,153,153,153,154,154,154,154, - 155,155,156,156,157,157,157,157,157,157,158,158,159,159,160,160, - 160,160,160,160,161,161,162,162,162,162,162,162,163,163,163,163, - 163,163,164,164,165,165,165,165,166,166,166,166,167,167,167,167, - 168,168,169,169,170,170,170,170,171,171,171,171,172,172,172,172, - 173,173,173,173,174,174,174,174,175,175,175,175,176, 21, 21, 21, - 177,177,177,178,178,178,178,179,179,179,179,180,180,180,181,181, - 182,182,182,182,183,183,183,183,183,184,184,184,185,185,185,185, - 185,186,186,186,187,187,187,187,187,187,188, 43,189,189,189,189, - 190,190,190,191,191,191,191,191,192,192,192,193,192,192,192,192, - 194,194,194,194,195,195,195,195,196,196,196,196,197,197,197,197, - 198,198,198,198,198,198, 66, 66,199,199,199,199,199, 49, 49, 49, - 200,200,200,200,201,201,201,201,202,202,202,202,203,203,203,203, - 204,204,204,204,205,205,205,205,205,206,206,206,206,206,206, 55, - 207,207,207,207,208,208,208,208,209,209,209,209,209,209,209,210, - 210,210,210,210,211,211,211,211,211,211,212,212,212,212,212,212, - 213,213,213,213,214,214,214,214,110,110,110,110,215,215,215,215, - 216,216,216,216,217,217,217,217,218,218,218,218,219,219,219,219, - 220,220,220,221,221,221,221,221,221,222,222,222,223,223,223,223, - 224,224,224,224,225,225,225,225,226,226,226,226,226,226,227, 94, - 228,228,228,228,229,229,229,229,230, 99, 99, 99, 99, 99, 99, 99, - 99, 99,102,231, 99,232,102,233,233,233,233,233,234,234,234,234, - 234,234, 0, 0, 8, 0, 0, 0, 0, 0,235,236,237, 0,238, 0, - 239,239,239,239, 91, 91, 91, 13,240,240,240,240,241,241,241,241, - 242,242,242,242,243,243,243,243,244,244,244,244,245,245,245,245, - 246,246,246,246,247, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, - 2, 2, 3, 0, 0, 0, 4, 0, 2, 2, 2, 2, 2, 3, 2, 2, - 2, 2, 5, 0, 2, 5, 6, 0, 7, 7, 7, 7, 8, 9, 8, 10, - 8, 11, 8, 8, 8, 8, 8, 8, 12, 13, 13, 13, 14, 14, 14, 14, - 14, 15, 14, 14, 16, 17, 17, 17, 17, 17, 17, 17, 18, 19, 19, 19, - 19, 19, 19, 19, 20, 21, 20, 22, 20, 20, 23, 23, 20, 20, 20, 20, - 22, 20, 24, 7, 7, 25, 20, 20, 26, 20, 20, 20, 20, 20, 20, 21, - 27, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, - 31, 31, 31, 31, 32, 20, 20, 20, 33, 33, 33, 33, 34, 35, 33, 33, - 33, 36, 33, 33, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39, - 40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43, - 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, 46, 47, - 48, 48, 48, 48, 49, 49, 49, 49, 49, 50, 51, 49, 52, 52, 52, 52, - 53, 53, 53, 53, 53, 53, 54, 53, 55, 55, 55, 55, 56, 56, 56, 56, - 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59, 60, 60, 60, 60, - 60, 60, 61, 62, 63, 63, 63, 63, 64, 64, 64, 64, 64, 65, 0, 0, - 66, 66, 66, 66, 67, 67, 67, 67, 68, 68, 68, 68, 69, 70, 71, 71, - 71, 71, 71, 71, 72, 72, 72, 72, 73, 73, 73, 73, 74, 74, 74, 74, - 75, 75, 75, 75, 76, 76, 76, 76, 77, 77, 77, 77, 78, 78, 78, 78, - 79, 79, 79, 79, 80, 80, 80, 80, 81, 81, 81, 81, 82, 7, 7, 7, - 83, 7, 84, 85, 0, 84, 86, 0, 2, 87, 88, 2, 2, 2, 2, 89, - 90, 87, 91, 2, 2, 2, 92, 2, 2, 2, 2, 93, 0, 0, 0, 86, - 1, 0, 0, 94, 0, 95, 96, 0, 4, 0, 0, 0, 0, 0, 0, 4, - 97, 97, 97, 97, 98, 98, 98, 98, 13, 13, 13, 13, 99, 99, 99, 99, - 100,100,100,100, 0,101, 0, 0,102,100,103,104, 0, 0,100, 0, - 105,106,106,106,106,106,106,106,106,106,107,105,108,109,109,109, - 109,109,109,109,109,109,110,108,111,111,111,111,112, 55, 55, 55, - 55, 55, 55,113,109,109,109,110,109,109, 0, 0,114,114,114,114, - 115,115,115,115,116,116,116,116,117,117,117,117, 96, 2, 2, 2, - 2, 2, 94, 2,118,118,118,118,119,119,119,119,120,120,120,120, - 121,121,121,121,121,121,121,122,123,123,123,123,124,124,124,124, - 124,124,124,125,126,126,126,126,127,127,127,127,128,128,128,128, - 2, 2, 3, 2, 2,129,130, 0,131,131,131,131,132, 17, 17, 18, - 20, 20, 20,133, 7, 7, 7,134, 20, 20, 20, 23, 0,135,109,109, - 109,109,109,136,137,137,137,137, 0, 0, 0,138,139,139,139,139, - 140,140,140,140, 84, 0, 0, 0,141,141,141,141,142,142,142,142, - 143,143,143,143,144,144,144,144,145,145,145,145,146,146,146,146, - 147,147,147,147,148,148,148,148,149,149,149,149,150,150,150,150, - 151,151,151,151,152,152,152,152,153,153,153,153,154,154,154,154, - 155,155,155,155,156,156,156,156,157,157,157,157,158,158,158,158, - 159,159,159,159,160,160,160,160,161,161,161,161,162,162,162,162, - 163,163,163,163,164,164,164,164,165,165,165,165,166,166,166,166, - 167,167,167,167,168,168,168,168,169,169,169,169,170,170,170,170, - 171,171,171,171,172,172,172,172,173,173,173,173,174,174,174,174, - 175,175,175,175,176,176,176,176,177, 20, 20, 20,178,178,178,178, - 179,179,179,179,180,180,180,180,181,181,181,181,182,182,182,182, - 183,183,183,183,184,184,184,184,185,185,185,185,186,186,186,186, - 187,187,187,187,188,188,188,188,189, 45, 45, 45,190,190,190,190, - 191,191,191,191,192,192,192,192,193,193,193,193,193,193,194,193, - 195,195,195,195,196,196,196,196,197,197,197,197,198,198,198,198, - 199,199,199,199,200,200,200,200,201,201,201,201,202,202,202,202, - 203,203,203,203,204,204,204,204,205,205,205,205,206,206,206,206, - 207,207,207,207,208,208,208,208,209,209,209,209,210,210,210,210, - 211,211,211,211,212,212,212,212,213,213,213,213,214,214,214,214, - 215,215,215,215,216,216,216,216,217,217,217,217,218,218,218,218, - 219,219,219,219,220,220,220,220,221,221,221,221,222,222,222,222, - 223,223,223,223,224,224,224,224,225,225,225,225,226,226,226,226, - 227,227,227,227,228,229,229,229,230,230,230,230,229,229,229,229, - 231,106,106,106,232,106,106,106,106,233,109,109,234,234,234,234, - 235,235,235,235, 0,236, 86, 0, 0, 0,236, 7, 82,138, 7, 0, - 0, 0,237, 86,238,238,238,238,239,239,239,239,240,240,240,240, - 241,241,241,241,242,242,242,242,243,243,243,243,244,244,244,244, - 245,245,245,245,246, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 19, 0, 19, 0, 0, 0, - 0, 0, 26, 26, 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, 9, 9, - 9, 9, 0, 9, 9, 0, 9, 0, 9, 9, 55, 55, 55, 55, 55, 55, - 6, 6, 6, 6, 6, 1, 1, 6, 6, 4, 4, 4, 4, 4, 4, 4, - 4, 14, 14, 14, 14, 14, 14, 14, 3, 3, 3, 3, 3, 0, 3, 3, - 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 1, 1, 1, 3, 3, - 1, 3, 3, 3, 37, 37, 37, 37, 38, 38, 38, 38, 64, 64, 64, 64, - 90, 90, 90, 90, 95, 95, 95, 95, 3, 3, 0, 3, 7, 7, 7, 7, - 7, 1, 1, 1, 1, 7, 7, 7, 0, 0, 7, 7, 5, 5, 5, 5, - 11, 11, 11, 11, 10, 10, 10, 10, 21, 21, 21, 21, 22, 22, 22, 22, - 23, 23, 23, 23, 16, 16, 16, 16, 20, 20, 20, 20, 36, 36, 36, 36, - 24, 24, 24, 24, 24, 24, 24, 0, 18, 18, 18, 18, 25, 25, 25, 25, - 25, 0, 0, 0, 0, 25, 25, 25, 33, 33, 33, 33, 8, 8, 8, 8, - 8, 8, 8, 0, 12, 12, 12, 12, 30, 30, 30, 30, 29, 29, 29, 29, - 28, 28, 28, 28, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 0, - 0, 0, 35, 35, 45, 45, 45, 45, 44, 44, 44, 44, 44, 0, 0, 0, - 43, 43, 43, 43, 46, 46, 46, 46, 31, 31, 31, 31, 32, 32, 0, 0, - 32, 0, 32, 32, 32, 32, 32, 32, 48, 48, 48, 48, 52, 52, 52, 52, - 58, 58, 58, 58, 54, 54, 54, 54, 91, 91, 91, 91, 62, 62, 62, 62, - 76, 76, 76, 76, 93, 93, 93, 93, 70, 70, 70, 70, 73, 73, 73, 73, - 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, - 1, 1, 0, 0, 19, 19, 9, 9, 9, 9, 9, 6, 19, 9, 9, 9, - 9, 9, 19, 19, 9, 9, 9, 19, 6, 19, 19, 19, 19, 19, 19, 9, - 0, 0, 0, 19, 0, 0, 9, 0, 0, 0, 19, 19, 27, 27, 27, 27, - 56, 56, 56, 56, 61, 61, 61, 61, 13, 13, 13, 13, 0, 13, 0, 13, - 0, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 0, 15, 15, 15, - 15, 15, 15, 15, 15, 1, 1, 0, 0, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 0, 26, 26, 26, 26, 26, 12, 12, 12, 12, 12, 12, 0, - 39, 39, 39, 39, 86, 86, 86, 86, 77, 77, 77, 77, 79, 79, 79, 79, - 60, 60, 60, 60, 65, 65, 65, 65, 75, 75, 75, 75, 69, 69, 69, 69, - 69, 69, 0, 69, 74, 74, 74, 74, 84, 84, 84, 84, 84, 84, 84, 0, - 68, 68, 68, 68, 92, 92, 92, 92, 87, 87, 87, 87, 19, 9, 19, 19, - 19, 19, 0, 0, 2, 2, 2, 2, 19, 19, 19, 4, 3, 3, 0, 0, - 1, 1, 6, 6, 0, 0, 17, 17, 17, 17, 0, 0, 49, 49, 49, 49, - 0, 1, 1, 1, 71, 71, 71, 71, 67, 67, 67, 67, 42, 42, 42, 42, - 41, 41, 41, 41,118,118,118,118, 53, 53, 53, 53, 59, 59, 59, 59, - 40, 40, 40, 40, 51, 51, 51, 51, 50, 50, 50, 50,135,135,135,135, - 106,106,106,106,104,104,104,104,161,161,161,161,170,170,170,170, - 110,110,110,110, 47, 47, 47, 47, 81, 81, 81, 81,120,120,120,120, - 116,116,116,116,128,128,128,128, 66, 66, 66, 66, 72, 72, 72, 72, - 98, 98, 98, 98, 97, 97, 97, 97, 57, 57, 57, 57, 88, 88, 88, 88, - 117,117,117,117,112,112,112,112, 78, 78, 78, 78, 83, 83, 83, 83, - 82, 82, 82, 82,122,122,122,122, 89, 89, 89, 89,130,130,130,130, - 144,144,144,144,165,165,165,165,156,156,156,156,156,156, 3, 3, - 147,147,147,147,148,148,148,148,158,158,158,158,153,153,153,153, - 149,149,149,149, 94, 94, 94, 94, 85, 85, 85, 85,101,101,101,101, - 96, 96, 96, 96,111,111,111,111,100,100,100,100,100, 36, 36, 36, - 108,108,108,108,129,129,129,129,109,109,109,109,107,107,107,107, - 107,107,107, 1,171,171,171,171,137,137,137,137,124,124,124,124, - 123,123,123,123,114,114,114,114,102,102,102,102,126,126,126,126, - 142,142,142,142,125,125,125,125,154,154,154,154,150,150,150,150, - 141,141,141,141,140,140,140,140,121,121,121,121,169,169,169,169, - 133,133,133,133,134,134,134,134,138,138,138,138,143,143,143,143, - 145,145,145,145,163,163,163,163, 63, 63, 63, 63,157,157,157,157, - 80, 80, 80, 80,127,127,127,127,166,166,166,166,115,115,115,115, - 159,159,159,159,103,103,103,103,119,119,119,119,167,167,167,167, - 146,146,146,146, 99, 99, 99, 99,136,139, 13, 13,155,155,155,155, - 136,136,136,136, 17, 15, 15, 15, 17, 17, 15, 15, 15, 17, 17, 17, - 139,139,139,139,105,105,105,105, 0, 0, 0, 1, 0, 0, 1, 1, - 131,131,131,131,151,151,151,151,160,160,160,160,152,152,152,152, - 164,164,164,164,168,168,168,168,113,113,113,113,132,132,132,132, - 15, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, - 9, 10, 9, 11, 12, 13, 9, 9, 9, 14, 9, 9, 15, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 16, 17, 9, 9, 9, 9, 18, 9, 9, 9, 9, 9, 19, 20, 21, 9, - 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 23, 9, 9, 9, 9, 9, 24, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 25, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, - 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 23, 0, 0, 24, 25, 26, 27, 28, 29, 30, - 0, 0, 31, 32, 0, 33, 0, 34, 0, 35, 0, 0, 0, 0, 36, 37, - 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 43, 44, 0, 45, 0, 0, 0, 0, 0, 0, 46, 47, - 0, 0, 0, 0, 0, 48, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 50, 51, 0, 0, 0, 52, 0, 0, 53, 0, - 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 55, 0, - 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 57, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 58, 59, 60, 61, 62, 63, 64, 65, 0, 0, - 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 67, 68, 0, 69, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, - 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100, - 101,102,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,104, 0, 0, 0, 0, 0, 0,105,106, 0,107, 0, - 0, 0,108, 0,109, 0,110, 0,111,112,113, 0,114, 0, 0, 0, - 115, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,117, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,118,119,120,121, 0,122,123,124,125,126, - 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128,129,130,131,132,133,134,135,136,137,138,139,140,141, - 142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157, - 0, 0, 0,158,159,160,161, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,162, 0, - 163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,164,165, 0, 0, 0, - 0, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,167, 0, 0, 0,168,169, 0, 0,170, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,171, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,172, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,175, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,176,177, 0, 0, 0, 0,178,179, 0, - 0, 0,180,181,182,183,184,185,186,187,188,189,190,191,192,193, - 194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209, - 210,211,212,213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, - 3, 4, -}; -static const uint16_t -_hb_ucd_u16[5080] = -{ - 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12, - 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23, - 13, 13, 13, 24, 25, 11, 11, 11, 11, 26, 11, 27, 28, 29, 30, 31, - 32, 32, 32, 32, 32, 32, 32, 33, 34, 35, 36, 11, 37, 38, 13, 39, - 9, 9, 9, 11, 11, 11, 13, 13, 40, 13, 13, 13, 41, 13, 13, 13, - 13, 13, 13, 35, 9, 42, 11, 11, 43, 44, 32, 45, 46, 47, 47, 48, - 49, 50, 47, 47, 51, 32, 52, 53, 47, 47, 47, 47, 47, 54, 55, 56, - 57, 58, 47, 32, 59, 47, 47, 47, 47, 47, 60, 53, 61, 47, 62, 63, - 47, 64, 65, 66, 47, 67, 47, 47, 68, 69, 47, 47, 70, 32, 71, 32, - 72, 47, 47, 73, 74, 75, 76, 77, 78, 47, 47, 79, 80, 81, 82, 83, - 84, 47, 47, 85, 86, 87, 88, 89, 84, 47, 47, 79, 90, 47, 82, 91, - 92, 47, 47, 93, 94, 95, 82, 96, 97, 47, 47, 98, 99, 100, 101, 102, - 103, 47, 47, 104, 105, 106, 82, 107, 108, 47, 47, 93, 109, 110, 82, 111, - 112, 47, 47, 113, 114, 115, 82, 116, 92, 47, 47, 47, 117, 118, 101, 119, - 47, 47, 47, 120, 121, 122, 66, 66, 47, 47, 47, 123, 124, 125, 47, 47, - 126, 127, 128, 129, 47, 47, 47, 130, 131, 32, 32, 132, 133, 134, 66, 66, - 47, 47, 135, 136, 122, 137, 138, 139, 140, 141, 9, 9, 9, 11, 11, 142, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 143, 144, 145, - 47, 146, 9, 9, 9, 9, 9, 147, 148, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 149, 47, 150, 151, 47, 47, 47, 47, 152, 153, - 47, 154, 47, 155, 47, 156, 47, 156, 47, 47, 47, 157, 158, 159, 160, 145, - 161, 160, 47, 47, 162, 47, 47, 47, 163, 47, 164, 47, 47, 47, 47, 47, - 47, 47, 165, 166, 167, 47, 47, 47, 47, 47, 47, 47, 47, 168, 146, 146, - 47, 169, 47, 47, 47, 170, 171, 172, 160, 160, 173, 174, 32, 32, 32, 32, - 175, 47, 47, 176, 177, 122, 178, 179, 180, 47, 181, 61, 47, 47, 182, 183, - 47, 47, 184, 185, 186, 61, 47, 187, 188, 9, 9, 9, 66, 189, 190, 191, - 11, 11, 192, 27, 27, 27, 193, 194, 11, 195, 27, 27, 32, 32, 32, 32, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 196, 13, 13, 13, 13, 13, 13, - 197, 197, 197, 197, 197, 198, 197, 11, 199, 199, 199, 200, 201, 202, 202, 201, - 203, 204, 205, 206, 207, 208, 209, 210, 211, 27, 212, 212, 212, 213, 214, 32, - 215, 216, 217, 218, 219, 145, 220, 220, 221, 222, 223, 146, 224, 225, 146, 226, - 227, 227, 227, 227, 227, 227, 227, 227, 228, 146, 229, 146, 146, 146, 146, 230, - 146, 231, 227, 232, 146, 233, 234, 146, 146, 146, 146, 146, 146, 146, 145, 145, - 145, 235, 146, 146, 146, 146, 236, 145, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 237, 238, 146, 146, 239, 146, 146, 146, 146, 146, 146, 240, 146, - 146, 146, 146, 146, 146, 146, 241, 242, 145, 243, 146, 146, 244, 227, 245, 227, - 246, 247, 227, 227, 227, 248, 227, 249, 146, 146, 146, 227, 250, 146, 146, 146, - 9, 9, 9, 11, 11, 11, 251, 252, 13, 13, 13, 13, 13, 13, 253, 254, - 11, 11, 11, 47, 47, 47, 255, 256, 47, 47, 47, 47, 47, 47, 32, 32, - 257, 258, 259, 260, 261, 262, 263, 263, 264, 265, 266, 267, 268, 47, 47, 47, - 47, 269, 148, 47, 47, 47, 47, 270, 47, 271, 47, 47, 146, 146, 146, 47, - 146, 146, 272, 146, 273, 274, 146, 146, 272, 146, 146, 274, 146, 146, 146, 146, - 47, 47, 47, 47, 146, 146, 146, 146, 47, 275, 47, 47, 47, 47, 47, 47, - 47, 146, 146, 146, 146, 47, 47, 187, 276, 47, 61, 47, 13, 13, 277, 278, - 13, 279, 47, 47, 47, 47, 280, 281, 31, 282, 283, 284, 13, 13, 13, 285, - 286, 287, 288, 289, 290, 291, 9, 292, 293, 47, 294, 295, 47, 47, 47, 296, - 297, 47, 47, 298, 299, 160, 32, 300, 61, 47, 301, 47, 302, 303, 47, 47, - 72, 47, 47, 304, 305, 306, 307, 61, 47, 47, 308, 309, 310, 311, 47, 312, - 47, 47, 47, 313, 58, 314, 315, 316, 47, 47, 47, 11, 11, 317, 318, 11, - 11, 11, 11, 11, 47, 47, 319, 160, 320, 320, 320, 320, 320, 320, 320, 320, - 321, 321, 321, 321, 321, 321, 321, 321, 11, 322, 323, 47, 47, 47, 47, 47, - 47, 47, 47, 324, 31, 325, 47, 47, 47, 47, 47, 326, 146, 47, 47, 47, - 47, 47, 47, 47, 327, 146, 146, 328, 32, 329, 32, 330, 331, 332, 333, 47, - 47, 47, 47, 47, 47, 47, 47, 334, 335, 2, 3, 4, 5, 336, 337, 338, - 47, 339, 47, 47, 47, 47, 340, 341, 342, 145, 145, 343, 220, 220, 220, 344, - 345, 146, 146, 146, 146, 146, 146, 346, 347, 347, 347, 347, 347, 347, 347, 347, - 47, 47, 47, 47, 47, 47, 348, 145, 47, 47, 349, 47, 350, 47, 47, 60, - 47, 351, 47, 47, 47, 352, 220, 220, 9, 9, 147, 11, 11, 47, 47, 47, - 47, 47, 160, 9, 9, 147, 11, 11, 47, 47, 47, 47, 47, 47, 351, 9, - 9, 353, 11, 11, 47, 47, 47, 47, 27, 27, 27, 27, 27, 27, 27, 27, - 47, 47, 47, 47, 47, 354, 47, 355, 47, 47, 356, 145, 145, 145, 47, 357, - 47, 358, 47, 351, 66, 66, 66, 66, 47, 47, 47, 359, 145, 145, 145, 145, - 360, 47, 47, 361, 145, 66, 47, 362, 47, 363, 145, 145, 364, 47, 365, 66, - 47, 47, 47, 366, 47, 367, 47, 367, 47, 366, 144, 145, 145, 145, 145, 145, - 9, 9, 9, 9, 11, 11, 11, 368, 47, 47, 369, 160, 370, 9, 371, 11, - 372, 227, 227, 227, 227, 227, 227, 227, 145, 145, 145, 145, 145, 145, 145, 145, - 47, 47, 373, 47, 47, 47, 47, 374, 47, 363, 375, 47, 60, 376, 66, 47, - 377, 66, 66, 47, 378, 145, 47, 47, 379, 47, 47, 361, 380, 381, 382, 383, - 180, 47, 47, 384, 385, 47, 47, 160, 97, 47, 386, 387, 388, 47, 47, 389, - 180, 47, 47, 390, 391, 392, 393, 145, 47, 47, 394, 395, 360, 32, 32, 32, - 47, 47, 366, 47, 47, 396, 172, 160, 92, 47, 47, 113, 397, 398, 399, 32, - 47, 47, 47, 400, 401, 402, 403, 32, 47, 47, 47, 404, 405, 406, 47, 47, - 47, 47, 47, 407, 408, 160, 160, 160, 47, 47, 409, 410, 411, 412, 32, 32, - 47, 47, 47, 413, 414, 160, 66, 66, 47, 47, 415, 416, 160, 160, 160, 160, - 47, 417, 418, 419, 47, 47, 47, 47, 47, 47, 394, 420, 66, 66, 66, 66, - 9, 9, 9, 9, 11, 11, 128, 421, 47, 47, 47, 422, 423, 160, 160, 160, - 47, 47, 47, 47, 47, 424, 425, 426, 427, 47, 47, 428, 429, 430, 47, 47, - 431, 432, 66, 47, 47, 47, 47, 47, 66, 66, 66, 66, 66, 66, 66, 66, - 47, 47, 47, 47, 47, 47, 433, 160, 47, 47, 409, 434, 433, 128, 145, 435, - 47, 156, 436, 437, 32, 32, 32, 32, 47, 47, 47, 360, 438, 160, 47, 47, - 439, 440, 160, 160, 160, 160, 160, 160, 47, 47, 47, 47, 47, 47, 47, 441, - 442, 47, 47, 443, 444, 445, 32, 32, 47, 47, 47, 47, 145, 446, 447, 448, - 220, 220, 220, 220, 220, 220, 220, 66, 47, 47, 47, 47, 47, 47, 47, 433, - 47, 47, 47, 209, 449, 32, 47, 47, 47, 450, 451, 160, 160, 160, 160, 160, - 47, 47, 47, 47, 47, 47, 306, 47, 47, 47, 47, 47, 160, 47, 47, 452, - 47, 47, 47, 453, 454, 455, 456, 47, 27, 27, 27, 27, 457, 47, 458, 160, - 9, 9, 9, 9, 9, 9, 11, 11, 145, 459, 66, 66, 66, 66, 66, 66, - 47, 47, 47, 47, 396, 460, 426, 426, 461, 462, 27, 27, 27, 27, 463, 426, - 47, 464, 209, 209, 209, 209, 209, 209, 146, 146, 146, 146, 146, 146, 146, 160, - 32, 32, 32, 32, 32, 146, 146, 146, 146, 146, 146, 146, 146, 146, 465, 466, - 467, 146, 468, 146, 146, 146, 146, 146, 146, 146, 146, 146, 469, 146, 146, 146, - 9, 470, 11, 471, 472, 11, 197, 9, 473, 474, 9, 475, 11, 9, 470, 11, - 471, 472, 11, 197, 9, 473, 474, 9, 475, 11, 9, 470, 11, 471, 472, 11, - 197, 9, 473, 474, 9, 475, 11, 9, 470, 11, 197, 9, 476, 477, 478, 479, - 11, 480, 9, 481, 482, 483, 484, 11, 485, 9, 486, 11, 487, 160, 160, 160, - 32, 32, 32, 488, 32, 32, 489, 490, 491, 492, 32, 32, 32, 32, 32, 32, - 493, 11, 11, 11, 11, 11, 11, 11, 32, 32, 32, 27, 27, 27, 27, 27, - 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 47, 494, 495, 146, 146, 146, - 47, 47, 450, 32, 47, 47, 374, 496, 47, 47, 47, 47, 47, 47, 497, 160, - 47, 47, 47, 47, 47, 47, 450, 498, 47, 47, 47, 47, 356, 32, 32, 32, - 9, 9, 473, 11, 499, 306, 66, 66, 145, 145, 500, 501, 145, 145, 145, 145, - 145, 145, 502, 145, 145, 145, 145, 145, 47, 47, 47, 47, 47, 47, 47, 227, - 503, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 504, - 209, 209, 209, 209, 209, 209, 209, 209, 0, 0, 0, 0, 0, 0, 0, 0, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 716, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 717, + 0, 0, 0, 0, 1, 2, 1, 2, 0, 0, 3, 3, 4, 5, 4, 5, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 0, 0, 7, 0, + 8, 8, 8, 8, 8, 8, 8, 9, 10, 11, 12, 11, 11, 11, 13, 11, + 14, 14, 14, 14, 14, 14, 14, 14, 15, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 16, 17, 18, 17, 17, 19, 20, 21, 21, 22, 21, 23, 24, + 25, 26, 27, 27, 28, 29, 27, 30, 27, 27, 27, 27, 27, 31, 27, 27, + 32, 33, 33, 33, 34, 27, 27, 27, 35, 35, 35, 36, 37, 37, 37, 38, + 39, 39, 40, 41, 42, 43, 44, 27, 27, 45, 27, 27, 27, 27, 46, 27, + 47, 47, 47, 47, 47, 48, 49, 47, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 108, 109, 110, 111, 108, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 121, 122, 121, 123, 124, 124, 125, 126, 127, 128, 129, 130, 124, 124, + 131, 131, 131, 131, 132, 131, 133, 134, 131, 132, 131, 135, 135, 136, 124, 124, + 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 138, 138, 139, 138, 138, 140, + 141, 141, 141, 141, 141, 141, 141, 141, 142, 142, 142, 142, 143, 144, 142, 142, + 143, 142, 142, 145, 146, 147, 142, 142, 142, 146, 142, 142, 142, 148, 142, 149, + 142, 150, 151, 151, 151, 151, 151, 152, 153, 153, 153, 153, 153, 153, 153, 153, + 154, 155, 156, 156, 156, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, 167, 167, 167, 167, 168, 169, 169, 170, 171, 172, 172, 172, 172, 172, 173, + 172, 172, 174, 153, 153, 153, 153, 175, 176, 177, 178, 178, 179, 180, 181, 182, + 183, 183, 184, 183, 185, 186, 167, 167, 187, 188, 189, 189, 189, 190, 189, 191, + 192, 192, 193, 8, 8, 194, 195, 124, 196, 196, 196, 196, 197, 196, 196, 196, + 198, 198, 198, 198, 199, 199, 199, 200, 201, 201, 201, 202, 203, 204, 204, 204, + 205, 138, 138, 206, 207, 208, 209, 210, 4, 4, 211, 4, 4, 212, 213, 214, + 4, 4, 4, 215, 8, 8, 8, 8, 11, 216, 11, 11, 216, 217, 11, 218, + 11, 11, 11, 219, 219, 220, 11, 221, 222, 0, 0, 0, 0, 0, 223, 224, + 225, 226, 0, 0, 227, 8, 8, 228, 0, 0, 229, 230, 231, 0, 4, 4, + 232, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 233, 124, 234, 124, 0, 0, 235, 235, 235, 235, 235, 235, 235, 235, + 0, 0, 0, 0, 0, 0, 0, 236, 237, 237, 237, 237, 237, 237, 4, 4, + 238, 238, 238, 238, 238, 238, 238, 239, 138, 138, 139, 240, 240, 240, 241, 242, + 142, 243, 244, 244, 244, 244, 14, 14, 0, 0, 0, 0, 0, 245, 124, 124, + 246, 247, 246, 246, 246, 246, 246, 248, 246, 246, 246, 246, 246, 246, 246, 246, + 246, 246, 246, 246, 246, 249, 124, 0, 250, 0, 251, 252, 253, 254, 254, 254, + 254, 255, 256, 257, 257, 257, 257, 258, 259, 260, 260, 261, 141, 141, 141, 141, + 262, 0, 260, 260, 0, 0, 263, 257, 141, 262, 0, 0, 0, 0, 141, 264, + 0, 0, 0, 0, 0, 257, 257, 265, 257, 257, 257, 257, 257, 266, 0, 0, + 246, 246, 246, 246, 0, 0, 0, 0, 267, 267, 267, 267, 267, 267, 267, 267, + 268, 267, 267, 267, 269, 270, 270, 270, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 272, 124, 14, 14, 14, 14, 14, 14, 273, 273, 273, 273, 273, 274, + 0, 0, 275, 4, 4, 4, 4, 4, 276, 4, 4, 4, 4, 226, 124, 277, + 278, 278, 279, 233, 280, 280, 280, 281, 282, 282, 282, 282, 283, 284, 47, 47, + 285, 285, 286, 287, 287, 288, 141, 289, 290, 290, 290, 290, 291, 292, 137, 293, + 294, 294, 294, 295, 296, 297, 137, 137, 298, 298, 298, 298, 299, 300, 301, 302, + 303, 304, 244, 4, 4, 305, 306, 151, 151, 151, 151, 151, 301, 301, 307, 308, + 141, 141, 309, 141, 310, 141, 141, 311, 124, 124, 124, 124, 124, 124, 124, 124, + 246, 246, 246, 246, 246, 246, 312, 246, 246, 246, 246, 246, 246, 313, 124, 124, + 314, 315, 21, 316, 317, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 318, 27, 27, 27, 27, 27, 27, 27, 27, 27, 124, 124, 27, + 8, 233, 319, 0, 0, 320, 321, 322, 27, 27, 27, 27, 27, 27, 27, 323, + 324, 0, 1, 2, 1, 2, 325, 256, 257, 326, 141, 262, 327, 328, 329, 330, + 331, 332, 333, 334, 335, 335, 124, 124, 332, 332, 332, 332, 332, 332, 332, 336, + 337, 0, 0, 338, 11, 11, 11, 11, 339, 340, 341, 124, 124, 0, 0, 342, + 343, 344, 345, 345, 345, 346, 347, 348, 349, 349, 350, 351, 352, 353, 353, 354, + 355, 356, 357, 357, 358, 359, 124, 124, 360, 360, 360, 360, 360, 361, 361, 361, + 362, 363, 364, 365, 365, 366, 365, 367, 368, 368, 369, 370, 370, 370, 371, 372, + 372, 373, 374, 375, 376, 376, 376, 377, 378, 378, 378, 378, 378, 378, 378, 378, + 378, 378, 378, 379, 378, 380, 381, 124, 382, 4, 4, 383, 124, 124, 124, 124, + 384, 385, 385, 386, 387, 388, 389, 389, 390, 391, 392, 124, 124, 124, 393, 394, + 395, 396, 397, 398, 399, 400, 124, 124, 401, 401, 402, 403, 402, 404, 402, 402, + 405, 406, 407, 408, 409, 409, 410, 410, 411, 411, 124, 124, 412, 412, 413, 414, + 415, 415, 415, 416, 417, 418, 419, 420, 421, 422, 423, 124, 124, 124, 124, 124, + 424, 424, 424, 424, 425, 124, 124, 124, 426, 426, 426, 427, 426, 426, 426, 428, + 429, 429, 430, 431, 432, 432, 433, 432, 434, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 27, 435, 436, 436, 437, 438, 439, 440, 124, 441, + 442, 442, 443, 444, 444, 445, 124, 446, 447, 124, 124, 448, 449, 124, 450, 451, + 452, 452, 452, 452, 453, 454, 452, 455, 456, 456, 456, 456, 457, 458, 459, 460, + 461, 461, 461, 462, 463, 464, 464, 465, 466, 466, 466, 466, 466, 466, 467, 468, + 469, 470, 469, 469, 471, 124, 124, 124, 472, 473, 474, 475, 475, 475, 476, 477, + 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 487, 488, 489, 490, 491, 124, + 492, 492, 492, 492, 492, 493, 494, 124, 495, 495, 495, 495, 496, 497, 124, 124, + 498, 498, 498, 499, 498, 500, 124, 124, 501, 501, 501, 501, 502, 503, 504, 124, + 505, 505, 505, 506, 506, 137, 507, 124, 508, 509, 510, 508, 511, 124, 124, 124, + 512, 512, 512, 513, 124, 124, 124, 124, 124, 124, 514, 514, 514, 514, 514, 515, + 516, 517, 518, 519, 520, 521, 124, 124, 124, 124, 522, 523, 523, 522, 524, 124, + 525, 525, 525, 525, 526, 527, 527, 527, 527, 527, 528, 153, 529, 529, 529, 530, + 531, 124, 124, 124, 124, 124, 532, 124, 124, 124, 124, 124, 533, 533, 534, 535, + 536, 537, 537, 538, 539, 537, 540, 541, 541, 542, 543, 544, 124, 124, 124, 124, + 545, 546, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 555, 556, 557, 124, + 124, 124, 124, 124, 124, 124, 558, 559, 560, 561, 560, 562, 560, 563, 124, 124, + 124, 124, 124, 564, 565, 565, 565, 566, 567, 567, 567, 567, 567, 567, 567, 567, + 567, 568, 124, 124, 124, 124, 124, 124, 567, 567, 567, 567, 567, 567, 569, 570, + 567, 567, 567, 567, 571, 124, 124, 124, 124, 572, 572, 572, 572, 572, 572, 573, + 574, 574, 574, 574, 574, 574, 574, 574, 574, 574, 574, 574, 574, 575, 574, 574, + 574, 574, 574, 574, 574, 574, 574, 576, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 578, 124, 124, 124, 579, 579, 579, 580, 124, 124, 124, 124, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 581, 582, 583, 584, 585, + 585, 585, 585, 586, 587, 588, 589, 590, 591, 591, 591, 591, 592, 593, 594, 595, + 591, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 596, 596, 596, 597, + 124, 124, 124, 124, 598, 598, 598, 598, 598, 599, 600, 601, 600, 602, 124, 124, + 603, 603, 603, 603, 604, 603, 603, 603, 605, 603, 124, 124, 124, 124, 606, 607, + 608, 608, 608, 608, 608, 608, 608, 608, 609, 609, 609, 609, 609, 609, 609, 609, + 609, 609, 609, 609, 609, 610, 124, 611, 608, 612, 124, 124, 124, 124, 124, 124, + 608, 608, 608, 608, 608, 608, 608, 613, 124, 124, 124, 124, 124, 124, 124, 614, + 615, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, + 254, 254, 616, 617, 124, 618, 619, 620, 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 621, 622, 622, 622, 622, 622, 622, 623, 624, + 625, 626, 627, 124, 124, 124, 124, 124, 0, 0, 0, 0, 0, 0, 0, 340, + 0, 0, 0, 628, 0, 629, 0, 629, 8, 8, 194, 8, 630, 0, 0, 0, + 0, 0, 0, 0, 627, 124, 124, 124, 0, 0, 0, 0, 0, 0, 0, 631, + 0, 0, 632, 0, 0, 0, 633, 634, 635, 0, 636, 0, 0, 0, 234, 124, + 11, 11, 11, 11, 637, 124, 124, 124, 124, 124, 124, 124, 0, 627, 0, 627, + 0, 0, 0, 0, 0, 638, 0, 639, 0, 0, 0, 0, 0, 223, 0, 0, + 0, 640, 641, 642, 643, 0, 0, 0, 644, 645, 0, 646, 647, 648, 0, 0, + 0, 0, 649, 0, 0, 0, 0, 0, 0, 0, 0, 0, 650, 0, 0, 0, + 651, 651, 651, 651, 651, 651, 651, 651, 652, 653, 654, 124, 124, 124, 124, 124, + 4, 655, 656, 124, 124, 124, 124, 124, 657, 658, 659, 14, 14, 14, 660, 124, + 661, 124, 124, 124, 124, 124, 124, 124, 662, 662, 663, 664, 665, 124, 124, 124, + 124, 666, 667, 124, 668, 668, 668, 669, 124, 124, 124, 124, 124, 670, 670, 671, + 124, 124, 124, 124, 124, 672, 672, 673, 124, 124, 124, 124, 674, 675, 674, 676, + 124, 124, 124, 124, 124, 124, 677, 678, 679, 679, 679, 679, 679, 679, 679, 679, + 679, 679, 679, 679, 680, 681, 124, 124, 682, 682, 682, 682, 683, 684, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 324, 0, 0, 0, 685, 124, 124, 124, 124, + 324, 0, 0, 245, 124, 124, 124, 124, 686, 27, 687, 688, 689, 690, 691, 692, + 693, 694, 695, 694, 124, 124, 124, 696, 0, 0, 348, 0, 0, 0, 0, 0, + 0, 627, 225, 324, 324, 324, 0, 631, 0, 0, 245, 124, 124, 124, 697, 0, + 698, 0, 0, 348, 639, 227, 631, 124, 0, 0, 0, 0, 0, 699, 340, 340, + 0, 0, 0, 0, 0, 233, 348, 629, 348, 0, 0, 0, 700, 233, 0, 0, + 700, 0, 245, 348, 227, 639, 124, 124, 0, 0, 0, 0, 0, 700, 245, 340, + 701, 0, 0, 0, 702, 703, 704, 639, 0, 320, 0, 0, 0, 0, 0, 234, + 246, 246, 246, 246, 246, 246, 124, 124, 246, 312, 246, 246, 246, 246, 246, 246, + 246, 246, 312, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 705, 246, + 246, 246, 246, 246, 246, 312, 124, 124, 246, 312, 124, 124, 124, 124, 124, 124, + 246, 246, 246, 246, 706, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 313, + 707, 124, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 1, 2, 2, 2, + 2, 2, 3, 0, 0, 0, 4, 0, 2, 2, 2, 2, 2, 3, 2, 2, + 2, 2, 5, 0, 2, 5, 6, 0, 7, 7, 7, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 8, 8, 8, 8, 16, 8, 8, 8, 17, 18, 18, 18, + 19, 19, 19, 19, 19, 20, 19, 19, 21, 22, 22, 22, 22, 22, 22, 22, + 22, 23, 21, 22, 22, 22, 23, 21, 24, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 12, 12, 25, 25, 26, 27, 25, 28, 12, 12, 29, 30, 29, 31, + 29, 29, 32, 32, 29, 29, 29, 29, 31, 29, 33, 7, 7, 34, 29, 29, + 35, 29, 29, 29, 29, 29, 29, 30, 36, 36, 36, 37, 36, 36, 36, 36, + 36, 36, 38, 39, 40, 40, 40, 40, 41, 12, 12, 12, 42, 42, 42, 42, + 42, 42, 43, 44, 45, 45, 45, 45, 45, 45, 45, 46, 45, 45, 45, 47, + 48, 48, 48, 48, 48, 48, 48, 49, 36, 36, 38, 12, 50, 51, 29, 29, + 52, 29, 29, 29, 53, 53, 53, 53, 54, 55, 53, 53, 53, 56, 53, 53, + 57, 58, 57, 59, 59, 57, 57, 57, 57, 57, 60, 57, 61, 62, 63, 57, + 57, 59, 59, 64, 12, 65, 12, 66, 57, 62, 57, 57, 57, 57, 57, 64, + 67, 67, 68, 69, 70, 71, 71, 71, 71, 71, 72, 71, 72, 73, 74, 72, + 68, 69, 70, 74, 75, 12, 67, 76, 12, 77, 71, 71, 71, 68, 12, 12, + 78, 78, 79, 80, 80, 79, 79, 79, 79, 79, 81, 79, 81, 78, 82, 79, + 79, 80, 80, 82, 83, 12, 12, 12, 79, 84, 79, 79, 82, 12, 78, 79, + 85, 85, 86, 87, 87, 86, 86, 86, 86, 86, 88, 86, 88, 85, 89, 86, + 86, 87, 87, 89, 12, 85, 12, 90, 86, 91, 86, 86, 86, 86, 12, 12, + 92, 93, 94, 92, 95, 96, 97, 95, 98, 99, 94, 92, 100, 100, 96, 92, + 94, 92, 95, 96, 99, 98, 12, 12, 12, 92, 100, 100, 100, 100, 94, 12, + 101, 101, 101, 102, 102, 101, 101, 101, 101, 101, 102, 101, 101, 101, 103, 101, + 101, 102, 102, 103, 12, 104, 105, 103, 101, 106, 101, 101, 12, 107, 101, 101, + 108, 108, 108, 109, 109, 108, 108, 108, 108, 108, 109, 108, 108, 110, 111, 108, + 108, 109, 109, 111, 12, 112, 12, 113, 108, 114, 108, 108, 110, 12, 12, 12, + 115, 115, 115, 116, 116, 115, 115, 115, 115, 115, 115, 115, 115, 116, 116, 115, + 12, 115, 115, 115, 115, 117, 115, 115, 118, 118, 119, 119, 119, 120, 121, 119, + 119, 119, 119, 119, 122, 119, 119, 123, 119, 120, 124, 125, 119, 126, 119, 119, + 12, 121, 119, 119, 121, 127, 12, 12, 128, 129, 129, 129, 129, 129, 129, 129, + 129, 129, 130, 131, 129, 129, 129, 12, 12, 12, 12, 12, 132, 133, 134, 135, + 135, 135, 135, 135, 135, 136, 135, 135, 135, 135, 135, 137, 135, 138, 135, 134, + 135, 135, 137, 135, 139, 139, 139, 139, 139, 139, 140, 139, 139, 139, 139, 141, + 140, 139, 139, 139, 139, 139, 139, 142, 139, 143, 144, 12, 145, 145, 145, 145, + 146, 146, 146, 146, 146, 147, 12, 148, 146, 146, 149, 146, 150, 150, 150, 150, + 151, 151, 151, 151, 151, 151, 152, 153, 151, 154, 152, 153, 152, 153, 151, 154, + 152, 153, 151, 151, 151, 154, 151, 151, 151, 151, 154, 155, 151, 151, 151, 156, + 151, 151, 153, 12, 157, 157, 157, 157, 157, 158, 157, 158, 159, 159, 159, 159, + 160, 160, 160, 160, 160, 160, 160, 161, 162, 162, 162, 162, 162, 162, 163, 164, + 162, 162, 165, 12, 166, 166, 166, 166, 166, 167, 12, 168, 169, 169, 169, 169, + 169, 170, 12, 12, 171, 171, 171, 171, 171, 12, 12, 12, 172, 172, 172, 173, + 173, 12, 12, 12, 174, 174, 174, 174, 174, 174, 174, 175, 174, 174, 175, 12, + 176, 177, 178, 178, 178, 178, 179, 12, 178, 178, 178, 178, 178, 178, 180, 12, + 178, 178, 181, 12, 159, 182, 12, 12, 183, 183, 183, 183, 183, 183, 183, 184, + 183, 183, 183, 12, 185, 183, 183, 183, 186, 186, 186, 186, 186, 186, 186, 187, + 186, 188, 12, 12, 189, 189, 189, 189, 189, 189, 189, 12, 189, 189, 190, 12, + 189, 189, 191, 192, 193, 193, 193, 193, 193, 193, 193, 194, 195, 195, 195, 195, + 195, 195, 195, 196, 195, 195, 195, 197, 195, 195, 198, 12, 195, 195, 195, 198, + 7, 7, 7, 199, 7, 7, 7, 12, 200, 200, 200, 200, 200, 200, 200, 201, + 202, 202, 202, 202, 203, 203, 203, 203, 203, 12, 12, 203, 204, 204, 204, 204, + 204, 204, 205, 204, 204, 204, 206, 207, 208, 208, 208, 208, 19, 19, 209, 12, + 146, 146, 210, 211, 202, 202, 12, 12, 212, 7, 7, 7, 213, 7, 214, 215, + 0, 214, 216, 12, 2, 217, 218, 2, 2, 2, 2, 219, 220, 217, 221, 2, + 2, 2, 222, 2, 2, 2, 2, 223, 8, 224, 8, 224, 8, 8, 225, 225, + 8, 8, 8, 224, 8, 15, 8, 8, 8, 10, 8, 226, 10, 15, 8, 14, + 0, 0, 0, 227, 0, 228, 0, 0, 229, 0, 0, 230, 0, 0, 0, 231, + 2, 2, 2, 232, 233, 12, 12, 12, 234, 12, 12, 12, 0, 235, 236, 0, + 4, 0, 0, 0, 0, 0, 0, 4, 2, 2, 5, 12, 0, 0, 233, 12, + 0, 0, 231, 12, 237, 237, 237, 237, 0, 238, 0, 0, 239, 239, 239, 239, + 18, 18, 18, 18, 18, 12, 240, 18, 241, 241, 241, 241, 241, 241, 12, 242, + 243, 12, 12, 242, 151, 154, 12, 12, 151, 154, 151, 154, 0, 0, 0, 233, + 244, 244, 244, 244, 244, 244, 245, 244, 244, 12, 12, 12, 244, 246, 12, 12, + 0, 247, 0, 0, 248, 244, 249, 250, 0, 0, 244, 0, 251, 252, 252, 252, + 252, 252, 252, 252, 252, 253, 254, 255, 256, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 258, 256, 12, 259, 260, 260, 260, 260, 260, 260, 261, 150, 150, 150, + 150, 150, 150, 262, 0, 233, 12, 131, 150, 150, 150, 263, 257, 257, 257, 258, + 257, 257, 0, 0, 264, 264, 264, 264, 264, 264, 264, 265, 264, 266, 12, 12, + 267, 267, 267, 267, 268, 268, 268, 268, 268, 268, 268, 12, 269, 269, 269, 269, + 269, 269, 12, 12, 236, 2, 2, 2, 2, 2, 230, 2, 270, 2, 2, 2, + 271, 271, 271, 271, 271, 271, 271, 272, 273, 273, 273, 273, 273, 273, 12, 12, + 274, 274, 274, 274, 274, 275, 12, 276, 274, 274, 275, 12, 277, 277, 277, 277, + 277, 277, 277, 278, 279, 279, 279, 279, 279, 12, 12, 280, 150, 150, 150, 281, + 282, 282, 282, 282, 282, 282, 282, 283, 282, 282, 284, 285, 145, 145, 145, 286, + 287, 287, 287, 287, 287, 288, 12, 12, 287, 287, 287, 289, 287, 287, 289, 287, + 290, 290, 290, 290, 291, 12, 12, 12, 12, 12, 292, 290, 293, 293, 293, 293, + 293, 294, 12, 12, 155, 154, 155, 154, 155, 154, 12, 12, 2, 2, 3, 2, + 2, 295, 296, 12, 293, 293, 293, 297, 293, 293, 297, 12, 150, 12, 12, 12, + 150, 262, 298, 150, 150, 150, 150, 12, 244, 244, 244, 246, 244, 244, 246, 12, + 2, 299, 12, 12, 300, 22, 12, 24, 25, 26, 25, 301, 302, 303, 25, 25, + 29, 29, 29, 304, 7, 7, 7, 305, 231, 0, 0, 0, 0, 231, 0, 12, + 29, 306, 29, 29, 29, 29, 29, 307, 308, 0, 0, 0, 0, 309, 257, 257, + 257, 257, 257, 310, 311, 150, 311, 150, 311, 150, 311, 281, 0, 231, 0, 231, + 12, 12, 308, 233, 312, 312, 312, 313, 312, 312, 312, 312, 312, 314, 312, 312, + 312, 312, 314, 315, 312, 312, 312, 316, 312, 312, 314, 12, 231, 131, 0, 0, + 0, 131, 0, 0, 8, 8, 8, 14, 0, 0, 0, 317, 318, 12, 12, 12, + 0, 0, 0, 319, 320, 320, 320, 320, 320, 320, 320, 321, 322, 322, 322, 322, + 323, 12, 12, 12, 214, 0, 0, 0, 0, 0, 0, 12, 324, 324, 324, 324, + 324, 12, 12, 325, 326, 326, 326, 326, 326, 326, 327, 12, 328, 328, 328, 328, + 328, 328, 329, 12, 330, 330, 330, 330, 330, 330, 330, 331, 332, 332, 332, 332, + 332, 12, 332, 332, 332, 333, 12, 12, 334, 334, 334, 334, 335, 335, 335, 335, + 336, 336, 336, 336, 336, 336, 336, 337, 336, 336, 337, 12, 338, 338, 338, 338, + 338, 12, 338, 338, 338, 338, 338, 12, 339, 339, 339, 339, 339, 339, 12, 12, + 340, 340, 340, 340, 340, 12, 12, 341, 342, 342, 343, 342, 343, 344, 342, 342, + 344, 342, 342, 342, 344, 342, 344, 345, 346, 346, 346, 346, 346, 12, 12, 12, + 347, 347, 347, 347, 347, 348, 12, 12, 347, 349, 12, 12, 347, 347, 12, 12, + 2, 350, 2, 2, 351, 2, 299, 12, 352, 353, 354, 352, 352, 352, 352, 352, + 352, 355, 356, 357, 358, 358, 358, 358, 358, 359, 358, 358, 360, 360, 360, 360, + 361, 361, 361, 361, 361, 361, 361, 362, 12, 363, 361, 361, 364, 364, 364, 364, + 365, 366, 367, 364, 368, 368, 368, 368, 368, 368, 368, 369, 370, 370, 370, 370, + 370, 370, 371, 372, 373, 373, 373, 373, 373, 373, 374, 12, 375, 375, 375, 375, + 376, 376, 376, 376, 376, 376, 12, 376, 377, 376, 376, 376, 378, 379, 12, 378, + 378, 380, 380, 378, 378, 378, 378, 378, 378, 381, 382, 383, 378, 378, 384, 12, + 385, 385, 385, 385, 386, 386, 386, 386, 387, 387, 387, 387, 387, 388, 389, 387, + 387, 388, 12, 12, 390, 390, 390, 390, 390, 391, 392, 390, 393, 393, 393, 393, + 393, 394, 393, 393, 395, 395, 395, 395, 396, 12, 395, 395, 397, 397, 397, 397, + 398, 12, 399, 400, 12, 12, 399, 397, 401, 401, 401, 401, 401, 401, 402, 12, + 403, 403, 403, 403, 404, 12, 12, 12, 404, 12, 405, 403, 406, 406, 406, 406, + 406, 406, 12, 12, 406, 406, 407, 12, 408, 408, 408, 408, 408, 409, 410, 408, + 408, 409, 12, 411, 29, 29, 29, 412, 413, 413, 413, 413, 413, 413, 414, 415, + 415, 12, 12, 12, 416, 29, 12, 12, 29, 29, 417, 12, 12, 12, 416, 29, + 418, 418, 418, 418, 418, 418, 12, 12, 419, 419, 419, 419, 419, 419, 420, 12, + 421, 421, 421, 421, 421, 421, 422, 12, 423, 423, 423, 423, 423, 423, 423, 12, + 424, 424, 424, 424, 424, 425, 12, 12, 426, 426, 426, 426, 426, 426, 426, 427, + 428, 426, 426, 426, 426, 427, 12, 429, 430, 430, 430, 430, 431, 12, 12, 432, + 433, 433, 433, 433, 433, 433, 434, 12, 433, 433, 435, 12, 436, 436, 436, 436, + 436, 437, 436, 436, 436, 436, 12, 12, 438, 438, 438, 438, 438, 439, 12, 12, + 440, 440, 440, 440, 118, 119, 119, 119, 119, 127, 12, 12, 441, 441, 441, 441, + 442, 441, 441, 441, 443, 12, 12, 12, 444, 445, 446, 447, 444, 444, 444, 447, + 444, 444, 448, 12, 449, 449, 449, 449, 449, 449, 450, 12, 449, 449, 451, 12, + 452, 453, 452, 454, 454, 452, 452, 452, 452, 452, 455, 452, 455, 453, 456, 452, + 452, 454, 454, 457, 458, 459, 12, 453, 452, 460, 452, 458, 452, 458, 12, 12, + 461, 461, 462, 463, 461, 461, 461, 461, 461, 462, 461, 461, 464, 465, 466, 461, + 461, 462, 467, 12, 468, 12, 12, 12, 469, 469, 469, 469, 469, 469, 469, 470, + 471, 12, 12, 12, 472, 472, 472, 472, 472, 472, 12, 12, 472, 472, 473, 12, + 474, 474, 474, 474, 474, 475, 474, 474, 474, 474, 474, 475, 476, 476, 476, 476, + 476, 477, 12, 12, 476, 476, 478, 12, 178, 178, 178, 180, 479, 479, 479, 479, + 479, 479, 480, 12, 145, 12, 12, 12, 481, 481, 481, 481, 481, 481, 482, 483, + 481, 481, 481, 12, 481, 482, 12, 12, 484, 484, 484, 484, 484, 484, 484, 12, + 485, 485, 485, 485, 486, 12, 12, 487, 488, 489, 490, 488, 488, 491, 488, 488, + 488, 488, 488, 488, 488, 492, 493, 488, 488, 489, 12, 12, 488, 488, 494, 12, + 495, 495, 496, 495, 495, 495, 495, 495, 495, 497, 12, 12, 498, 498, 498, 498, + 498, 498, 12, 12, 499, 499, 499, 499, 500, 12, 12, 12, 501, 501, 501, 501, + 501, 501, 502, 12, 53, 53, 503, 12, 440, 440, 12, 12, 504, 504, 504, 504, + 505, 12, 12, 12, 504, 504, 505, 12, 506, 506, 507, 506, 506, 506, 506, 506, + 506, 508, 506, 506, 506, 509, 12, 12, 506, 506, 506, 510, 511, 511, 511, 511, + 512, 511, 511, 511, 511, 511, 513, 511, 511, 514, 12, 12, 515, 516, 517, 515, + 515, 515, 515, 515, 515, 516, 518, 517, 515, 515, 12, 12, 515, 515, 519, 12, + 520, 521, 522, 520, 520, 520, 520, 520, 520, 520, 520, 523, 521, 520, 524, 12, + 520, 520, 525, 12, 526, 526, 526, 526, 526, 526, 526, 12, 526, 526, 527, 12, + 528, 528, 528, 528, 528, 528, 529, 12, 530, 530, 530, 530, 531, 530, 530, 530, + 530, 530, 532, 533, 530, 530, 532, 12, 534, 12, 12, 12, 100, 100, 100, 100, + 96, 12, 12, 98, 535, 535, 535, 535, 535, 535, 536, 12, 535, 535, 535, 537, + 535, 538, 12, 12, 535, 12, 12, 12, 539, 539, 539, 539, 540, 12, 12, 12, + 541, 541, 541, 541, 541, 542, 12, 12, 541, 541, 543, 12, 544, 544, 544, 544, + 544, 545, 12, 12, 546, 546, 546, 546, 546, 546, 547, 12, 269, 269, 548, 12, + 549, 549, 549, 549, 549, 549, 549, 550, 549, 549, 551, 552, 553, 553, 553, 553, + 553, 553, 553, 554, 553, 553, 555, 12, 556, 556, 556, 556, 556, 556, 556, 557, + 556, 557, 12, 12, 558, 558, 558, 558, 558, 559, 12, 12, 558, 558, 560, 558, + 560, 558, 558, 558, 558, 558, 12, 561, 562, 562, 562, 562, 562, 562, 563, 12, + 564, 564, 564, 564, 564, 564, 565, 12, 566, 566, 566, 566, 566, 566, 567, 566, + 566, 12, 12, 12, 568, 568, 568, 568, 568, 568, 569, 570, 568, 568, 12, 570, + 571, 572, 12, 12, 244, 573, 12, 12, 574, 574, 574, 574, 575, 575, 575, 575, + 575, 576, 12, 12, 12, 12, 12, 577, 574, 574, 574, 578, 578, 12, 12, 12, + 257, 579, 257, 580, 581, 252, 252, 252, 582, 12, 12, 12, 583, 12, 12, 12, + 253, 584, 12, 12, 12, 257, 12, 12, 585, 585, 585, 585, 585, 585, 585, 12, + 586, 586, 586, 586, 586, 586, 587, 12, 586, 586, 586, 588, 586, 586, 588, 12, + 586, 586, 589, 586, 0, 12, 12, 12, 0, 12, 238, 0, 317, 12, 12, 12, + 7, 590, 12, 12, 0, 233, 12, 12, 0, 231, 308, 0, 0, 591, 227, 0, + 0, 0, 591, 7, 212, 592, 7, 0, 0, 0, 593, 227, 8, 224, 12, 12, + 0, 231, 12, 12, 0, 0, 317, 12, 0, 0, 0, 228, 594, 595, 308, 228, + 0, 0, 596, 308, 0, 308, 0, 0, 0, 596, 231, 308, 0, 228, 0, 228, + 0, 0, 596, 231, 0, 597, 238, 0, 228, 0, 0, 0, 0, 233, 0, 0, + 0, 0, 0, 238, 598, 598, 598, 598, 598, 598, 598, 12, 12, 12, 599, 598, + 600, 598, 598, 598, 2, 2, 2, 299, 12, 270, 299, 12, 239, 601, 239, 239, + 239, 239, 602, 239, 603, 604, 601, 12, 19, 19, 19, 605, 12, 12, 12, 606, + 607, 607, 607, 607, 607, 607, 607, 608, 607, 607, 607, 609, 607, 607, 609, 610, + 611, 611, 611, 611, 611, 611, 611, 612, 613, 613, 613, 613, 613, 613, 614, 615, + 616, 616, 616, 616, 616, 616, 617, 12, 618, 618, 618, 618, 618, 618, 619, 620, + 621, 621, 621, 621, 621, 621, 621, 622, 621, 623, 12, 624, 151, 154, 151, 625, + 151, 151, 151, 154, 626, 626, 626, 626, 626, 627, 626, 626, 626, 628, 12, 12, + 629, 629, 629, 629, 629, 629, 629, 12, 629, 629, 630, 631, 0, 317, 12, 12, + 29, 632, 29, 29, 633, 634, 632, 29, 412, 29, 635, 12, 636, 51, 635, 632, + 633, 634, 635, 635, 633, 634, 412, 29, 412, 29, 632, 637, 29, 29, 638, 29, + 29, 29, 29, 12, 632, 632, 638, 29, 50, 12, 12, 12, 12, 238, 0, 0, + 639, 12, 12, 12, 0, 0, 317, 0, 0, 0, 12, 12, 0, 0, 231, 238, + 0, 231, 317, 308, 0, 0, 0, 640, 0, 0, 231, 131, 641, 12, 12, 12, + 244, 244, 573, 12, 642, 12, 12, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962, 969, 970, 971, 976,1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0, 0,1080,1081,1082,1086,1110, 0, 0,1124,1125,1126,1127,1131,1133, 0,1147, @@ -5831,8 +4348,7 @@ _hb_ucd_u16[5080] = 96, 929, 802, 804, 806, 97, 98, 807, 930, 99, 931, 932, 933, 814, 100, 816, 817, 818, 819, 820, 821, 935, 0, 0, }; -static const int16_t -_hb_ucd_i16[92] = +static const int16_t _hb_ucd_i16[92]= { 0, 0, 1, -1, 2, 0, -2, 0, 0, 2, 0, -2, 0, 16, 0, -16, 0, 1, -1, 0, 3, 3, 3, -3, -3, -3, 0, 2016, 0, 2527, 1923, 1914, @@ -5842,40 +4358,1271 @@ _hb_ucd_i16[92] = 0,-2016,-2104, 0, 0,-2106,-2108,-2106,-2250, 0,-2527, 0, }; -static inline uint_fast8_t -_hb_ucd_gc (unsigned u) +static inline uint8_t _hb_ucd_gc (unsigned u) { - return u<1114112u?_hb_ucd_u8[5208+(((_hb_ucd_u8[1168+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; + return u<1114110 ? _hb_ucd_u8[6560u+((_hb_ucd_u8[816u+((_hb_ucd_u16[((_hb_ucd_u8[272u+((_hb_ucd_u8[((((((((u)>>1))>>3))>>4))>>4)])<<4)+((((((((u)>>1))>>3))>>4))&15)])<<4)+((((((u)>>1))>>3))&15)])<<3)+((((u)>>1))&7)])<<1)+((u)&1)] : 2; } -static inline uint_fast8_t -_hb_ucd_ccc (unsigned u) +static inline uint8_t _hb_ucd_ccc (unsigned u) { - return u<125259u?_hb_ucd_u8[7206+(((_hb_ucd_u8[6638+(((_hb_ucd_u8[6162+(((_hb_ucd_u8[5802+(((_hb_ucd_u8[5556+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; + return u<125259 ? _hb_ucd_u8[8620u+((_hb_ucd_u8[8036u+((_hb_ucd_u8[7556u+((_hb_ucd_u8[7188u+((_hb_ucd_u8[6942u+((((((((u)>>2))>>2))>>2))>>3)])<<3)+((((((((u)>>2))>>2))>>2))&7)])<<2)+((((((u)>>2))>>2))&3)])<<2)+((((u)>>2))&3)])<<2)+((u)&3)] : 0; } -static inline unsigned -_hb_ucd_b4 (const uint8_t* a, unsigned i) +static inline uint8_t _hb_ucd_b4 (const uint8_t* a, unsigned i) { - return (a[i>>1]>>((i&1u)<<2))&15u; + return (a[i>>1]>>((i&1)<<2))&15; } -static inline int_fast16_t -_hb_ucd_bmg (unsigned u) +static inline int16_t _hb_ucd_bmg (unsigned u) { - return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[8098+(((_hb_ucd_u8[7866+(((_hb_ucd_u8[7770+(((_hb_ucd_b4(7706+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0; + return u<65380 ? _hb_ucd_i16[((_hb_ucd_u8[9516u+((_hb_ucd_u8[9284u+((_hb_ucd_u8[9188u+((_hb_ucd_b4(_hb_ucd_u8+9124u,((((((((u)>>1))>>2))>>3))>>3)))<<3)+((((((((u)>>1))>>2))>>3))&7)])<<3)+((((((u)>>1))>>2))&7)])<<2)+((((u)>>1))&3)])<<1)+((u)&1)] : 0; } -static inline uint_fast8_t -_hb_ucd_sc (unsigned u) +static inline uint8_t _hb_ucd_sc (unsigned u) { - return u<918016u?_hb_ucd_u8[11464+(((_hb_ucd_u8[10472+(((_hb_ucd_u8[9452+(((_hb_ucd_u8[8764+(((_hb_ucd_u8[8460+(((_hb_ucd_u8[8346+(u>>2>>2>>2>>3>>4)])<<4)+((u>>2>>2>>2>>3)&15u))])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2; + return u<918000 ? _hb_ucd_u8[10950u+((_hb_ucd_u16[4648u+((_hb_ucd_u16[2608u+((_hb_ucd_u8[10214u+((_hb_ucd_u8[9764u+((((((((u)>>2))>>2))>>3))>>4)])<<4)+((((((((u)>>2))>>2))>>3))&15)])<<3)+((((((u)>>2))>>2))&7)])<<2)+((((u)>>2))&3)])<<2)+((u)&3)] : 2; } -static inline uint_fast16_t -_hb_ucd_dm (unsigned u) +static inline uint16_t _hb_ucd_dm (unsigned u) { - return u<195102u?_hb_ucd_u16[1656+(((_hb_ucd_u8[12834+(((_hb_ucd_u8[12452+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; + return u<195102 ? _hb_ucd_u16[7480u+((_hb_ucd_u8[13904u+((_hb_ucd_u8[13522u+((((u)>>4))>>5)])<<5)+((((u)>>4))&31)])<<4)+((u)&15)] : 0; } + +#else + +#include + +static const uint8_t _hb_ucd_u8[13937]= +{ + 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 9, 10, 7, 7, 7, 7, 7, 11, 12, 12, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 7, 21, 22, 22, 22, 23, 24, 7, 7, + 7, 25, 22, 22, 22, 26, 27, 28, 22, 29, 30, 31, 32, 33, 34, 35, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 21, 22, 36, + 7, 7, 7, 7, 7, 7, 37, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 38, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 34, 34, 34, 35, 36, 37, 34, 34, 34, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 62, 63, 64, 65, 66, 67, 68, 69, 67, 70, 71, + 67, 67, 62, 72, 62, 62, 73, 67, 74, 75, 76, 77, 78, 67, 67, 67, + 79, 80, 34, 81, 82, 83, 67, 67, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 84, 34, 34, 34, 34, + 85, 34, 34, 34, 34, 34, 34, 34, 34, 86, 34, 34, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 34, 34, 34, 34, 34, 34, 34, 34, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, + 100,100, 34, 34, 34, 34,101,102, 34, 34,103,104,105,106,107,108, + 34, 34,109,110,111,112,113,114,115,116,117,118, 34, 34, 34,119, + 120,121,122,123,124,125,126,127, 34,128,129,130,131,132,133,134, + 135,136,137,138,139,140,141,142,143,144,111,145,146,147,148,111, + 149,150,151,152,153,154,155,156,157,158,159,160,111,161,162,163, + 34, 34, 34, 34, 34, 34, 34, 34,164, 34, 34,111,111,111,111,111, + 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,165, + 34, 34, 34, 34, 34, 34, 34, 34,166, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111, + 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, + 111,111,167,111,111,111,111,111,111,111,111,111,111,111,111,111, + 34, 34, 34, 34,168,169,170, 34,111,111,171,111,172,173,174,175, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111, + 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,119, + 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111, + 111,111,111,111,111,111,111,111, 34,176,111,111,111,111,111,111, + 111,111,111,111,111,111,111,111, 67,177, 67, 67, 67,178,179, 67, + 67, 67,180,181,182,131, 65,111,183,184,185,186,187,188,189,190, + 67, 67, 67, 67,191,192,111,111,111,111,111,111,111,111,193,111, + 194,195,196,111,111,197,111,111,111,198,111,199,111,200,111, 34, + 34,201,202,111,111,111,111,111,131,203,204,111, 34,205,111,111, + 67, 67,206, 67, 67,111, 67,207, 67, 67, 67, 67, 67, 67, 67, 67, + 67,208, 67, 67, 67, 67, 67,177,111,111,111,111,111,111,111,111, + 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111,111, + 34, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111, + 209,111,195,195,111,111,111,111,111,111,111,111,111,111,111,111, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2, + 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 17, 18, 19, 1, 20, 20, 21, 22, 23, 24, 25, + 26, 27, 15, 2, 28, 29, 27, 30, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 31, 11, 11, 11, 32, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 33, 16, 16, 16, 16, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 34, 34, 34, 34, 34, 34, 34, 34, 16, 32, 32, 32, + 32, 32, 32, 32, 11, 34, 34, 16, 34, 32, 32, 11, 34, 11, 16, 11, + 11, 34, 32, 11, 32, 16, 11, 34, 32, 32, 32, 11, 34, 16, 32, 11, + 34, 11, 34, 34, 32, 35, 32, 16, 36, 36, 37, 34, 38, 37, 34, 34, + 34, 34, 34, 34, 34, 34, 16, 32, 34, 38, 32, 11, 32, 32, 32, 32, + 32, 32, 16, 16, 16, 11, 34, 32, 34, 34, 11, 32, 32, 32, 32, 32, + 16, 16, 36, 16, 16, 16, 16, 16, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 40, 40, 39, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, 40, + 39, 39, 41, 40, 40, 40, 41, 41, 40, 40, 40, 40, 40, 40, 40, 40, + 42, 42, 42, 42, 42, 42, 42, 42, 32, 32, 41, 32, 16, 43, 16, 10, + 40, 40, 40, 44, 11, 11, 11, 11, 34, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34, + 16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 45, 34, 32, 34, 11, + 32, 46, 42, 42, 47, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16, + 11, 11, 11, 11, 48, 2, 2, 2, 16, 16, 16, 16, 49, 50, 51, 52, + 53, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 54, + 55, 56, 42, 55, 42, 42, 42, 42, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 57, 2, 2, 2, 2, 2, 2, 58, 58, 58, 8, 9, 59, 2, 60, + 42, 42, 42, 42, 42, 56, 61, 2, 62, 36, 36, 36, 36, 63, 42, 42, + 7, 7, 7, 7, 7, 2, 2, 36, 64, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 65, 42, 42, 42, 66, 46, 42, 42, 67, 68, 69, 42, 42, 36, + 7, 7, 7, 7, 7, 36, 70, 71, 2, 2, 2, 2, 2, 2, 2, 72, + 63, 36, 36, 36, 36, 36, 36, 36, 42, 42, 42, 42, 42, 42, 64, 36, + 36, 36, 36, 42, 42, 42, 42, 42, 7, 7, 7, 7, 7, 36, 36, 36, + 36, 36, 36, 36, 36, 63, 42, 42, 42, 42, 39, 21, 2, 39, 68, 20, + 36, 36, 36, 42, 42, 68, 42, 42, 42, 42, 68, 42, 68, 42, 42, 42, + 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 36, 36, 63, 42, 42, 2, + 36, 36, 36, 36, 73, 36, 36, 36, 58, 58, 58, 74, 42, 42, 42, 42, + 36, 36, 36, 36, 75, 42, 42, 42, 42, 74, 42, 42, 42, 42, 42, 42, + 42, 76, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 76, 64, 77, + 78, 42, 42, 42, 76, 77, 78, 77, 63, 42, 42, 42, 36, 36, 36, 36, + 36, 42, 2, 7, 7, 7, 7, 7, 79, 36, 36, 36, 36, 36, 36, 36, + 63, 77, 80, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 64, 77, + 78, 42, 42, 76, 77, 77, 78, 36, 36, 36, 36, 81, 77, 77, 36, 36, + 36, 42, 42, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 52, 57, 42, + 42, 76, 80, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 42, 77, + 78, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 64, 36, 36, 36, + 36, 36, 36, 7, 7, 7, 7, 7, 42, 36, 63, 2, 2, 2, 2, 2, + 78, 42, 42, 42, 76, 77, 78, 42, 59, 20, 20, 20, 82, 42, 42, 42, + 42, 77, 80, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 64, 78, + 78, 42, 42, 76, 77, 77, 78, 42, 42, 42, 42, 76, 77, 77, 36, 36, + 71, 27, 27, 27, 27, 27, 27, 27, 42, 64, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 77, 76, 77, 77, 77, 77, 77, 78, 42, + 36, 36, 36, 81, 77, 77, 77, 77, 77, 77, 77, 7, 7, 7, 7, 7, + 27, 83, 60, 60, 52, 60, 60, 60, 76, 77, 64, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 64, 42, 76, 77, 77, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 36, 36, 36, 36, 7, 7, 7, 84, 27, 27, 27, 83, + 63, 77, 65, 36, 36, 36, 36, 36, 77, 77, 77, 76, 77, 77, 42, 42, + 42, 42, 76, 77, 77, 77, 36, 36, 85, 81, 77, 77, 77, 77, 77, 77, + 42, 77, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 63, 64, 77, + 78, 42, 42, 77, 77, 77, 78, 70, 60, 60, 36, 81, 27, 27, 27, 86, + 27, 27, 27, 27, 83, 36, 36, 36, 36, 36, 36, 36, 36, 42, 42, 76, + 77, 42, 42, 42, 77, 77, 77, 77, 7, 77, 2, 2, 2, 2, 2, 2, + 63, 36, 42, 42, 42, 42, 42, 87, 36, 36, 36, 68, 42, 42, 42, 56, + 7, 7, 7, 7, 7, 2, 2, 2, 63, 36, 42, 42, 42, 42, 64, 36, + 36, 36, 36, 39, 42, 42, 42, 42, 7, 7, 7, 7, 7, 7, 36, 36, + 70, 60, 2, 2, 2, 2, 2, 2, 2, 88, 88, 60, 42, 60, 60, 60, + 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 46, 46, 46, 4, 4, 77, + 63, 42, 42, 42, 42, 42, 42, 76, 42, 42, 56, 42, 36, 36, 63, 42, + 42, 42, 42, 42, 42, 42, 42, 60, 60, 60, 60, 69, 60, 60, 60, 60, + 2, 2, 88, 60, 21, 2, 2, 2, 36, 36, 36, 36, 36, 81, 78, 42, + 76, 42, 42, 42, 78, 76, 78, 64, 36, 36, 36, 77, 42, 36, 36, 42, + 64, 77, 80, 81, 77, 77, 77, 36, 63, 42, 64, 36, 36, 36, 36, 36, + 36, 76, 78, 76, 77, 77, 78, 81, 7, 7, 7, 7, 7, 77, 78, 60, + 16, 16, 16, 16, 16, 49, 43, 16, 36, 36, 36, 36, 36, 36, 63, 42, + 2, 2, 2, 2, 89, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 60, 60, 60, 60, 60, 60, 60, 60, 11, 11, 11, 11, 16, 16, 16, 16, + 90, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 70, 65, + 91, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 92, 93, 93, + 36, 36, 36, 36, 36, 57, 2, 94, 95, 36, 36, 36, 36, 36, 36, 36, + 36, 42, 76, 77, 77, 77, 77, 80, 36, 42, 96, 2, 2, 2, 2, 2, + 36, 42, 42, 42, 42, 42, 42, 42, 36, 36, 42, 78, 42, 42, 42, 77, + 77, 77, 77, 76, 78, 42, 42, 42, 42, 42, 2, 79, 2, 59, 63, 42, + 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 97, 2, 55, 42, 74, + 36, 75, 36, 36, 36, 36, 36, 36, 36, 36, 63, 64, 36, 36, 36, 36, + 36, 36, 36, 36, 63, 36, 36, 36, 42, 76, 77, 78, 76, 77, 77, 77, + 77, 76, 77, 77, 78, 42, 42, 42, 60, 60, 2, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 27, 27, 60, 36, 36, 36, 63, 76, 78, 42, 2, + 36, 36, 81, 76, 42, 42, 42, 42, 76, 76, 78, 42, 42, 42, 76, 77, + 77, 78, 42, 42, 42, 42, 42, 42, 2, 2, 2, 79, 2, 2, 2, 2, + 42, 42, 42, 42, 42, 42, 42, 98, 42, 42, 80, 36, 36, 36, 36, 36, + 36, 36, 76, 42, 42, 76, 76, 77, 77, 76, 80, 36, 36, 36, 36, 2, + 88, 60, 60, 60, 60, 46, 42, 42, 42, 42, 60, 60, 60, 60, 21, 2, + 42, 80, 36, 36, 36, 36, 36, 36, 81, 42, 42, 77, 42, 78, 42, 36, + 36, 36, 36, 76, 42, 77, 78, 78, 42, 77, 77, 77, 77, 77, 2, 2, + 36, 36, 77, 77, 77, 77, 42, 42, 42, 42, 77, 42, 42, 56, 2, 2, + 7, 7, 7, 7, 7, 7, 85, 36, 36, 36, 36, 36, 39, 39, 39, 2, + 16, 16, 16, 16, 34, 16, 16, 16, 42, 56, 42, 42, 42, 42, 42, 42, + 76, 42, 42, 42, 64, 36, 63, 36, 36, 36, 64, 81, 42, 36, 36, 36, + 16, 16, 16, 16, 16, 16, 39, 39, 39, 39, 39, 39, 39, 43, 16, 16, + 16, 16, 16, 16, 43, 16, 16, 16, 16, 16, 16, 16, 16, 99, 39, 39, + 32, 32, 32, 16, 16, 16, 16, 32, 16, 16, 16, 16, 11, 11, 11, 11, + 16, 16, 16, 16, 34, 11, 11, 11, 16, 16, 16, 16,100,100,100,100, + 16, 16, 16, 16, 11, 11,101,102, 40, 16, 16, 16, 11, 11,101, 40, + 16, 16, 16, 16, 11, 11,103, 40,104,104,104,104,104,105, 58, 58, + 50, 50, 50, 2,106,107,106,107, 2, 2, 2, 2,108, 58, 58,109, + 2, 2, 2, 2,110,111, 2,112,113, 2,114,115, 2, 2, 2, 2, + 2, 9,113, 2, 2, 2, 2,116, 58, 58, 58, 58, 58, 58, 58, 58, + 117, 39, 27, 27, 27, 8,114,118, 27, 27, 27, 27, 27, 8,114, 93, + 20, 20, 20, 20, 20, 20, 20, 20, 42, 42, 42, 42, 42, 42,119, 47, + 98, 47, 98, 42, 42, 42, 42, 42, 60,120, 60,121, 60, 34, 11, 16, + 11, 32,121, 60, 45, 11, 11, 60, 60, 60,120,120,120, 11, 11,122, + 11, 11, 35, 36,123, 60, 16, 11, 8, 8, 45, 16, 16, 26, 60,124, + 94, 94, 94, 94, 94, 94, 94, 94, 94,125,126, 94,127, 60, 60, 60, + 8, 8,128, 60, 60, 8, 60, 60,128, 26, 60,128, 60, 60, 60,128, + 60, 60, 60, 60, 60, 60, 60, 8, 60,128,128, 60, 60, 60, 60, 60, + 60, 60, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 60, 60, 60, 60, 4, 4, 60, 60, 8, 60, 60, 60,129,130, 60, 60, + 60, 60, 60, 60, 60, 60,128, 60, 60, 60, 60, 60, 60, 26, 8, 8, + 8, 8, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 8, 8, + 8, 60, 60, 60, 60, 60, 60, 60, 27, 27, 27, 27, 27, 27, 60, 60, + 60, 60, 60, 60, 60, 27, 27, 27, 60, 60, 60, 26, 60, 60, 60, 60, + 26, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 8, 8, 8, 8, + 60, 60, 60, 60, 60, 60, 60, 26, 60, 60, 60, 60, 4, 4, 4, 4, + 4, 4, 4, 27, 27, 27, 27, 27, 27, 27, 60, 60, 60, 60, 60, 60, + 8, 8,114,131, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, + 8,114,132,132,132,132,132,132,132,132,132,132,131, 8, 8, 8, + 8, 8, 8, 8, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, + 8, 8,128, 26, 8, 8,128, 60, 32, 11, 32, 34, 34, 34, 34, 11, + 32, 32, 34, 16, 16, 16, 39, 11, 32, 32,124, 60, 60,121, 34,133, + 42, 32, 16, 16, 49, 2, 89, 2, 36, 36, 36, 36, 36, 36, 36, 75, + 2, 2, 2, 2, 2, 2, 2, 55, 2,106,106, 2,110,111,106, 2, + 2, 2, 2, 6, 2, 97,106, 2,106, 4, 4, 4, 4, 2, 2, 79, + 2, 2, 2, 2, 2, 50, 2, 2, 97,134, 2, 2, 2, 2, 2, 2, + 60, 2,135,132,132,132,136, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 1, 2,137,138, 4, 4, 4, 4, 4, 60, 4, 4, 4, 4,139, 93, + 140, 94, 94, 94, 94, 42, 42, 77,141, 39, 39, 60, 94,142, 57, 60, + 71, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 63,143,144, 62, + 36, 36, 36, 36, 36, 57, 39, 62, 60, 27, 27, 60, 60, 60, 60, 60, + 27, 27, 27, 27, 27, 60, 60, 60, 60, 60, 60, 60, 27, 27, 27, 27, + 145, 27, 27, 27, 27, 27, 27, 27, 36, 36, 75, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36,146, 2, 32, 32, 32, 32, 32, 32, 32, 63, + 47,147, 42, 42, 42, 42, 42, 79, 32, 32, 32, 32, 32, 32, 39, 42, + 36, 36, 36, 94, 94, 94, 94, 94, 42, 2, 2, 2, 2, 2, 2, 2, + 40, 40, 40,144, 39, 39, 39, 39, 40, 32, 32, 32, 32, 32, 32, 32, + 16, 32, 32, 32, 32, 32, 32, 32, 43, 16, 16, 16, 34, 34, 34, 32, + 32, 32, 32, 32, 41,148, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 11, 11, 32, 11, 11, 32, 32, 32, 32, 32, 32, + 32, 32, 11, 11, 34, 34, 32, 32, 32, 32, 32, 32, 32, 32, 11, 11, + 48, 39,149, 35, 39, 35, 36, 36, 36, 64, 36, 64, 36, 63, 36, 36, + 36, 81, 78, 76, 60, 60, 42, 42, 27, 27, 27, 60,150, 60, 60, 60, + 36, 36, 2, 2, 2, 2, 2, 2, 77, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 77, 77, 77, 77, 77, 77, 77, 77, 42, 42, 42, 42, 42, 2, + 42, 36, 36, 36, 2, 65, 65, 63, 36, 36, 36, 42, 42, 42, 42, 2, + 36, 36, 36, 63, 42, 42, 42, 42, 42, 77, 77, 77, 77, 77, 77, 96, + 36, 63, 77, 42, 42, 77, 42, 77, 96, 2, 2, 2, 2, 2, 2, 79, + 7, 7, 7, 7, 7, 7, 7, 2, 36, 36, 63, 62, 36, 36, 36, 36, + 36, 36, 36, 36, 63, 42, 42, 76, 78, 76, 78, 42, 42, 42, 42, 42, + 36, 63, 36, 36, 36, 36, 76, 77, 7, 7, 7, 7, 7, 7, 2, 2, + 62, 36, 36, 70, 60, 81, 76, 36, 64, 42, 64, 63, 64, 36, 36, 42, + 36, 36, 36, 36, 36, 36, 75, 2, 36, 36, 36, 36, 36, 81, 42, 77, + 2, 75,151, 42, 42, 42, 42, 42, 16, 16, 16, 16, 16,102, 39, 39, + 16, 16, 16, 16, 99, 40, 40, 40, 36, 81, 78, 77, 76, 96, 78, 42, + 152,152,152,152,152,152,152,152,153,153,153,153,153,153,153,153, + 16, 16, 16, 16, 16, 16, 35, 64, 36, 36, 36, 36,154, 36, 36, 36, + 36, 40, 40, 40, 40, 40, 40, 40, 40, 22, 60, 60, 60, 60, 60, 60, + 60, 71, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,132, + 60, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 60, 60, 60, 60, + 36, 36, 36, 36, 36, 36,150, 60, 2, 2, 2,135,115, 2, 2, 2, + 6,155,156,132,132,132,132,132,132,132,115,135,115, 2,112,157, + 2, 2, 2, 2,139,132,132,115, 2,158, 8, 8, 59, 2, 2, 2, + 36, 36, 36, 36, 36, 36, 36,159, 2, 2, 3, 2, 4, 5, 6, 2, + 16, 16, 16, 16, 16, 17, 18,114,115, 4, 2, 36, 36, 36, 36, 36, + 62, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 39, + 20,160, 52, 20, 26, 8,128, 60, 60, 60, 60, 60,161, 58, 60, 60, + 2, 2, 2, 89, 27, 27, 27, 27, 27, 27, 27, 83, 60, 60, 60, 60, + 94, 94,127, 27, 83, 60, 60, 60, 60, 60, 60, 60, 60, 27, 60, 60, + 60, 60, 60, 60, 60, 60, 46, 42,162,162,162,162,162,162,162,162, + 163, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 86, 36, + 138, 36, 36, 36, 36, 94, 94, 94, 36, 36, 36, 36, 36, 36, 36, 57, + 164, 94, 94, 94, 94, 94, 94, 94, 11, 11, 11, 32, 16, 16, 16, 16, + 36, 36, 36, 57, 27, 27, 27, 27, 36, 36, 36, 70,145, 27, 27, 27, + 36, 36, 36,165, 27, 27, 27, 27, 36, 36, 36, 36, 36,165, 27, 27, + 36, 36, 36, 27, 27, 27, 27, 30, 36, 36, 36, 36, 36, 36, 27, 36, + 63, 42, 42, 42, 42, 42, 42, 42, 36, 36, 36, 36, 42, 42, 42, 42, + 36, 36, 36, 36, 36, 36,165, 30, 36, 36, 36, 36, 36, 36,165, 27, + 36, 36, 36, 36, 71, 36, 36, 36, 36, 36, 63, 42, 42,163, 27, 27, + 36, 36, 36, 36, 57, 2, 2, 2, 36, 36, 36, 36, 27, 27, 27, 27, + 16, 16, 16, 16, 16, 27, 27, 27, 36, 36, 42, 42, 42, 42, 42, 42, + 7, 7, 7, 7, 7, 36, 36, 62, 11, 11, 11, 11,166, 42, 42,141, + 16, 16, 16, 16, 16, 16, 16, 8, 36, 36, 36, 36, 36, 63,167, 50, + 88, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 42, 42, 42, + 27, 27, 27, 86, 36, 36, 36, 36,163, 27, 30, 2, 2, 2, 2, 2, + 36, 42, 42, 2, 2, 2, 2, 2, 36, 36,165, 27, 27, 27, 27, 27, + 78, 80, 36, 36, 36, 36, 36, 36, 42, 42, 42, 56, 2, 2, 2, 2, + 2, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 7, 7, 7, 7, 7, + 64, 63, 64, 36, 36, 36, 36, 63, 77, 78, 42, 76, 78, 56, 72, 2, + 2, 42, 42, 42, 42, 42, 66, 58, 36, 36, 36, 63, 42, 42, 78, 42, + 42, 42, 42, 7, 7, 7, 7, 7, 2, 2, 81, 80, 36, 36, 36, 36, + 36, 63, 2, 36, 36, 36, 36, 36, 36, 81, 77, 42, 42, 42, 42, 76, + 80, 36, 57, 2, 55, 42, 56, 78, 7, 7, 7, 7, 7, 57, 57, 2, + 89, 27, 27, 27, 27, 27, 27, 27, 36, 36, 36, 36, 36, 36, 77, 78, + 42, 77, 76, 42, 2, 2, 2, 64, 36, 36, 36, 36, 36, 36, 36, 63, + 76, 77, 77, 77, 77, 77, 77, 77, 36, 36, 36, 81, 77, 77, 80, 36, + 36, 77, 77, 42, 42, 42, 42, 42, 36, 36, 36, 36, 77, 78, 42, 42, + 42, 77, 77, 77, 77, 77, 77, 76, 64, 64, 2, 2, 2, 2, 2, 2, + 55, 42, 42, 42, 42, 42, 42, 42, 36, 36, 81, 77, 42, 42, 42, 42, + 77, 42, 76, 64, 36, 57, 2, 2, 7, 7, 7, 7, 7, 2, 2, 64, + 77, 78, 42, 42, 76, 76, 77, 78, 76, 42, 36, 65, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 81, 77, 42, 42, 42, 77, 77, 42, 78, + 56, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 42, 42, + 77, 78, 42, 42, 42, 76, 78, 78, 56, 2, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 63, 78, 77, 42, 42, 42, 78, 57, 2, 2, 2, + 36, 36, 36, 36, 36, 36, 63, 78, 77, 42, 42, 78, 42, 42, 42, 42, + 7, 7, 7, 7, 7, 27, 2, 88, 42, 42, 42, 42, 78, 56, 2, 2, + 27, 27, 27, 27, 27, 27, 27, 86, 77, 77, 77, 77, 77, 78, 76, 64, + 80, 78, 2, 2, 2, 2, 2, 2, 81, 77, 42, 42, 42, 42, 77, 77, + 64, 65, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 63, 42, 42, 42, 42, 64, 36, 36, 36, 63, 42, 42, 76, 63, 42, 56, + 2, 2, 2, 55, 42, 42, 42, 42, 63, 42, 42, 76, 78, 42, 36, 36, + 36, 36, 36, 36, 36, 42, 42, 42, 42, 42, 42, 76, 42, 2, 65, 2, + 76, 42, 76, 76, 77, 77, 77, 77, 57, 2, 2, 2, 2, 2, 2, 2, + 42, 42, 42, 42, 42, 42, 42, 78, 2, 36, 36, 36, 36, 36, 36, 36, + 42, 42, 42, 42, 76, 42, 42, 42, 76, 42, 78, 42, 42, 42, 42, 42, + 42, 42, 42, 63, 42, 42, 42, 42, 36, 36, 36, 36, 36, 77, 77, 77, + 42, 76, 78, 78, 36, 36, 36, 36, 36, 36, 36, 36, 75, 36, 36, 36, + 36, 63, 76, 96, 2, 2, 2, 2, 42, 81, 36, 36, 36, 36, 36, 36, + 36, 36, 77, 42, 42, 42, 42, 77, 76, 56, 2, 2, 2, 2, 2, 2, + 7, 7, 7, 7, 7, 42, 42, 42, 27, 27, 83, 60, 60, 60, 52, 20, + 150, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 21, + 64, 36, 36, 63, 42, 42, 42, 42, 36, 36, 36, 36, 36, 36, 36, 42, + 42, 42, 42, 42, 42, 77, 78, 42, 42, 42, 56, 2, 2, 2, 2, 2, + 42, 42, 42, 56, 2, 2, 60, 60, 39, 39, 88, 60, 60, 60, 60, 60, + 7, 7, 7, 7, 7,168, 27, 27, 27, 86, 36, 36, 36, 36, 36, 36, + 39, 62, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 75,146, 2, + 27, 27, 27, 30, 2, 2, 2, 2, 11, 11, 11, 11, 11, 32, 16, 16, + 81, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 78, + 42, 67, 39, 39, 39, 39, 39, 39, 39, 79, 42, 42, 42, 42, 42, 42, + 77, 39, 94, 94, 94, 94, 94, 94, 36, 36, 36, 36, 36, 36, 46, 56, + 7, 7, 7, 7, 7, 60, 60, 60, 60, 60,169, 78, 42, 60,169, 77, + 77,170, 58, 58, 58, 74, 42, 42, 42, 69, 46, 42, 42, 42, 60, 60, + 60, 60, 60, 60, 60, 42, 42, 60, 60, 42, 69, 60, 60, 60, 60, 60, + 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 16, 11, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, + 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, + 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, + 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, + 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 32, 16, 7, + 42, 42, 42, 69, 60, 46, 42, 42, 42, 42, 42, 42, 42, 42, 69, 60, + 60, 60, 46, 60, 60, 60, 60, 60, 60, 60, 69, 21, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 55, 42, 42, 16, 16, 16, 16, 16,123, 16, 16, + 42, 42, 42, 67, 39, 39, 39, 39, 7, 7, 7, 7, 7, 7, 7, 70, + 36, 36, 36, 36, 36, 36, 42, 42, 7, 7, 7, 7, 7, 7, 7,171, + 36, 36, 36, 36, 36, 75, 42, 42,172, 7, 7, 7, 7, 7, 7, 84, + 36, 63, 36, 64, 36, 36, 36, 42, 36, 36, 63, 42, 42, 42, 42, 75, + 16, 16, 42, 42, 42, 67, 39, 39, 27, 27, 27, 27, 27, 27,145, 27, + 173, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,145, + 27, 27, 27, 27, 27, 27, 83, 60, 60, 60, 60, 60, 60, 25, 40, 40, + 0, 0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13, + 25, 25, 25, 21, 21, 9, 9, 9, 9, 22, 21, 18, 24, 16, 24, 5, + 5, 5, 5, 22, 25, 18, 25, 0, 23, 23, 26, 21, 24, 26, 7, 20, + 25, 1, 26, 24, 26, 25, 15, 15, 24, 15, 7, 19, 15, 21, 9, 25, + 9, 5, 5, 25, 5, 9, 5, 7, 7, 7, 9, 8, 8, 5, 6, 6, + 24, 24, 6, 24, 12, 12, 6, 5, 9, 21, 25, 9, 26, 12, 11, 11, + 9, 6, 5, 21, 17, 17, 17, 26, 26, 23, 23, 12, 17, 12, 21, 12, + 12, 21, 7, 21, 1, 1, 21, 23, 26, 26, 1, 21, 6, 7, 7, 12, + 12, 7, 21, 7, 12, 1, 12, 6, 6, 12, 12, 26, 7, 26, 26, 7, + 21, 1, 24, 7, 1, 12, 7, 6, 12, 10, 10, 10, 10, 12, 21, 6, + 10, 7, 7, 10, 23, 7, 15, 26, 13, 21, 13, 7, 15, 7, 12, 23, + 21, 26, 21, 15, 17, 7, 29, 7, 7, 22, 18, 18, 14, 14, 14, 7, + 10, 21, 17, 21, 11, 12, 5, 6, 8, 8, 8, 24, 5, 24, 9, 24, + 29, 29, 29, 1, 20, 19, 22, 20, 27, 28, 1, 29, 21, 20, 19, 21, + 21, 16, 16, 21, 25, 22, 18, 21, 21, 29, 15, 6, 18, 6, 12, 11, + 9, 26, 26, 9, 26, 5, 7, 5, 5, 26, 14, 9, 5, 14, 14, 15, + 25, 26, 26, 22, 18, 26, 18, 25, 18, 22, 5, 12, 22, 21, 21, 22, + 18, 17, 26, 6, 7, 14, 17, 22, 26, 14, 17, 6, 14, 6, 12, 24, + 24, 6, 26, 15, 6, 21, 11, 21, 24, 9, 6, 9, 23, 26, 6, 10, + 4, 4, 3, 3, 7, 25, 17, 16, 16, 22, 16, 16, 25, 17, 7, 1, + 25, 24, 26, 1, 2, 2, 12, 15, 21, 14, 7, 15, 9, 12, 12, 17, + 13, 15, 26, 10, 10, 1, 13, 23, 7, 13, 23, 15, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, 13, 0, 14, 0, 0, 0, + 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, + 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 21, 22, 23, 0, 0, + 0, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, + 0, 36, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, 42, 43, 44, + 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, + 0, 0, 0, 0, 3, 0, 0, 0, 4, 5, 6, 7, 0, 8, 9, 10, + 0, 11, 12, 13, 14, 15, 16, 17, 16, 18, 16, 19, 16, 19, 16, 19, + 0, 19, 16, 20, 16, 19, 21, 19, 0, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, + 0, 0, 0, 0, 0, 0, 34, 0, 0, 35, 0, 0, 36, 0, 37, 0, + 0, 0, 38, 39, 40, 41, 42, 43, 44, 45, 46, 0, 0, 47, 0, 0, + 0, 48, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 50, 0, 51, + 0, 52, 53, 0, 54, 0, 0, 0, 0, 0, 0, 55, 56, 57, 0, 0, + 0, 0, 58, 0, 0, 59, 60, 61, 62, 63, 0, 0, 64, 65, 0, 0, + 0, 66, 0, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 70, 0, 71, + 0, 0, 72, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, 74, 75, + 0, 0, 0, 0, 76, 77, 0, 78, 79, 0, 0, 80, 81, 0, 82, 62, + 0, 83, 84, 0, 0, 85, 86, 87, 0, 88, 0, 89, 0, 90, 0, 0, + 51, 91, 51, 0, 92, 0, 93, 0, 0, 0, 81, 0, 0, 0, 94, 95, + 0, 96, 97, 98, 99, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0,100, + 101, 0, 0, 0, 0, 0, 0,102, 0, 0, 0, 0, 0, 0,103, 0, + 0, 0, 0, 0, 0,104,105, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,106, 0, 0,107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,108, + 109, 0, 0,110, 0, 0, 0, 0, 0, 0,111, 0,112, 0,105, 0, + 0, 0, 0, 0,113,114, 0, 0, 0, 0, 0, 0, 0,115, 0, 0, + 0,116, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, 0,118, 0,119, + 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, 8, 0, + 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, 0, 13, 0, 0, 14, 15, + 0, 16, 0, 17, 18, 0, 0, 19, 0, 20, 21, 0, 0, 0, 0, 0, + 22, 23, 0, 24, 25, 0, 0, 26, 0, 0, 0, 27, 0, 0, 28, 29, + 30, 31, 0, 0, 0, 32, 33, 34, 0, 0, 33, 0, 0, 35, 33, 0, + 0, 0, 33, 36, 0, 0, 0, 0, 0, 37, 38, 0, 0, 0, 0, 0, + 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, 43, + 0, 44, 0, 0, 0, 45, 46, 0, 0, 0, 47, 0, 0, 0, 0, 0, + 0, 48, 49, 0, 0, 0, 0, 50, 0, 0, 0, 51, 0, 52, 0, 53, + 0, 0, 0, 0, 54, 0, 0, 0, 0, 55, 0, 56, 0, 0, 0, 0, + 57, 58, 0, 0, 0, 59, 60, 61, 62, 0, 0, 0, 0, 63, 52, 0, + 64, 65, 0, 0, 66, 0, 0, 0, 67, 68, 0, 0, 0, 69, 0, 70, + 71, 72, 73, 74, 1, 75, 0, 76, 77, 78, 0, 0, 79, 80, 0, 0, + 0, 81, 0, 0, 1, 1, 0, 0, 82, 0, 0, 83, 0, 0, 0, 0, + 79, 84, 0, 85, 0, 0, 0, 0, 0, 80, 86, 0, 87, 0, 52, 0, + 1, 80, 0, 0, 88, 0, 0, 89, 0, 0, 0, 0, 0, 90, 57, 0, + 0, 0, 0, 0, 0, 91, 92, 0, 0, 86, 0, 0, 33, 0, 0, 93, + 0, 0, 0, 0, 94, 0, 0, 0, 0, 49, 0, 0, 95, 0, 0, 0, + 0, 96, 97, 0, 0, 98, 0, 0, 99, 0, 0, 0,100, 0, 0, 0, + 101, 0, 0, 0,102, 0, 0, 0, 0,103,104, 95, 0, 0,105, 0, + 0, 0, 86, 0, 0,106, 0, 0, 0,107,108, 0, 0,109,110, 0, + 0, 0, 0, 0, 0,111, 0, 0,112, 0, 0, 0, 0,113, 33, 0, + 114,115,116, 57, 0, 0,117, 35, 0, 0,118, 0, 0, 0,119, 0, + 0, 0, 0, 0, 0,120, 0, 0,121, 0, 0, 0, 0,122, 90, 0, + 0, 0, 0, 0, 57, 0, 0, 0, 0, 52,123, 0, 0, 0, 0,124, + 0, 0,125, 0, 0, 0, 0,123, 0, 0,126, 0, 0, 0, 0, 0, + 81, 0, 0, 0, 0,127, 0, 0, 0,128, 0, 0, 0,129, 0,130, + 0, 0, 0, 0,131,132,133, 0,134, 0,135, 0, 0, 0,136,137, + 138, 0, 79, 0, 0, 0, 0, 0, 35, 0, 0, 0,139, 0, 0, 0, + 140, 0, 0, 0,141, 0, 0, 0,142,143, 0,144, 0, 0,145, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, + 7, 4, 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, 18, 1, + 1, 1, 19, 1, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, 25, 26, + 27, 28, 29, 30, 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, 34, 35, + 1, 36, 37, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, 42, 0, + 0, 0, 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, 21, 0, + 0, 47, 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, 0, 19, + 52, 1, 0, 0, 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, 54, 21, + 35, 1, 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, 0, 0, + 0, 59, 0, 60, 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, 0, 0, + 64, 0, 0, 0, 65, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, + 68, 0, 0, 69, 70, 0, 71, 72, 73, 74, 75, 76, 0, 0, 0, 77, + 0, 0, 0, 78, 79, 0, 0, 0, 0, 47, 0, 0, 0, 49, 0, 80, + 0, 0, 0, 62, 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, 0, 0, + 83, 0, 0, 19, 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, 1, 52, + 15, 86, 36, 10, 21, 1, 1, 1, 1, 41, 1, 21, 87, 0, 0, 55, + 0, 0, 0, 0, 19, 10, 1, 0, 0, 0, 0, 0, 88, 0, 0, 89, + 0, 0, 88, 0, 0, 0, 0, 78, 0, 0, 90, 9, 12, 4, 91, 8, + 92, 47, 0, 58, 50, 0, 21, 1, 21, 93, 94, 1, 1, 1, 1, 95, + 96, 97, 98, 1, 99, 58, 81,100,101, 4, 58, 0, 0, 0, 0, 0, + 0, 19, 50, 0, 0, 0, 0, 0, 0, 61, 0, 0,102,103, 0, 0, + 104, 0, 0, 1, 1, 50, 0, 0, 0, 38, 0, 63, 0, 0, 0, 0, + 0, 62, 0, 0,105, 68, 61, 0, 0, 0, 78, 0, 0, 0,106,107, + 58, 38, 81, 0, 0, 0, 0, 0, 0,108, 1, 14, 4, 12, 84, 0, + 0, 0, 0, 38, 90, 0, 0, 0, 0,109, 0, 0,110, 61, 0,111, + 0, 0, 0, 1, 0, 0, 0, 0, 49, 50, 0, 0, 19, 58, 0, 0, + 112, 51, 0,112, 14, 52,113, 41, 0, 0, 62, 0, 0, 61, 0, 0, + 114, 0, 90, 0, 0, 0, 61, 62, 0, 0, 62, 0, 89, 0, 0,114, + 0, 0, 0, 0,115, 0, 0, 0, 78, 55, 0, 38, 1, 58, 1, 58, + 0, 0, 0, 0, 0, 88, 63, 89, 0, 0,116, 0, 0, 0, 55, 0, + 0, 0, 0,116, 0, 0, 0, 0, 61, 0, 0, 0, 0, 79, 0, 61, + 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, 79, 0, 0, 0, 8, 92, + 0, 0, 1, 90, 0, 0,117, 0, 0, 0, 0, 0, 0,118, 0,119, + 120,121,122, 0,105, 4,123, 49, 23, 0, 0, 0, 38, 50, 38, 58, + 0, 0, 1, 90, 1, 1, 1, 1, 39, 1, 48,106, 90, 0, 0, 0, + 0, 1, 0, 0, 0,124, 0, 0, 0,113, 19, 59, 0, 38, 0, 81, + 0, 0, 4,123, 0, 0, 0, 1,125, 0, 0, 0, 0, 0,230,230, + 230,230,230,232,220,220,220,220,232,216,220,220,220,220,220,202, + 202,220,220,220,220,202,202,220,220,220, 1, 1, 1, 1, 1,220, + 220,220,220,230,230,230,230,240,230,220,220,220,230,230,230,220, + 220, 0,230,230,230,220,220,220,220,230,232,220,220,230,233,234, + 234,233,234,234,233,230, 0, 0, 0,230, 0,220,230,230,230,230, + 220,230,230,230,222,220,230,230,220,220,230,222,228,230, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, + 25, 0,230,220, 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, 28, 29, + 30, 31, 32, 33, 34,230,230,220,220,230,220,230,230,220, 35, 0, + 0, 0, 0, 0,230,230,230, 0, 0,230,230, 0,220,230,230,220, + 0, 0, 0, 36, 0, 0,230,220,230,230,220,220,230,220,220,230, + 220,230,220,230,230, 0, 0,220, 0, 0,230,230, 0,230, 0,230, + 230,230,230,230, 0, 0, 0,220,220,220,230,220,220,220,230,230, + 0,220, 27, 28, 29,230, 7, 0, 0, 0, 0, 9, 0, 0, 0,230, + 220,230,230, 0, 0, 0, 0, 0,230, 0, 0, 84, 91, 0, 0, 0, + 0, 9, 9, 0, 0, 0, 0, 0, 9, 0,103,103, 9, 0,107,107, + 107,107,118,118, 9, 0,122,122,122,122,220,220, 0, 0, 0,220, + 0,220, 0,216, 0, 0, 0,129,130, 0,132, 0, 0, 0, 0, 0, + 130,130,130,130, 0, 0,130, 0,230,230, 9, 0,230,230, 0, 0, + 220, 0, 0, 0, 0, 7, 0, 9, 9, 0, 9, 9, 0, 0, 0,230, + 0, 0, 0,228, 0, 0, 0,222,230,220,220, 0, 0, 0,230, 0, + 0,220,230,220, 0,220,230,230,230,234, 0, 0, 9, 9, 0, 0, + 7, 0,230,230,230, 0,230, 0, 1, 1, 1, 0, 0, 0,230,234, + 214,220,202,230,230,230,230,230,232,228,228,220,218,230,233,220, + 230,220,230,230, 1, 1, 1, 1, 1,230, 0, 1, 1,230,220,230, + 1, 1, 0, 0,218,228,232,222,224,224, 0, 8, 8, 0, 0, 0, + 0,220,230, 0,230,230,220, 0, 0,230, 0, 0, 26, 0, 0,220, + 0,230,230, 1,220, 0, 0,230,220, 0, 0, 0,220,220, 0, 0, + 230,220, 0, 9, 7, 0, 0, 7, 9, 0, 0, 0, 9, 7, 6, 6, + 0, 0, 0, 0, 1, 0, 0,216,216, 1, 1, 1, 0, 0, 0,226, + 216,216,216,216,216, 0,220,220,220, 0,232,232,220,230,230,230, + 7, 0, 16, 17, 17, 33, 17, 49, 17, 17, 84, 97,135,145, 26, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17,177, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 5, 3, 3, 3, + 3, 3, 6, 7, 8, 3, 3, 3, 3, 3, 9, 10, 11, 12, 13, 3, + 3, 3, 3, 3, 3, 3, 3, 14, 3, 15, 3, 3, 3, 3, 3, 3, + 16, 17, 18, 19, 20, 21, 3, 3, 3, 22, 23, 24, 3, 3, 3, 3, + 3, 3, 25, 3, 3, 3, 3, 3, 3, 3, 3, 26, 3, 3, 27, 28, + 0, 1, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 4, 0, 5, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, + 0, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 0, + 0, 14, 15, 16, 6, 0, 17, 18, 19, 19, 19, 20, 21, 22, 23, 24, + 19, 25, 0, 26, 27, 19, 19, 28, 29, 30, 0, 31, 0, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 19, 28, 0, 32, 33, 9, 34, 35, 19, + 0, 0, 36, 37, 38, 39, 40, 19, 0, 41, 42, 43, 44, 31, 0, 1, + 45, 42, 0, 0, 0, 0, 0, 32, 14, 14, 0, 0, 0, 0, 14, 0, + 0, 46, 47, 47, 47, 47, 48, 49, 47, 47, 47, 47, 50, 51, 52, 53, + 43, 21, 0, 0, 0, 0, 0, 0, 0, 54, 6, 55, 0, 14, 19, 1, + 0, 0, 0, 0, 56, 57, 0, 0, 0, 0, 0, 19, 58, 31, 0, 0, + 0, 0, 0, 0, 0, 59, 14, 0, 0, 0, 0, 1, 0, 2, 0, 0, + 0, 3, 0, 0, 0, 60, 61, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 2, 3, 0, 4, 5, 0, 0, 6, 0, 0, 0, 7, + 0, 0, 0, 1, 1, 0, 0, 8, 9, 0, 8, 9, 0, 0, 0, 0, + 8, 9, 10, 11, 12, 0, 0, 0, 13, 0, 0, 0, 0, 14, 15, 16, + 17, 0, 0, 0, 1, 0, 0, 18, 19, 0, 0, 0, 20, 0, 0, 0, + 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 8, 21, 9, + 0, 0, 22, 0, 0, 0, 0, 1, 0, 23, 24, 25, 0, 0, 26, 0, + 0, 0, 8, 21, 27, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 28, + 29, 30, 0, 31, 32, 20, 1, 1, 0, 0, 0, 8, 21, 9, 1, 4, + 5, 0, 0, 0, 33, 9, 0, 1, 1, 1, 0, 8, 21, 21, 21, 21, + 34, 1, 35, 21, 21, 21, 9, 36, 0, 0, 37, 38, 1, 0, 39, 0, + 0, 0, 1, 0, 1, 0, 0, 0, 0, 8, 21, 9, 1, 0, 0, 0, + 40, 0, 8, 21, 21, 21, 21, 21, 21, 21, 21, 9, 0, 1, 1, 1, + 1, 8, 21, 21, 21, 9, 0, 0, 0, 41, 0, 42, 43, 0, 0, 0, + 1, 44, 0, 0, 0, 45, 8, 9, 1, 0, 0, 0, 8, 21, 21, 21, + 9, 0, 1, 0, 1, 1, 8, 21, 21, 9, 0, 4, 5, 8, 9, 1, + 0, 0, 16, 50, 84,118,136,152,186,187,187,187,187,187,187,187, + 187,187,187,187,187,187,187,187,187,187,187,187,187,187, 12, 0, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 13, 13, 13, + 13, 13, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 15, 16, 17, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 19, 32, 33, 33, 33, 33, 33, + 34, 19, 19, 19, 19, 19, 19, 35, 19, 36, 37, 38, 38, 38, 38, 38, + 38, 39, 40, 19, 19, 19, 19, 19, 19, 19, 41, 42, 19, 19, 43, 19, + 19, 19, 44, 45, 9, 46, 47, 48, 49, 50, 51, 52, 9, 9, 19, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 53, 19, 19, 53, 19, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 54, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 55, + 0, 0, 1, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 0, + 1, 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 32, 33, 33, 33, 34, 35, 35, 35, 35, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 2, 2, 51, 51, 52, + 53, 54, 55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57, + 57, 56, 56, 56, 56, 56, 56, 58, 59, 60, 61, 56, 62, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 56, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 71, 62, 62, 62, 62, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 73, 74, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 32, + 32, 32, 32, 32, 32, 32, 32, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 62, 62, 62, 62, 88, 89, 89, 89, 90, 89, 91, 92, 93, 94, 95, + 95, 96, 97, 87, 98, 99,100,101,102,103,104,105,105,105, 2,106, + 107,108,109,110,111,112,113,114,115,116,117, 89,118,119,120,121, + 122,123,124,125,126,127,128,129,130, 87,131,132,133,134, 87,135, + 136,137,138,139,140,141,142,143,144,145,146, 87,147,148,149,150, + 150,150,150,150,150,150,150,150,150,150, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87,151,152,152,152,152,152,152,152,152,153, + 153,153,153,153, 87, 87, 87, 87, 87,154, 87, 87, 87, 87, 87,155, + 155,155,155,156,157,158,158, 87, 87,159, 87,160,161,162,163,164, + 164,164,164,164,164,164,164,164,164,164,164,164,164,165,165,165, + 165,164,164, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,166,167, + 168,169,170,170,170, 87, 87,171,172, 87, 87, 87, 87, 87, 87, 56, + 56, 56, 56, 56, 56,173, 56, 56, 56,174,175, 51, 56, 56, 87,176, + 176,176,176,176,176, 87, 87, 87, 87, 87, 87, 87, 87, 2, 87,177, + 6,178, 87, 87,179, 87, 87, 87,180, 87,181, 87,182, 87, 33,183, + 183,184, 87, 87, 87, 87, 87, 56, 56, 56, 87, 89, 89, 87, 87, 56, + 56, 56, 56,185, 87, 56, 56, 62, 62, 62, 62, 62, 87, 87, 87, 62, + 87, 87, 87, 87, 87, 87, 87, 56, 87,186,186, 0, 1, 2, 2, 0, + 0, 0, 0, 1, 2, 1, 2, 0, 0, 3, 3, 4, 5, 4, 5, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 0, 0, 7, 0, 8, + 8, 8, 8, 8, 8, 8, 9, 10, 11, 11, 11, 11, 11, 12, 11, 13, + 13, 13, 13, 13, 13, 13, 13, 14, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 15, 16, 16, 16, 16, 16, 17, 18, 18, 18, 18, 18, 18, 19, + 20, 21, 21, 22, 23, 21, 24, 21, 21, 21, 21, 21, 25, 21, 21, 26, + 26, 26, 26, 26, 21, 21, 21, 27, 27, 27, 27, 28, 28, 28, 28, 29, + 29, 29, 29, 30, 30, 26, 21, 21, 21, 21, 21, 21, 21, 31, 21, 32, + 32, 32, 32, 32, 33, 34, 32, 35, 35, 35, 35, 35, 35, 35, 35, 36, + 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 38, + 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 40, + 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 42, + 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 44, + 44, 44, 45, 44, 44, 44, 44, 46, 46, 46, 46, 46, 46, 46, 46, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 47, 47, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 50, 50, 50, 50, 50, 51, 52, + 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 55, 55, 55, 56, + 56, 57, 57, 57, 57, 58, 57, 59, 59, 60, 61, 62, 62, 63, 63, 64, + 64, 64, 64, 64, 64, 64, 64, 65, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 55, 55, 55, 55, 55, 67, 67, 67, 67, 67, 68, 68, 68, 69, + 69, 69, 69, 69, 69, 64, 64, 70, 70, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 8, 8, 8, 8, 8, 72, 72, 72, 72, 72, 72, 72, 72, 73, + 73, 73, 73, 74, 74, 74, 74, 75, 75, 75, 75, 75, 76, 76, 76, 13, + 50, 50, 50, 73, 77, 78, 79, 4, 4, 80, 4, 4, 81, 82, 83, 4, + 4, 4, 84, 8, 8, 8, 8, 11, 11, 11, 11, 11, 11, 11, 11, 85, + 0, 0, 0, 0, 0, 0, 86, 0, 4, 0, 0, 0, 8, 8, 8, 0, + 0, 87, 88, 89, 0, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 90, 90, 90, 90, 90, 90, 90, 90, 91, + 91, 91, 91, 91, 91, 4, 4, 92, 92, 92, 92, 92, 92, 92, 92, 50, + 50, 50, 93, 93, 93, 93, 93, 53, 53, 53, 53, 53, 53, 13, 13, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 0, 95, + 0, 96, 97, 98, 99, 99, 99, 99,100,101,102,102,102,102,103,104, + 104,104,105, 52, 52, 52, 52, 52, 0,104,104, 0, 0, 0,102, 52, + 52, 0, 0, 0, 0, 52,106, 0, 0, 0, 0, 0,102,102,107,102, + 102,102,102,102,108, 0, 0, 94, 94, 94, 94, 0, 0, 0, 0,109, + 109,109,109,109,109,109,109,109,109,109,109,109,110,110,110,111, + 111,111,111,111,111,111,111,111,111,111,111, 13, 13, 13, 13, 13, + 13,112,112,112,112,112,112, 0, 0,113, 4, 4, 4, 4, 4,114, + 4, 4, 4, 4, 4, 4, 4,115,115,115, 0,116,116,116,116,117, + 117,117,117,117,117, 32, 32,118,118,119,120,120,120, 52, 52,121, + 121,121,121,122,121, 49, 49,123,123,123,123,123,123, 49, 49,124, + 124,124,124,124,124,125,125, 53, 53, 53, 4, 4,126,127, 54, 54, + 54, 54, 54,125,125,125,125,128,128,128,128,128,128,128,128, 4, + 129, 18, 18, 18, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21,130, 21, 21, 21, 21, 8, 0,131, 0, 0, 0, 0, 21, 21, + 21, 21, 21, 21, 21, 21,132, 0, 0, 1, 2, 1, 2,133,101,102, + 134, 52, 52, 52, 52, 0, 0,135,135,135,135,135,135,135,135, 0, + 0, 0, 0, 11, 11, 11, 11, 11, 0, 11, 11, 11, 0, 0,136,137, + 137,138,138,138,138,139, 0,140,140,140,141,141,142,142,142,143, + 143,144,144,144,144,144,144,145,145,145,145,145,146,146,146,147, + 147,147,148,148,148,148,148,149,149,149,150,150,150,150,151,151, + 151,151,151,152,152,152,152,153,153,153,153,153,153,153,153,154, + 154,154,154,155,155,156,156,157,157,157,157,157,157,158,158,159, + 159,160,160,161,161,161,161,162,162,163,163,163,163,163,163,164, + 164,164,164,164,164,165,165,166,166,166,166,167,167,167,167,168, + 168,168,168,169,169,170,170,171,171,171,171,171,171,171,171,172, + 172,172,172,172,172,172,172,173,173,173,173,173,173,173,173,174, + 174,174,174,175,175,175,175,175,175,175,175,175,175,175,175,176, + 176,176,176,177, 21, 21, 21,178,178,178,179,179,179,179,180,180, + 180,180,181,181,181,182,182,183,183,183,183,183,183,183,183,184, + 184,184,184,184,185,185,185,186,186,186,186,186,187,187,187,188, + 188,188,188,188,188,189, 43,190,190,190,190,190,190,190,190,191, + 191,191,192,192,192,192,192,193,193,193,194,193,193,193,193,195, + 195,195,195,195,195,195,195,196,196,196,196,196,196,196,196,197, + 197,197,197,197,197,197,197,198,198,198,198,198,198,198,198,199, + 199,199,199,199,199, 66, 66,200,200,200,200,200, 49, 49, 49,201, + 201,201,201,201,201,201,201,202,202,202,202,202,202,202,202,203, + 203,203,203,203,203,203,203,204,204,204,204,204,204,204,204,205, + 205,205,205,205,205,205,205,206,206,206,206,206,207,207,207,207, + 207,207, 55,208,208,208,208, 32, 32, 32, 32, 32, 32,188,188,209, + 209,209,209,209,209,209,209,210,210,210,210,210,210,210,211,211, + 211,211,211,211,211,211,211,212,212,212,212,212,212,213,213,213, + 213,213,214,214,214,214,214,215,215,215,215,215,215,215,215,216, + 216,216,216,216,216,216,216,110,110,110,110, 39, 39, 39, 39,217, + 217,217,217,217,217,217,217,218,218,218,218,218,218,218,218,219, + 219,219,219,219,219,219,219,220,220,220,220,220,220,220,220,221, + 221,221,221,221,221,221,221,112,112,112,112,112,112,112,112,112, + 112,112,112,222,222,222,223,223,223,223,223,223,224,224,224,225, + 225,225,225,225,225,225,225,226,226,226,226,226,226,226,226,227, + 227,227,227,227,227,227,227,227,227,228,228,228,228,228,228,229, + 229,229,229,229,229,229,229,229,229,229,229,229,229,230, 94,231, + 231,231,231,231,231,231,231,232,232,232,232,232,232,232,232,102, + 102,102,102,102,102,102,102,233, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99,102,234, 99,235,102,236,236, + 236,236,236,236,236,236,236,237,237,237,237,237,237,237,237,237, + 237, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 0, 0, 0, 0, + 0, 0, 0, 0, 0,238,239,240, 0,241, 0, 0, 0, 0, 0,242, + 242,242,242,242,242,242,242, 91, 91, 91, 13, 13, 13, 13, 13,243, + 243,243,243,243,243,243,243,244,244,244,244,245,245,245,245,246, + 246,246,246,246,246,246,246,247,247,247,247,247,247,247,247,248, + 248,248,248,248,248,248,248,249,249,249,249,249,249,249,249,250, + 250,250,250,250,250,250,250,251, 0, 0, 0, 0, 0, 0, 0, 8, + 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 1, 2, 2, 2, 2, + 2, 3, 0, 0, 0, 4, 0, 2, 2, 2, 2, 2, 3, 2, 2, 2, + 2, 5, 0, 2, 5, 6, 0, 7, 7, 7, 7, 8, 9, 8, 10, 8, + 11, 8, 8, 8, 8, 8, 8, 12, 13, 13, 13, 14, 14, 14, 14, 14, + 15, 14, 14, 16, 17, 17, 17, 17, 17, 17, 17, 18, 19, 19, 19, 19, + 19, 19, 19, 20, 21, 20, 22, 20, 20, 23, 23, 20, 20, 20, 20, 22, + 20, 24, 7, 7, 25, 20, 20, 26, 20, 20, 20, 20, 20, 20, 21, 27, + 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, + 31, 31, 31, 32, 20, 20, 20, 33, 33, 33, 33, 34, 35, 33, 33, 33, + 36, 33, 33, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39, 40, + 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43, 44, + 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, 46, 47, 48, + 48, 48, 48, 49, 49, 49, 49, 49, 50, 51, 49, 52, 52, 52, 52, 53, + 53, 53, 53, 53, 53, 54, 53, 55, 55, 55, 55, 56, 56, 56, 56, 57, + 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59, 60, 60, 60, 60, 60, + 60, 61, 62, 63, 63, 63, 63, 64, 64, 64, 64, 64, 65, 0, 0, 66, + 66, 66, 66, 67, 67, 67, 67, 68, 68, 68, 68, 69, 70, 71, 71, 71, + 71, 71, 71, 72, 72, 72, 72, 73, 73, 73, 73, 74, 74, 74, 74, 75, + 75, 75, 75, 76, 76, 76, 76, 77, 77, 77, 77, 78, 78, 78, 78, 79, + 79, 79, 79, 80, 80, 80, 80, 81, 81, 81, 81, 82, 7, 7, 7, 83, + 7, 84, 85, 0, 84, 86, 0, 2, 87, 88, 2, 2, 2, 2, 89, 90, + 87, 91, 2, 2, 2, 92, 2, 2, 2, 2, 93, 0, 0, 0, 86, 1, + 0, 0, 94, 0, 95, 96, 0, 4, 0, 0, 0, 0, 0, 0, 4, 97, + 97, 97, 97, 98, 98, 98, 98, 13, 13, 13, 13, 99, 99, 99, 99,100, + 100,100,100, 0,101, 0, 0,102,100,103,104, 0, 0,100, 0,105, + 106,106,106,106,106,106,106,106,106,107,105,108,109,109,109,109, + 109,109,109,109,109,110,108,111,111,111,111,112, 55, 55, 55, 55, + 55, 55,113,109,109,109,110,109,109, 0, 0,114,114,114,114,115, + 115,115,115,116,116,116,116,117,117,117,117, 96, 2, 2, 2, 2, + 2, 94, 2,118,118,118,118,119,119,119,119,120,120,120,120,121, + 121,121,121,121,121,121,122,123,123,123,123,124,124,124,124,124, + 124,124,125,126,126,126,126,127,127,127,127,128,128,128,128, 2, + 2, 3, 2, 2,129,130, 0,131,131,131,131,132, 17, 17, 18, 20, + 20, 20,133, 7, 7, 7,134, 20, 20, 20, 23, 0,135,109,109,109, + 109,109,136,137,137,137,137, 0, 0, 0,138,139,139,139,139,140, + 140,140,140, 84, 0, 0, 0,141,141,141,141,142,142,142,142,143, + 143,143,143,144,144,144,144,145,145,145,145,146,146,146,146,147, + 147,147,147,148,148,148,148,149,149,149,149,150,150,150,150,151, + 151,151,151,152,152,152,152,153,153,153,153,154,154,154,154,155, + 155,155,155,156,156,156,156,157,157,157,157,158,158,158,158,159, + 159,159,159,160,160,160,160,161,161,161,161,162,162,162,162,163, + 163,163,163,164,164,164,164,165,165,165,165,166,166,166,166,167, + 167,167,167,168,168,168,168,169,169,169,169,170,170,170,170,171, + 171,171,171,172,172,172,172,173,173,173,173,174,174,174,174,175, + 175,175,175,176,176,176,176,177,177,177,177,178, 20, 20, 20,179, + 179,179,179,180,180,180,180,181,181,181,181,182,182,182,182,183, + 183,183,183,184,184,184,184,185,185,185,185,186,186,186,186,187, + 187,187,187,188,188,188,188,189,189,189,189,190, 45, 45, 45,191, + 191,191,191,192,192,192,192,193,193,193,193,194,194,194,194,194, + 194,195,194,196,196,196,196,197,197,197,197,198,198,198,198,199, + 199,199,199,200,200,200,200,201,201,201,201,202,202,202,202,203, + 203,203,203,204,204,204,204,205,205,205,205,206,206,206,206,207, + 207,207,207,208,208,208,208,209,209,209,209,210,210,210,210,211, + 211,211,211,212,212,212,212,213,213,213,213,214,214,214,214,215, + 215,215,215,216,216,216,216,217,217,217,217,218,218,218,218,219, + 219,219,219,220,220,220,220,221,221,221,221,222,222,222,222,223, + 223,223,223,224,224,224,224,225,225,225,225,226,226,226,226,227, + 227,227,227,228,228,228,228,229,229,229,229,230,230,230,230,231, + 232,232,232,233,233,233,233,232,232,232,232,234,106,106,106,235, + 106,106,106,106,236,109,109,237,237,237,237,238,238,238,238, 0, + 239, 86, 0, 0, 0,239, 7, 82,138, 7, 0, 0, 0,240, 86,241, + 241,241,241,242,242,242,242,243,243,243,243,244,244,244,244,245, + 245,245,245,246,246,246,246,247,247,247,247,248,248,248,248,249, + 249,249,249,250, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 0, 0, 0, 19, 0, 19, 0, 0, 0, 0, + 0, 26, 26, 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, 9, 9, 9, + 9, 0, 9, 9, 0, 9, 0, 9, 9, 55, 55, 55, 55, 55, 55, 6, + 6, 6, 6, 6, 1, 1, 6, 6, 4, 4, 4, 4, 4, 4, 4, 4, + 14, 14, 14, 14, 14, 14, 14, 3, 3, 3, 3, 3, 0, 3, 3, 0, + 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 1, 1, 1, 3, 3, 1, + 3, 3, 3, 37, 37, 37, 37, 38, 38, 38, 38, 64, 64, 64, 64, 90, + 90, 90, 90, 95, 95, 95, 95, 3, 3, 0, 3, 7, 7, 7, 7, 7, + 1, 1, 1, 1, 7, 7, 7, 0, 0, 7, 7, 5, 5, 5, 5, 11, + 11, 11, 11, 10, 10, 10, 10, 21, 21, 21, 21, 22, 22, 22, 22, 23, + 23, 23, 23, 16, 16, 16, 16, 20, 20, 20, 20, 36, 36, 36, 36, 24, + 24, 24, 24, 24, 24, 24, 0, 18, 18, 18, 18, 25, 25, 25, 25, 25, + 0, 0, 0, 0, 25, 25, 25, 33, 33, 33, 33, 8, 8, 8, 8, 8, + 8, 8, 0, 12, 12, 12, 12, 30, 30, 30, 30, 29, 29, 29, 29, 28, + 28, 28, 28, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 0, 0, + 0, 35, 35, 45, 45, 45, 45, 44, 44, 44, 44, 44, 0, 0, 0, 43, + 43, 43, 43, 46, 46, 46, 46, 31, 31, 31, 31, 32, 32, 0, 0, 32, + 0, 32, 32, 32, 32, 32, 32, 48, 48, 48, 48, 52, 52, 52, 52, 58, + 58, 58, 58, 54, 54, 54, 54, 91, 91, 91, 91, 62, 62, 62, 62, 76, + 76, 76, 76, 93, 93, 93, 93, 70, 70, 70, 70, 73, 73, 73, 73, 1, + 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, + 1, 0, 0, 19, 19, 9, 9, 9, 9, 9, 6, 19, 9, 9, 9, 9, + 9, 19, 19, 9, 9, 9, 19, 6, 19, 19, 19, 19, 19, 19, 9, 0, + 0, 0, 19, 0, 0, 9, 0, 0, 0, 19, 19, 27, 27, 27, 27, 56, + 56, 56, 56, 61, 61, 61, 61, 13, 13, 13, 13, 0, 13, 0, 13, 0, + 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 0, 15, 15, 15, 15, + 15, 15, 15, 15, 1, 1, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 0, 26, 26, 26, 26, 26, 12, 12, 12, 12, 12, 12, 0, 39, + 39, 39, 39, 86, 86, 86, 86, 77, 77, 77, 77, 79, 79, 79, 79, 60, + 60, 60, 60, 65, 65, 65, 65, 75, 75, 75, 75, 69, 69, 69, 69, 69, + 69, 0, 69, 74, 74, 74, 74, 84, 84, 84, 84, 84, 84, 84, 0, 68, + 68, 68, 68, 92, 92, 92, 92, 87, 87, 87, 87, 19, 9, 19, 19, 19, + 19, 0, 0, 2, 2, 2, 2, 19, 19, 19, 4, 3, 3, 0, 0, 1, + 1, 6, 6, 0, 0, 17, 17, 17, 17, 0, 0, 49, 49, 49, 49, 0, + 1, 1, 1, 71, 71, 71, 71, 67, 67, 67, 67, 42, 42, 42, 42, 41, + 41, 41, 41,118,118,118,118, 53, 53, 53, 53, 59, 59, 59, 59, 40, + 40, 40, 40, 51, 51, 51, 51, 50, 50, 50, 50,135,135,135,135,106, + 106,106,106,104,104,104,104,161,161,161,161,170,170,170,170,110, + 110,110,110, 47, 47, 47, 47, 81, 81, 81, 81,120,120,120,120,116, + 116,116,116,128,128,128,128, 66, 66, 66, 66, 72, 72, 72, 72,173, + 173,173,173, 98, 98, 98, 98, 97, 97, 97, 97, 57, 57, 57, 57, 88, + 88, 88, 88,117,117,117,117,112,112,112,112, 78, 78, 78, 78, 83, + 83, 83, 83, 82, 82, 82, 82,122,122,122,122, 89, 89, 89, 89,130, + 130,130,130,144,144,144,144,165,165,165,165,156,156,156,156,156, + 156, 3, 3,147,147,147,147,148,148,148,148,158,158,158,158,153, + 153,153,153,149,149,149,149, 94, 94, 94, 94, 85, 85, 85, 85,101, + 101,101,101, 96, 96, 96, 96,111,111,111,111,100,100,100,100,100, + 36, 36, 36,108,108,108,108,129,129,129,129,109,109,109,109,107, + 107,107,107,107,107,107, 1,171,171,171,171,137,137,137,137,124, + 124,124,124,123,123,123,123,114,114,114,114,102,102,102,102,126, + 126,126,126,142,142,142,142,125,125,125,125,154,154,154,154,150, + 150,150,150,141,141,141,141,140,140,140,140,121,121,121,121,169, + 169,169,169,133,133,133,133,134,134,134,134,138,138,138,138,143, + 143,143,143,175,175,175,175,145,145,145,145,163,163,163,163, 63, + 63, 63, 63,157,157,157,157, 80, 80, 80, 80,127,127,127,127,166, + 166,166,166,115,115,115,115,159,159,159,159,103,103,103,103,119, + 119,119,119,167,167,167,167,146,146,146,146,172,172,172,172, 99, + 99, 99, 99,136,139, 13, 13,155,155,155,155,136,136,136,136, 17, + 15, 15, 15, 17, 17, 15, 15, 15, 17, 17, 17,139,139,139,139,105, + 105,105,105, 0, 0, 0, 1, 0, 0, 1, 1,131,131,131,131,151, + 151,151,151,160,160,160,160,152,152,152,152,164,164,164,164,168, + 168,168,168,174,174,174,174,113,113,113,113,132,132,132,132, 15, + 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, + 10, 9, 11, 12, 13, 9, 9, 9, 14, 9, 9, 15, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 16, + 17, 9, 9, 9, 9, 18, 9, 9, 9, 9, 9, 19, 20, 21, 9, 22, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 23, 9, 9, 9, 9, 9, 24, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 25, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 26, + 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 23, 0, 0, 24, 25, 26, 27, 28, 29, 30, 0, + 0, 31, 32, 0, 33, 0, 34, 0, 35, 0, 0, 0, 0, 36, 37, 38, + 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 43, 44, 0, 45, 0, 0, 0, 0, 0, 0, 46, 47, 0, + 0, 0, 0, 0, 48, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 50, 51, 0, 0, 0, 52, 0, 0, 53, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, + 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 58, 59, 60, 61, 62, 63, 64, 65, 0, 0, 0, + 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 67, 68, 0, 69, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, + 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101, + 102,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,104, 0, 0, 0, 0, 0, 0,105,106, 0,107, 0, 0, + 0,108, 0,109, 0,110, 0,111,112,113, 0,114, 0, 0, 0,115, + 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,117, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,118,119,120,121, 0,122,123,124,125,126, 0, + 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142, + 143,144,145,146,147,148,149,150,151,152,153,154,155,156,157, 0, + 0, 0,158,159,160,161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,162, 0,163, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,164,165, 0, 0, 0, 0, + 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,167, 0, 0, 0,168,169, 0, 0,170, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,171, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,172, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,175, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,176,177, 0, 0, 0, 0,178,179, 0, 0, + 0,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194, + 195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210, + 211,212,213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, + 4, +}; +static const uint16_t _hb_ucd_u16[5104]= +{ + 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12, + 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23, + 13, 13, 13, 24, 25, 11, 11, 11, 11, 26, 11, 27, 28, 29, 30, 31, + 32, 32, 32, 32, 32, 32, 32, 33, 34, 35, 36, 11, 37, 38, 13, 39, + 9, 9, 9, 11, 11, 11, 13, 13, 40, 13, 13, 13, 41, 13, 13, 13, + 13, 13, 13, 35, 9, 42, 11, 11, 43, 44, 32, 45, 46, 47, 47, 48, + 49, 50, 47, 47, 51, 32, 52, 53, 47, 47, 47, 47, 47, 54, 55, 56, + 57, 58, 47, 32, 59, 47, 47, 47, 47, 47, 60, 53, 61, 47, 62, 63, + 47, 64, 65, 66, 47, 67, 47, 47, 68, 69, 47, 47, 70, 32, 71, 32, + 72, 47, 47, 73, 74, 75, 76, 77, 78, 47, 47, 79, 80, 81, 82, 83, + 84, 47, 47, 85, 86, 87, 88, 89, 84, 47, 47, 79, 90, 47, 82, 91, + 92, 47, 47, 93, 94, 95, 82, 96, 97, 47, 47, 98, 99, 100, 101, 102, + 103, 47, 47, 104, 105, 106, 82, 107, 108, 47, 47, 93, 109, 110, 82, 111, + 112, 47, 47, 113, 114, 115, 82, 116, 92, 47, 47, 47, 117, 118, 101, 119, + 47, 47, 47, 120, 121, 122, 66, 66, 47, 47, 47, 123, 124, 125, 47, 47, + 126, 127, 128, 129, 47, 47, 47, 130, 131, 32, 32, 132, 133, 134, 66, 66, + 47, 47, 135, 136, 122, 137, 138, 139, 140, 141, 9, 9, 9, 11, 11, 142, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 143, 144, 145, + 47, 146, 9, 9, 9, 9, 9, 147, 148, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 149, 47, 150, 151, 47, 47, 47, 47, 152, 153, + 47, 154, 47, 155, 47, 156, 47, 156, 47, 47, 47, 157, 158, 159, 160, 145, + 161, 160, 47, 47, 162, 47, 47, 47, 163, 47, 164, 47, 47, 47, 47, 47, + 47, 47, 165, 166, 167, 47, 47, 47, 47, 47, 47, 47, 47, 168, 146, 146, + 47, 169, 47, 47, 47, 170, 171, 172, 160, 160, 173, 174, 32, 32, 32, 32, + 175, 47, 47, 176, 177, 122, 178, 179, 180, 47, 181, 61, 47, 47, 182, 183, + 47, 47, 184, 185, 186, 61, 47, 187, 188, 9, 9, 9, 66, 189, 190, 191, + 11, 11, 192, 27, 27, 27, 193, 194, 11, 195, 27, 27, 32, 32, 32, 32, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 196, 13, 13, 13, 13, 13, 13, + 197, 197, 197, 197, 197, 198, 197, 11, 199, 199, 199, 200, 201, 202, 202, 201, + 203, 204, 205, 206, 207, 208, 209, 210, 211, 27, 212, 212, 212, 213, 214, 32, + 215, 216, 217, 218, 219, 145, 220, 220, 221, 222, 223, 146, 224, 225, 146, 226, + 227, 227, 227, 227, 227, 227, 227, 227, 228, 146, 229, 146, 146, 146, 146, 230, + 146, 231, 227, 232, 146, 233, 234, 146, 146, 146, 146, 146, 146, 146, 145, 145, + 145, 235, 146, 146, 146, 146, 236, 145, 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 237, 238, 146, 146, 239, 146, 146, 146, 146, 146, 146, 240, 146, + 146, 146, 146, 146, 146, 146, 241, 242, 145, 243, 146, 146, 244, 227, 245, 227, + 246, 247, 227, 227, 227, 248, 227, 249, 146, 146, 146, 227, 250, 146, 146, 146, + 9, 9, 9, 11, 11, 11, 251, 252, 13, 13, 13, 13, 13, 13, 253, 254, + 11, 11, 11, 47, 47, 47, 255, 256, 47, 47, 47, 47, 47, 47, 32, 32, + 257, 258, 259, 260, 261, 262, 263, 263, 264, 265, 266, 267, 268, 47, 47, 47, + 47, 269, 148, 47, 47, 47, 47, 270, 47, 271, 47, 47, 146, 146, 146, 47, + 146, 146, 272, 146, 273, 274, 146, 146, 272, 146, 146, 274, 146, 146, 146, 146, + 47, 47, 47, 47, 146, 146, 146, 146, 47, 275, 47, 47, 47, 47, 47, 47, + 47, 146, 146, 146, 146, 47, 47, 187, 276, 47, 61, 47, 13, 13, 277, 278, + 13, 279, 47, 47, 47, 47, 280, 281, 31, 282, 283, 284, 13, 13, 13, 285, + 286, 287, 288, 289, 290, 291, 9, 292, 293, 47, 294, 295, 47, 47, 47, 296, + 297, 47, 47, 298, 299, 160, 32, 300, 61, 47, 301, 47, 302, 303, 47, 47, + 72, 47, 47, 304, 305, 306, 307, 61, 47, 47, 308, 309, 310, 311, 47, 312, + 47, 47, 47, 313, 58, 314, 315, 316, 47, 47, 47, 11, 11, 317, 318, 11, + 11, 11, 11, 11, 47, 47, 319, 160, 320, 320, 320, 320, 320, 320, 320, 320, + 321, 321, 321, 321, 321, 321, 321, 321, 11, 322, 323, 47, 47, 47, 47, 47, + 47, 47, 47, 324, 325, 326, 47, 47, 47, 47, 47, 327, 146, 47, 47, 47, + 47, 328, 47, 47, 329, 146, 146, 330, 32, 331, 32, 332, 333, 334, 335, 47, + 47, 47, 47, 47, 47, 47, 47, 336, 337, 2, 3, 4, 5, 338, 339, 340, + 47, 341, 47, 47, 47, 47, 342, 343, 344, 145, 145, 345, 220, 220, 220, 346, + 347, 146, 146, 146, 146, 146, 146, 348, 349, 349, 349, 349, 349, 349, 349, 349, + 47, 47, 47, 47, 47, 47, 350, 145, 47, 47, 351, 47, 352, 47, 47, 60, + 47, 353, 47, 47, 47, 354, 220, 220, 9, 9, 147, 11, 11, 47, 47, 47, + 47, 47, 160, 9, 9, 147, 11, 11, 47, 47, 47, 47, 47, 47, 353, 9, + 9, 355, 11, 11, 47, 47, 47, 47, 27, 27, 27, 27, 27, 27, 27, 27, + 47, 47, 47, 47, 47, 356, 47, 357, 47, 47, 358, 145, 145, 145, 47, 359, + 47, 360, 47, 353, 47, 47, 47, 47, 47, 47, 47, 361, 145, 145, 145, 145, + 362, 47, 47, 363, 145, 66, 47, 364, 47, 365, 145, 145, 366, 47, 367, 66, + 47, 47, 47, 368, 47, 369, 47, 369, 47, 368, 144, 145, 145, 145, 145, 145, + 9, 9, 9, 9, 11, 11, 11, 370, 47, 47, 371, 160, 372, 9, 373, 11, + 374, 227, 227, 227, 227, 227, 227, 227, 145, 145, 145, 145, 145, 145, 145, 145, + 47, 47, 375, 47, 275, 376, 146, 377, 47, 365, 378, 47, 60, 379, 66, 47, + 380, 66, 66, 47, 381, 145, 47, 47, 382, 47, 47, 363, 383, 384, 385, 386, + 180, 47, 47, 387, 388, 47, 47, 160, 97, 47, 389, 390, 391, 47, 47, 392, + 180, 47, 47, 393, 394, 395, 396, 145, 47, 47, 397, 398, 362, 32, 32, 32, + 47, 47, 368, 47, 47, 399, 172, 160, 92, 47, 47, 113, 400, 401, 402, 32, + 47, 47, 47, 403, 404, 405, 406, 32, 47, 47, 47, 407, 408, 409, 47, 47, + 47, 47, 47, 410, 411, 160, 160, 160, 47, 47, 412, 413, 414, 415, 32, 32, + 47, 47, 47, 416, 417, 160, 66, 66, 47, 47, 418, 419, 160, 160, 160, 160, + 47, 420, 421, 422, 47, 47, 47, 47, 47, 47, 397, 423, 66, 66, 66, 66, + 9, 9, 9, 9, 11, 11, 128, 424, 47, 47, 47, 425, 426, 160, 160, 160, + 47, 47, 47, 47, 47, 427, 428, 429, 430, 47, 47, 431, 432, 433, 47, 47, + 434, 435, 66, 47, 47, 47, 47, 47, 66, 66, 66, 66, 66, 66, 436, 429, + 47, 47, 47, 47, 47, 47, 437, 160, 47, 47, 412, 438, 437, 128, 145, 439, + 47, 156, 440, 441, 32, 32, 32, 32, 47, 47, 47, 362, 442, 160, 47, 47, + 443, 444, 160, 47, 47, 445, 160, 160, 47, 47, 47, 47, 47, 47, 47, 446, + 447, 47, 47, 448, 449, 450, 32, 32, 47, 47, 47, 47, 145, 451, 452, 453, + 220, 220, 220, 220, 220, 220, 220, 66, 47, 47, 47, 47, 47, 47, 47, 437, + 47, 47, 47, 209, 454, 32, 47, 47, 47, 455, 456, 160, 160, 160, 160, 160, + 47, 47, 47, 47, 47, 47, 306, 47, 47, 47, 47, 47, 160, 47, 47, 457, + 47, 47, 47, 458, 459, 460, 461, 47, 27, 27, 27, 27, 462, 47, 463, 160, + 9, 9, 9, 9, 9, 9, 11, 11, 145, 464, 9, 465, 11, 11, 11, 11, + 47, 47, 47, 47, 399, 466, 429, 429, 467, 468, 27, 27, 27, 27, 469, 470, + 47, 471, 209, 209, 209, 209, 209, 209, 146, 146, 146, 146, 146, 146, 146, 472, + 146, 146, 146, 146, 146, 146, 146, 227, 32, 32, 32, 32, 32, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 473, 474, 475, 146, 476, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 477, 146, 146, 146, 9, 478, 11, 479, 480, 11, 197, 9, + 481, 482, 9, 483, 11, 9, 478, 11, 479, 480, 11, 197, 9, 481, 482, 9, + 483, 11, 9, 478, 11, 479, 480, 11, 197, 9, 481, 482, 9, 483, 11, 9, + 478, 11, 197, 9, 484, 485, 486, 487, 11, 488, 9, 489, 490, 491, 492, 11, + 493, 9, 494, 11, 495, 160, 160, 160, 32, 32, 32, 496, 32, 32, 497, 498, + 499, 500, 32, 32, 32, 32, 32, 32, 501, 11, 11, 11, 11, 11, 11, 11, + 32, 32, 32, 27, 27, 27, 27, 27, 32, 32, 32, 32, 32, 32, 32, 32, + 47, 47, 47, 502, 503, 146, 146, 146, 47, 47, 455, 32, 47, 47, 504, 505, + 47, 47, 47, 47, 47, 47, 506, 160, 47, 47, 47, 47, 47, 47, 455, 507, + 47, 47, 47, 47, 47, 47, 508, 509, 47, 47, 47, 47, 358, 32, 32, 32, + 9, 9, 481, 11, 510, 306, 66, 66, 145, 145, 511, 512, 145, 145, 145, 145, + 145, 145, 513, 145, 145, 145, 145, 145, 47, 47, 47, 47, 47, 47, 47, 227, + 514, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 515, + 146, 146, 146, 146, 146, 227, 227, 227, 209, 209, 209, 209, 209, 209, 209, 209, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 939, 940, 941, 942, 946, 948, 0, 962, 969, 970, 971, 976,1001,1002,1003,1008, + 0,1033,1040,1041,1042,1043,1047, 0, 0,1080,1081,1082,1086,1110, 0, 0, + 1124,1125,1126,1127,1131,1133, 0,1147,1154,1155,1156,1161,1187,1188,1189,1193, + 0,1219,1226,1227,1228,1229,1233, 0, 0,1267,1268,1269,1273,1298, 0,1303, + 943,1128, 944,1129, 954,1139, 958,1143, 959,1144, 960,1145, 961,1146, 964,1149, + 0, 0, 973,1158, 974,1159, 975,1160, 983,1168, 978,1163, 988,1173, 990,1175, + 991,1176, 993,1178, 994,1179, 0, 0,1004,1190,1005,1191,1006,1192,1014,1199, + 1007, 0, 0, 0,1016,1201,1020,1206, 0,1022,1208,1025,1211,1023,1209, 0, + 0, 0, 0,1032,1218,1037,1223,1035,1221, 0, 0, 0,1044,1230,1045,1231, + 1049,1235, 0, 0,1058,1244,1064,1250,1060,1246,1066,1252,1067,1253,1072,1258, + 1069,1255,1077,1264,1074,1261, 0, 0,1083,1270,1084,1271,1085,1272,1088,1275, + 1089,1276,1096,1283,1103,1290,1111,1299,1115,1118,1307,1120,1309,1121,1310, 0, + 1053,1239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1093, + 1280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 949,1134,1010, + 1195,1050,1236,1090,1277,1341,1368,1340,1367,1342,1369,1339,1366, 0,1320,1347, + 1418,1419,1323,1350, 0, 0, 992,1177,1018,1204,1055,1241,1416,1417,1415,1424, + 1202, 0, 0, 0, 987,1172, 0, 0,1031,1217,1321,1348,1322,1349,1338,1365, + 950,1135, 951,1136, 979,1164, 980,1165,1011,1196,1012,1197,1051,1237,1052,1238, + 1061,1247,1062,1248,1091,1278,1092,1279,1071,1257,1076,1263, 0, 0, 997,1182, + 0, 0, 0, 0, 0, 0, 945,1130, 982,1167,1337,1364,1335,1362,1046,1232, + 1422,1423,1113,1301, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 9, 0, 10,1425, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0,1314,1427, 5,1434,1438,1443, 0,1450, 0,1455,1461, + 1514, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1446,1458,1468,1476,1480,1486, + 1517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1489,1503,1494,1500,1508, 0, + 0, 0, 0,1520,1521, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1526,1528, 0,1525, 0, 0, 0,1522, 0, 0, 0, 0,1536,1532,1539, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1534, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1556, 0, 0, 0, 0, 0, 0, + 1548,1550, 0,1547, 0, 0, 0,1567, 0, 0, 0, 0,1558,1554,1561, 0, + 0, 0, 0, 0, 0, 0,1568,1569, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1529,1551, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1523,1545,1524,1546, 0, 0,1527,1549, 0, 0,1570,1571,1530,1552,1531,1553, + 0, 0,1533,1555,1535,1557,1537,1559, 0, 0,1572,1573,1544,1566,1538,1560, + 1540,1562,1541,1563,1542,1564, 0, 0,1543,1565, 0, 0, 0, 0, 0, 0, + 0, 0,1606,1607,1609,1608,1610, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1613, 0,1611, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1620, 0, 0, 0, 0, 0, 0, + 0,1623, 0, 0,1624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1614,1615,1616,1617,1618,1619,1621,1622, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1628,1629, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1625,1626, 0,1627, + 0, 0, 0,1634, 0, 0,1635, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1630,1631,1632, 0, 0,1633, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1639, 0, 0,1638,1640, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1636,1637, 0, 0, + 0, 0, 0, 0,1641, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1642,1644,1643, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1645, 0, 0, 0, 0, 0, 0, 0, + 1646, 0, 0, 0, 0, 0, 0,1648,1649, 0,1647,1650, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1651,1653,1652, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1654, 0,1655,1657,1656, 0, + 0, 0, 0,1659, 0, 0, 0, 0, 0, 0, 0, 0, 0,1660, 0, 0, + 0, 0,1661, 0, 0, 0, 0,1662, 0, 0, 0, 0,1663, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1658, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1664, 0,1665,1673, 0,1674, 0, 0, 0, 0, 0, 0, 0, + 0,1666, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1668, 0, 0, 0, 0, 0, 0, 0, 0, 0,1669, 0, 0, + 0, 0,1670, 0, 0, 0, 0,1671, 0, 0, 0, 0,1672, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1667, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1675, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1676, 0,1677, 0,1678, 0,1679, 0,1680, 0, + 0, 0,1681, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1682, 0,1683, 0, 0, + 1684,1685, 0,1686, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 953,1138, 955,1140, 956,1141, 957,1142,1324,1351, 963,1148, 965,1150, 968,1153, + 966,1151, 967,1152,1378,1380,1379,1381, 984,1169, 985,1170,1420,1421, 986,1171, + 989,1174, 995,1180, 998,1183, 996,1181, 999,1184,1000,1185,1015,1200,1329,1356, + 1017,1203,1019,1205,1021,1207,1024,1210,1687,1688,1027,1213,1026,1212,1028,1214, + 1029,1215,1030,1216,1034,1220,1036,1222,1039,1225,1038,1224,1334,1361,1336,1363, + 1382,1384,1383,1385,1056,1242,1057,1243,1059,1245,1063,1249,1689,1690,1065,1251, + 1068,1254,1070,1256,1386,1387,1388,1389,1691,1692,1073,1259,1075,1262,1079,1266, + 1078,1265,1095,1282,1098,1285,1097,1284,1390,1391,1392,1393,1099,1286,1100,1287, + 1101,1288,1102,1289,1105,1292,1104,1291,1106,1294,1107,1295,1108,1296,1114,1302, + 1119,1308,1122,1311,1123,1312,1186,1260,1293,1305, 0,1394, 0, 0, 0, 0, + 952,1137, 947,1132,1317,1344,1316,1343,1319,1346,1318,1345,1693,1695,1371,1375, + 1370,1374,1373,1377,1372,1376,1694,1696, 981,1166, 977,1162, 972,1157,1326,1353, + 1325,1352,1328,1355,1327,1354,1697,1698,1009,1194,1013,1198,1054,1240,1048,1234, + 1331,1358,1330,1357,1333,1360,1332,1359,1699,1700,1396,1401,1395,1400,1398,1403, + 1397,1402,1399,1404,1094,1281,1087,1274,1406,1411,1405,1410,1408,1413,1407,1412, + 1409,1414,1109,1297,1117,1306,1116,1304,1112,1300, 0, 0, 0, 0, 0, 0, + 1471,1472,1701,1705,1702,1706,1703,1707,1430,1431,1715,1719,1716,1720,1717,1721, + 1477,1478,1729,1731,1730,1732, 0, 0,1435,1436,1733,1735,1734,1736, 0, 0, + 1481,1482,1737,1741,1738,1742,1739,1743,1439,1440,1751,1755,1752,1756,1753,1757, + 1490,1491,1765,1768,1766,1769,1767,1770,1447,1448,1771,1774,1772,1775,1773,1776, + 1495,1496,1777,1779,1778,1780, 0, 0,1451,1452,1781,1783,1782,1784, 0, 0, + 1504,1505,1785,1788,1786,1789,1787,1790, 0,1459, 0,1791, 0,1792, 0,1793, + 1509,1510,1794,1798,1795,1799,1796,1800,1462,1463,1808,1812,1809,1813,1810,1814, + 1467, 21,1475, 22,1479, 23,1485, 24,1493, 27,1499, 28,1507, 29, 0, 0, + 1704,1708,1709,1710,1711,1712,1713,1714,1718,1722,1723,1724,1725,1726,1727,1728, + 1740,1744,1745,1746,1747,1748,1749,1750,1754,1758,1759,1760,1761,1762,1763,1764, + 1797,1801,1802,1803,1804,1805,1806,1807,1811,1815,1816,1817,1818,1819,1820,1821, + 1470,1469,1822,1474,1465, 0,1473,1825,1429,1428,1426, 12,1432, 0, 26, 0, + 0,1315,1823,1484,1466, 0,1483,1829,1433, 13,1437, 14,1441,1826,1827,1828, + 1488,1487,1513, 19, 0, 0,1492,1515,1445,1444,1442, 15, 0,1831,1832,1833, + 1502,1501,1516, 25,1497,1498,1506,1518,1457,1456,1454, 17,1453,1313, 11, 3, + 0, 0,1824,1512,1519, 0,1511,1830,1449, 16,1460, 18,1464, 4, 0, 0, + 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 2, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1834,1835, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1836, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1837,1839,1838, + 0, 0, 0, 0,1840, 0, 0, 0, 0,1841, 0, 0,1842, 0, 0, 0, + 0, 0, 0, 0,1843, 0,1844, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1845, 0, 0,1846, 0, 0,1847, 0,1848, 0, 0, 0, 0, 0, 0, + 937, 0,1850, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1849, 936, 938, + 1851,1852, 0, 0,1853,1854, 0, 0,1855,1856, 0, 0, 0, 0, 0, 0, + 1857,1858, 0, 0,1861,1862, 0, 0,1863,1864, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1867,1868,1869,1870, + 1859,1860,1865,1866, 0, 0, 0, 0, 0, 0,1871,1872,1873,1874, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 33, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1875, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1877, 0,1878, 0, + 1879, 0,1880, 0,1881, 0,1882, 0,1883, 0,1884, 0,1885, 0,1886, 0, + 1887, 0,1888, 0, 0,1889, 0,1890, 0,1891, 0, 0, 0, 0, 0, 0, + 1892,1893, 0,1894,1895, 0,1896,1897, 0,1898,1899, 0,1900,1901, 0, 0, + 0, 0, 0, 0,1876, 0, 0, 0, 0, 0, 0, 0, 0, 0,1902, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1904, 0,1905, 0, + 1906, 0,1907, 0,1908, 0,1909, 0,1910, 0,1911, 0,1912, 0,1913, 0, + 1914, 0,1915, 0, 0,1916, 0,1917, 0,1918, 0, 0, 0, 0, 0, 0, + 1919,1920, 0,1921,1922, 0,1923,1924, 0,1925,1926, 0,1927,1928, 0, 0, + 0, 0, 0, 0,1903, 0, 0,1929,1930,1931,1932, 0, 0, 0,1933, 0, + 710, 385, 724, 715, 455, 103, 186, 825, 825, 242, 751, 205, 241, 336, 524, 601, + 663, 676, 688, 738, 411, 434, 474, 500, 649, 746, 799, 108, 180, 416, 482, 662, + 810, 275, 462, 658, 692, 344, 618, 679, 293, 388, 440, 492, 740, 116, 146, 168, + 368, 414, 481, 527, 606, 660, 665, 722, 781, 803, 809, 538, 553, 588, 642, 758, + 811, 701, 233, 299, 573, 612, 487, 540, 714, 779, 232, 267, 412, 445, 457, 585, + 594, 766, 167, 613, 149, 148, 560, 589, 648, 768, 708, 345, 411, 704, 105, 259, + 313, 496, 518, 174, 542, 120, 307, 101, 430, 372, 584, 183, 228, 529, 650, 697, + 424, 732, 428, 349, 632, 355, 517, 110, 135, 147, 403, 580, 624, 700, 750, 170, + 193, 245, 297, 374, 463, 543, 763, 801, 812, 815, 162, 384, 420, 730, 287, 330, + 337, 366, 459, 476, 509, 558, 591, 610, 726, 652, 734, 759, 154, 163, 198, 473, + 683, 697, 292, 311, 353, 423, 572, 494, 113, 217, 259, 280, 314, 499, 506, 603, + 608, 752, 778, 782, 788, 117, 557, 748, 774, 320, 109, 126, 260, 265, 373, 411, + 479, 523, 655, 737, 823, 380, 765, 161, 395, 398, 438, 451, 502, 516, 537, 583, + 791, 136, 340, 769, 122, 273, 446, 727, 305, 322, 400, 496, 771, 155, 190, 269, + 377, 391, 406, 432, 501, 519, 599, 684, 687, 749, 776, 175, 452, 191, 480, 510, + 659, 772, 805, 813, 397, 444, 619, 566, 568, 575, 491, 471, 707, 111, 636, 156, + 153, 288, 346, 578, 256, 435, 383, 729, 680, 767, 694, 295, 128, 210, 0, 0, + 227, 0, 379, 0, 0, 150, 493, 525, 544, 551, 552, 556, 783, 576, 604, 0, + 661, 0, 703, 0, 0, 735, 743, 0, 0, 0, 793, 794, 795, 808, 741, 773, + 118, 127, 130, 166, 169, 177, 207, 213, 215, 226, 229, 268, 270, 317, 327, 329, + 335, 369, 375, 381, 404, 441, 448, 458, 477, 484, 503, 539, 545, 547, 546, 548, + 549, 550, 554, 555, 561, 564, 569, 591, 593, 595, 598, 607, 620, 625, 625, 651, + 690, 695, 705, 706, 716, 717, 733, 735, 777, 786, 790, 315, 869, 623, 0, 0, + 102, 145, 134, 115, 129, 138, 165, 171, 207, 202, 206, 212, 227, 231, 240, 243, + 250, 254, 294, 296, 303, 308, 319, 325, 321, 329, 326, 335, 341, 357, 360, 362, + 370, 379, 388, 389, 393, 421, 424, 438, 456, 454, 458, 465, 477, 535, 485, 490, + 493, 507, 512, 514, 521, 522, 525, 526, 528, 533, 532, 541, 565, 569, 574, 586, + 591, 597, 607, 637, 647, 674, 691, 693, 695, 698, 703, 699, 705, 704, 702, 706, + 709, 717, 728, 736, 747, 754, 770, 777, 783, 784, 786, 787, 790, 802, 825, 848, + 847, 857, 55, 65, 66, 883, 892, 916, 822, 824, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1586, 0,1605, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1602,1603,1934,1935,1574,1575, + 1576,1577,1579,1580,1581,1583,1584, 0,1585,1587,1588,1589,1591, 0,1592, 0, + 1593,1594, 0,1595,1596, 0,1598,1599,1600,1601,1604,1582,1578,1590,1597, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1936, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,1937, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1938, 0,1939, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1940, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1941,1942, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1943,1944, 0, 0, 0, + 0, 0, 0,1945, 0,1946, 0, 0, 0, 0, 0, 0, 0, 0,1947, 0, + 0,1948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,1950, 0,1949,1951, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1953,1952, 0,1954, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1955,1956, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1957, 0, 0, 0, 0, 0, 0, 0, + 0,1958,1961,1959,1965,1960,1962,1964,1963, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1967,1966,1968, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1969,1970, + 1971,1972,1973,1974,1975, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1976,1977,1978,1980,1979, + 1981, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 106, 104, 107, 826, 114, 118, 119, 121, 123, 124, 127, 125, 34, 830, 130, 131, + 132, 137, 827, 35, 133, 139, 829, 142, 143, 112, 144, 145, 924, 151, 152, 37, + 157, 158, 159, 160, 38, 165, 166, 169, 171, 172, 173, 174, 176, 177, 178, 179, + 181, 182, 182, 182, 833, 468, 184, 185, 834, 187, 188, 189, 196, 192, 194, 195, + 197, 199, 200, 201, 203, 204, 204, 206, 208, 209, 211, 218, 213, 219, 214, 216, + 153, 234, 221, 222, 223, 220, 225, 224, 230, 835, 235, 236, 237, 238, 239, 244, + 836, 837, 247, 248, 249, 246, 251, 39, 40, 253, 255, 255, 838, 257, 258, 259, + 261, 839, 262, 263, 301, 264, 41, 266, 270, 272, 271, 841, 274, 842, 277, 276, + 278, 281, 282, 42, 283, 284, 285, 286, 43, 843, 44, 289, 290, 291, 293, 934, + 298, 845, 845, 621, 300, 300, 45, 852, 894, 302, 304, 46, 306, 309, 310, 312, + 316, 48, 47, 317, 846, 318, 323, 324, 325, 324, 328, 329, 333, 331, 332, 334, + 335, 336, 338, 339, 342, 343, 347, 351, 849, 350, 348, 352, 354, 359, 850, 361, + 358, 356, 49, 363, 365, 367, 364, 50, 369, 371, 851, 376, 386, 378, 53, 381, + 52, 51, 140, 141, 387, 382, 614, 78, 388, 389, 390, 394, 392, 856, 54, 399, + 396, 402, 404, 858, 405, 401, 407, 55, 408, 409, 410, 413, 859, 415, 56, 417, + 860, 418, 57, 419, 422, 424, 425, 861, 840, 862, 426, 863, 429, 431, 427, 433, + 437, 441, 438, 439, 442, 443, 864, 436, 449, 450, 58, 454, 453, 865, 447, 460, + 866, 867, 461, 466, 465, 464, 59, 467, 470, 469, 472, 828, 475, 868, 478, 870, + 483, 485, 486, 871, 488, 489, 872, 873, 495, 497, 60, 498, 61, 61, 504, 505, + 507, 508, 511, 62, 513, 874, 515, 875, 518, 844, 520, 876, 877, 878, 63, 64, + 528, 880, 879, 881, 882, 530, 531, 531, 533, 66, 534, 67, 68, 884, 536, 538, + 541, 69, 885, 549, 886, 887, 556, 559, 70, 561, 562, 563, 888, 889, 889, 567, + 71, 890, 570, 571, 72, 891, 577, 73, 581, 579, 582, 893, 587, 74, 590, 592, + 596, 75, 895, 896, 76, 897, 600, 898, 602, 605, 607, 899, 900, 609, 901, 611, + 853, 77, 615, 616, 79, 617, 252, 902, 903, 854, 855, 621, 622, 731, 80, 627, + 626, 628, 164, 629, 630, 631, 633, 904, 632, 634, 639, 640, 635, 641, 646, 651, + 638, 643, 644, 645, 905, 907, 906, 81, 653, 654, 656, 911, 657, 908, 82, 83, + 909, 910, 84, 664, 665, 666, 667, 669, 668, 671, 670, 674, 672, 673, 675, 85, + 677, 678, 86, 681, 682, 912, 685, 686, 87, 689, 36, 913, 914, 88, 89, 696, + 702, 709, 711, 915, 712, 713, 718, 719, 917, 831, 721, 720, 723, 832, 725, 728, + 918, 919, 739, 742, 744, 920, 745, 753, 756, 757, 755, 760, 761, 921, 762, 90, + 764, 922, 91, 775, 279, 780, 923, 925, 92, 93, 785, 926, 94, 927, 787, 787, + 789, 928, 792, 95, 796, 797, 798, 800, 96, 929, 802, 804, 806, 97, 98, 807, + 930, 99, 931, 932, 933, 814, 100, 816, 817, 818, 819, 820, 821, 935, 0, 0, +}; +static const int16_t _hb_ucd_i16[92]= +{ + 0, 0, 1, -1, 2, 0, -2, 0, 0, 2, 0, -2, 0, 16, 0, -16, + 0, 1, -1, 0, 3, 3, 3, -3, -3, -3, 0, 2016, 0, 2527, 1923, 1914, + 1918, 0, 2250, 0, 0, 138, 0, 7, -7, 0, -1, 1, 1824, 0, 2104, 0, + 2108, 2106, 0, 2106, 1316, 0, -1, -138, 8, 8, 8, 0, 7, 7, -8, -8, + -8, -7,-1316, 1, -1, 3, -3, 1, 0,-1914,-1918, 0, 0,-1923,-1824, 0, + 0,-2016,-2104, 0, 0,-2106,-2108,-2106,-2250, 0,-2527, 0, +}; + +static inline uint8_t _hb_ucd_gc (unsigned u) +{ + return u<1114112 ? _hb_ucd_u8[5296u+((_hb_ucd_u8[1168u+((_hb_ucd_u16[((_hb_ucd_u8[544u+((_hb_ucd_u8[((((((((u)>>1))>>3))>>3))>>4)])<<4)+((((((((u)>>1))>>3))>>3))&15)])<<3)+((((((u)>>1))>>3))&7)])<<3)+((((u)>>1))&7)])<<1)+((u)&1)] : 2; +} +static inline uint8_t _hb_ucd_ccc (unsigned u) +{ + return u<125259 ? _hb_ucd_u8[7322u+((_hb_ucd_u8[6738u+((_hb_ucd_u8[6258u+((_hb_ucd_u8[5890u+((_hb_ucd_u8[5644u+((((((((u)>>2))>>2))>>2))>>3)])<<3)+((((((((u)>>2))>>2))>>2))&7)])<<2)+((((((u)>>2))>>2))&3)])<<2)+((((u)>>2))&3)])<<2)+((u)&3)] : 0; +} +static inline uint8_t _hb_ucd_b4 (const uint8_t* a, unsigned i) +{ + return (a[i>>1]>>((i&1)<<2))&15; +} +static inline int16_t _hb_ucd_bmg (unsigned u) +{ + return u<65380 ? _hb_ucd_i16[((_hb_ucd_u8[8218u+((_hb_ucd_u8[7986u+((_hb_ucd_u8[7890u+((_hb_ucd_b4(_hb_ucd_u8+7826u,((((((((u)>>1))>>2))>>3))>>3)))<<3)+((((((((u)>>1))>>2))>>3))&7)])<<3)+((((((u)>>1))>>2))&7)])<<2)+((((u)>>1))&3)])<<1)+((u)&1)] : 0; +} +static inline uint8_t _hb_ucd_sc (unsigned u) +{ + return u<918016 ? _hb_ucd_u8[11655u+((_hb_ucd_u8[10647u+((_hb_ucd_u8[9151u+((_hb_ucd_u8[8703u+((_hb_ucd_u8[8495u+((_hb_ucd_b4(_hb_ucd_u8+8466u,((((((((((u)>>2))>>2))>>3))>>3))>>4)))<<4)+((((((((((u)>>2))>>2))>>3))>>3))&15)])<<3)+((((((((u)>>2))>>2))>>3))&7)])<<3)+((((((u)>>2))>>2))&7)])<<2)+((((u)>>2))&3)])<<2)+((u)&3)] : 2; +} +static inline uint16_t _hb_ucd_dm (unsigned u) +{ + return u<195102 ? _hb_ucd_u16[1680u+((_hb_ucd_u8[13041u+((_hb_ucd_u8[12659u+((((u)>>4))>>5)])<<5)+((((u)>>4))&31)])<<4)+((u)&15)] : 0; +} + + #endif - #endif /* HB_UCD_TABLE_HH */ /* == End of generated table == */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-unicode-emoji-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-unicode-emoji-table.hh index 4bc8d64c28f..711dd9b6571 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-unicode-emoji-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-unicode-emoji-table.hh @@ -7,13 +7,13 @@ * on file with this header: * * # emoji-data.txt - * # Date: 2024-05-01, 21:25:24 GMT - * # © 2024 Unicode®, Inc. + * # Date: 2025-07-25, 17:54:31 GMT + * # © 2025 Unicode®, Inc. * # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. * # For terms of use and license, see https://www.unicode.org/terms_of_use.html * # * # Emoji Data for UTS #51 - * # Used with Emoji Version 16.0 and subsequent minor revisions (if any) + * # Version: 17.0 * # * # For documentation and usage, see https://www.unicode.org/reports/tr51 */ @@ -23,54 +23,62 @@ #include "hb-unicode.hh" -static const uint8_t -_hb_emoji_u8[464] = +#include + +static const uint8_t _hb_emoji_u8[624]= { 16, 17, 17, 17, 50, 20, 21, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,118,152, - 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 0, 3, 4, 0, 0, 5, 6, 0, 7, 0, 8, 9, 10, 11, 12, - 0, 0, 13, 0, 0, 0, 14, 0, 15, 0, 0, 0, 0, 16, 0, 0, - 17, 17, 18, 19, 20, 17, 17, 21, 17, 17, 22, 17, 23, 17, 24, 25, - 26, 27, 28, 17, 17, 17, 0, 0, 17, 17, 17, 17, 17, 17, 17, 29, - 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 3, 0, 0, 4, 0, 0, - 5, 6, 0, 0, 7, 8, 0, 0, 8, 0, 9, 10, 0, 0, 11, 0, - 0, 12, 13, 14, 15, 16, 16, 16, 17, 16, 16, 16, 18, 19, 20, 21, - 22, 23, 0, 0, 0, 24, 0, 0, 25, 0, 26, 0, 0, 27, 0, 0, - 28, 0, 0, 0, 16, 16, 16, 16, 29, 9, 0, 30, 31, 32, 16, 33, - 34, 35, 36, 16, 16, 16, 16, 37, 16, 38, 39, 16, 16, 16, 40, 0, - 0, 0, 0, 41, 0, 0, 42, 16, 43, 0, 44, 0, 45, 46, 16, 16, - 47, 48, 49, 16, 16, 16, 16, 38, 0, 0, 0, 0, 0, 66, 0, 0, - 0, 0, 0, 16, 0, 2, 0, 0, 4, 0, 0, 2, 0, 0,240, 3, - 0, 6, 0, 0, 0, 0, 0, 12, 0, 1, 0, 0, 0,128, 0, 0, - 0,254, 15, 7, 4, 0, 0, 0, 0, 12, 64, 0, 1, 0, 0, 0, - 0, 0, 0,120,191,255,247,255,255,255,255,255, 63, 0,255,255, - 63,255, 87, 32, 2, 1, 24, 0,144, 80,184, 0,248, 0, 0, 0, - 0, 0,224, 0, 2, 0, 1,128, 0, 0, 48, 0,224, 0, 0, 24, - 0, 0, 33, 0, 0, 0, 1, 32, 0, 0,128, 2, 0,224, 0, 0, - 0,240, 3,192, 0, 64,254, 7, 0,224,255,255, 63, 0, 0, 0, - 254,255, 0, 4, 0,128,252,247, 0,254,255,255,255,255,255, 7, - 255,255,255, 63,192,255,255,255,255,255, 0, 0, 0, 0,240,255, - 0, 0,224,255, 0,240, 0, 0, 0,255, 0,252, 0,255, 0, 0, - 0,192,255,255, 0,240,255,255,255,255,255,247,191,255,255,255, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 3, 0, 0, 4, 0, 5, 0, 0, 0, 0, 0, 6, 0, 0, 7, + 0, 0, 0, 8, 0, 0, 9, 10, 11, 12, 13, 14, 15, 16, 17, 0, + 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 19, 20, 0, 0, + 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 0, 0, + 23, 0, 24, 25, 0, 26, 27, 28, 29, 30, 31, 31, 32, 31, 33, 34, + 31, 31, 31, 35, 36, 37, 38, 39, 31, 40, 31, 41, 0, 0, 0, 42, + 43, 44, 45, 46, 47, 48, 31, 31, 0, 49, 31, 31, 0, 0, 0, 0, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 36, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 16, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 0, 0, 2, 0, 0,240, 3, 0, 6, 0, 0, + 0, 0, 0, 12, 0, 1, 0, 0, 0,128, 0, 0, 0,254, 15, 7, + 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 64, 0, + 1, 0, 0, 0, 0, 0, 0,120, 31, 64, 50, 33, 77,196, 0, 7, + 5,255, 15,128,105, 1, 0,200, 0, 0,252, 26,131, 12, 3, 96, + 48,193, 26, 0, 0, 6,191, 39, 36,191, 84, 32, 2, 1, 24, 0, + 144, 80,184, 0, 24, 0, 0, 0, 0, 0,224, 0, 2, 0, 1,128, + 0, 0, 0, 0, 0, 0, 48, 0,224, 0, 0, 24, 0, 0, 0, 0, + 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 32, + 0, 0,128, 2, 0, 0, 0, 0, 16, 0, 0, 0, 0,240, 0, 0, + 0, 0,240,255, 0,128, 1, 0, 1,128, 1, 0, 0, 0,192,255, + 0, 0, 0, 0, 0, 0, 3,192, 0, 64,254, 7, 0,192,255,255, + 255,255,255,255, 63, 0, 0, 0,254,255, 0, 4, 0,128,252,247, + 0,254,255,255,192,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,243,255,255,255,255,255,207,206,255,255,255,255, + 255,255,255,255,255,255,185, 7,255,255,255,255,255,255,255,191, + 255,255,255,255,255,255,255, 63, 0,126,255,255,255,128,249, 7, + 128, 60, 97, 0, 48, 1, 6, 16, 28, 0, 14,112, 10,129, 8,252, + 255,255, 0, 0, 0, 0, 0, 0, 63,248,231,255, 63,250,249,255, + 0, 0, 0,252,255,255,255,255, 0,240, 0, 0, 0, 0, 0, 0, + 0,255, 0,252, 0, 0, 0, 0, 0,255, 0, 0, 0,192, 0,240, + 252,255, 0,254,255,255,255,255, 0,240,255,255,255,255,255,247, + 191,255,255,255,255,255,255,255, 0, 0, 0,255, 0,192,255,255, }; -static inline unsigned -_hb_emoji_b4 (const uint8_t* a, unsigned i) +static inline uint8_t _hb_emoji_b4 (const uint8_t* a, unsigned i) { - return (a[i>>1]>>((i&1u)<<2))&15u; + return (a[i>>1]>>((i&1)<<2))&15; } -static inline unsigned -_hb_emoji_b1 (const uint8_t* a, unsigned i) +static inline uint8_t _hb_emoji_b1 (const uint8_t* a, unsigned i) { - return (a[i>>3]>>((i&7u)<<0))&1u; + return (a[i>>3]>>((i&7)<<0))&1; } -static inline uint_fast8_t -_hb_emoji_is_Extended_Pictographic (unsigned u) +static inline uint8_t _hb_emoji_is_Extended_Pictographic (unsigned u) { - return u<131070u?_hb_emoji_b1(264+_hb_emoji_u8,((_hb_emoji_u8[144+(((_hb_emoji_u8[64+(((_hb_emoji_b4(_hb_emoji_u8,u>>5>>2>>3))<<3)+((u>>5>>2)&7u))])<<2)+((u>>5)&3u))])<<5)+((u)&31u)):0; + return u<131070 ? _hb_emoji_b1(_hb_emoji_u8+224u,((_hb_emoji_u8[64u+((_hb_emoji_b4(_hb_emoji_u8,((((u)>>6))>>4)))<<4)+((((u)>>6))&15)])<<6)+((u)&63)) : 0; } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-unicode.hh b/src/java.desktop/share/native/libharfbuzz/hb-unicode.hh index 924105001d7..9e6f89365fe 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-unicode.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-unicode.hh @@ -241,6 +241,57 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE } } + static hb_codepoint_t + vertical_char_for (hb_codepoint_t u) + { + switch (u >> 8) + { + case 0x20: switch (u) { + case 0x2013u: return 0xfe32u; // EN DASH + case 0x2014u: return 0xfe31u; // EM DASH + case 0x2025u: return 0xfe30u; // TWO DOT LEADER + case 0x2026u: return 0xfe19u; // HORIZONTAL ELLIPSIS + } break; + case 0x30: switch (u) { + case 0x3001u: return 0xfe11u; // IDEOGRAPHIC COMMA + case 0x3002u: return 0xfe12u; // IDEOGRAPHIC FULL STOP + case 0x3008u: return 0xfe3fu; // LEFT ANGLE BRACKET + case 0x3009u: return 0xfe40u; // RIGHT ANGLE BRACKET + case 0x300au: return 0xfe3du; // LEFT DOUBLE ANGLE BRACKET + case 0x300bu: return 0xfe3eu; // RIGHT DOUBLE ANGLE BRACKET + case 0x300cu: return 0xfe41u; // LEFT CORNER BRACKET + case 0x300du: return 0xfe42u; // RIGHT CORNER BRACKET + case 0x300eu: return 0xfe43u; // LEFT WHITE CORNER BRACKET + case 0x300fu: return 0xfe44u; // RIGHT WHITE CORNER BRACKET + case 0x3010u: return 0xfe3bu; // LEFT BLACK LENTICULAR BRACKET + case 0x3011u: return 0xfe3cu; // RIGHT BLACK LENTICULAR BRACKET + case 0x3014u: return 0xfe39u; // LEFT TORTOISE SHELL BRACKET + case 0x3015u: return 0xfe3au; // RIGHT TORTOISE SHELL BRACKET + case 0x3016u: return 0xfe17u; // LEFT WHITE LENTICULAR BRACKET + case 0x3017u: return 0xfe18u; // RIGHT WHITE LENTICULAR BRACKET + } break; + case 0xfe: switch (u) { + case 0xfe4fu: return 0xfe34u; // WAVY LOW LINE + } break; + case 0xff: switch (u) { + case 0xff01u: return 0xfe15u; // FULLWIDTH EXCLAMATION MARK + case 0xff08u: return 0xfe35u; // FULLWIDTH LEFT PARENTHESIS + case 0xff09u: return 0xfe36u; // FULLWIDTH RIGHT PARENTHESIS + case 0xff0cu: return 0xfe10u; // FULLWIDTH COMMA + case 0xff1au: return 0xfe13u; // FULLWIDTH COLON + case 0xff1bu: return 0xfe14u; // FULLWIDTH SEMICOLON + case 0xff1fu: return 0xfe16u; // FULLWIDTH QUESTION MARK + case 0xff3bu: return 0xfe47u; // FULLWIDTH LEFT SQUARE BRACKET + case 0xff3du: return 0xfe48u; // FULLWIDTH RIGHT SQUARE BRACKET + case 0xff3fu: return 0xfe33u; // FULLWIDTH LOW LINE + case 0xff5bu: return 0xfe37u; // FULLWIDTH LEFT CURLY BRACKET + case 0xff5du: return 0xfe38u; // FULLWIDTH RIGHT CURLY BRACKET + } break; + } + + return u; + } + struct { #define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_func_t name; HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS diff --git a/src/java.desktop/share/native/libharfbuzz/hb-utf.hh b/src/java.desktop/share/native/libharfbuzz/hb-utf.hh index 7fd3bf8828b..3891fb331af 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-utf.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-utf.hh @@ -37,7 +37,7 @@ struct hb_utf8_t typedef uint8_t codepoint_t; static constexpr unsigned max_len = 4; - static const codepoint_t * + static inline const codepoint_t * next (const codepoint_t *text, const codepoint_t *end, hb_codepoint_t *unicode, @@ -106,7 +106,7 @@ struct hb_utf8_t return text; } - static const codepoint_t * + static inline const codepoint_t * prev (const codepoint_t *text, const codepoint_t *start, hb_codepoint_t *unicode, @@ -185,7 +185,7 @@ struct hb_utf16_xe_t typedef TCodepoint codepoint_t; static constexpr unsigned max_len = 2; - static const codepoint_t * + static inline const codepoint_t * next (const codepoint_t *text, const codepoint_t *end, hb_codepoint_t *unicode, @@ -217,7 +217,7 @@ struct hb_utf16_xe_t return text; } - static const codepoint_t * + static inline const codepoint_t * prev (const codepoint_t *text, const codepoint_t *start, hb_codepoint_t *unicode, @@ -294,7 +294,7 @@ struct hb_utf32_xe_t typedef TCodepoint codepoint_t; static constexpr unsigned max_len = 1; - static const TCodepoint * + static inline const TCodepoint * next (const TCodepoint *text, const TCodepoint *end HB_UNUSED, hb_codepoint_t *unicode, @@ -306,7 +306,7 @@ struct hb_utf32_xe_t return text; } - static const TCodepoint * + static inline const TCodepoint * prev (const TCodepoint *text, const TCodepoint *start HB_UNUSED, hb_codepoint_t *unicode, @@ -353,7 +353,7 @@ struct hb_latin1_t typedef uint8_t codepoint_t; static constexpr unsigned max_len = 1; - static const codepoint_t * + static inline const codepoint_t * next (const codepoint_t *text, const codepoint_t *end HB_UNUSED, hb_codepoint_t *unicode, @@ -363,7 +363,7 @@ struct hb_latin1_t return text; } - static const codepoint_t * + static inline const codepoint_t * prev (const codepoint_t *text, const codepoint_t *start HB_UNUSED, hb_codepoint_t *unicode, @@ -405,7 +405,7 @@ struct hb_ascii_t typedef uint8_t codepoint_t; static constexpr unsigned max_len = 1; - static const codepoint_t * + static inline const codepoint_t * next (const codepoint_t *text, const codepoint_t *end HB_UNUSED, hb_codepoint_t *unicode, @@ -417,7 +417,7 @@ struct hb_ascii_t return text; } - static const codepoint_t * + static inline const codepoint_t * prev (const codepoint_t *text, const codepoint_t *start HB_UNUSED, hb_codepoint_t *unicode, diff --git a/src/java.desktop/share/native/libharfbuzz/hb-vector.hh b/src/java.desktop/share/native/libharfbuzz/hb-vector.hh index cd27da96648..b650ca9f066 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-vector.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-vector.hh @@ -32,6 +32,12 @@ #include "hb-meta.hh" #include "hb-null.hh" +// Change to 1 to force inline vector allocs, to see callsite in malloc-stats tool. +#if 0 +#define HB_ALWAYS_INLINE_VECTOR_ALLOCS HB_ALWAYS_INLINE +#else +#define HB_ALWAYS_INLINE_VECTOR_ALLOCS +#endif template @@ -45,6 +51,7 @@ struct hb_vector_t using c_array_t = typename std::conditional, hb_array_t>::type; hb_vector_t () = default; + HB_ALWAYS_INLINE_VECTOR_ALLOCS hb_vector_t (std::initializer_list lst) : hb_vector_t () { alloc (lst.size (), true); @@ -57,18 +64,21 @@ struct hb_vector_t { extend (o); } + HB_ALWAYS_INLINE_VECTOR_ALLOCS hb_vector_t (const hb_vector_t &o) : hb_vector_t () { alloc_exact (o.length); if (unlikely (in_error ())) return; copy_array (o.as_array ()); } + HB_ALWAYS_INLINE_VECTOR_ALLOCS hb_vector_t (array_t o) : hb_vector_t () { alloc_exact (o.length); if (unlikely (in_error ())) return; copy_array (o); } + HB_ALWAYS_INLINE_VECTOR_ALLOCS hb_vector_t (c_array_t o) : hb_vector_t () { alloc_exact (o.length); @@ -84,8 +94,29 @@ struct hb_vector_t } ~hb_vector_t () { fini (); } + template + void + set_storage (Type (&array)[n]) + { set_storage (array, n); } + void + set_storage (hb_array_t array) + { set_storage (array.arrayZ, array.length); } + template + void + set_storage (Type *array, unsigned n) + { + assert (allocated == 0); + assert (length == 0); + + arrayZ = array; + length = n; + } + template + HB_ALWAYS_INLINE_VECTOR_ALLOCS void extend (const Iterable &o) { auto iter = hb_iter (o); @@ -106,12 +137,14 @@ struct hb_vector_t push_has_room (*iter++); } } + HB_ALWAYS_INLINE_VECTOR_ALLOCS void extend (array_t o) { alloc (length + o.length); if (unlikely (in_error ())) return; copy_array (o); } + HB_ALWAYS_INLINE_VECTOR_ALLOCS void extend (c_array_t o) { alloc (length + o.length); @@ -136,10 +169,7 @@ struct hb_vector_t void fini () { - /* We allow a hack to make the vector point to a foreign array - * by the user. In that case length/arrayZ are non-zero but - * allocated is zero. Don't free anything. */ - if (allocated) + if (is_owned ()) { shrink_vector (0); hb_free (arrayZ); @@ -147,11 +177,13 @@ struct hb_vector_t init (); } - void reset () + HB_ALWAYS_INLINE_VECTOR_ALLOCS + hb_vector_t &reset () { if (unlikely (in_error ())) reset_error (); resize (0); + return *this; } friend void swap (hb_vector_t& a, hb_vector_t& b) noexcept @@ -237,13 +269,16 @@ struct hb_vector_t Type * operator + (unsigned int i) { return arrayZ + i; } const Type * operator + (unsigned int i) const { return arrayZ + i; } + HB_ALWAYS_INLINE_VECTOR_ALLOCS Type *push () { if (unlikely (!resize (length + 1))) return std::addressof (Crap (Type)); return std::addressof (arrayZ[length - 1]); } - template Type *push (Args&&... args) + template + HB_ALWAYS_INLINE_VECTOR_ALLOCS + Type *push (Args&&... args) { if (unlikely ((int) length >= allocated && !alloc (length + 1))) // If push failed to allocate then don't copy v, since this may cause @@ -253,13 +288,20 @@ struct hb_vector_t return push_has_room (std::forward (args)...); } - template Type *push_has_room (Args&&... args) + template + HB_ALWAYS_INLINE_VECTOR_ALLOCS + Type *push_has_room (Args&&... args) { /* Emplace. */ Type *p = std::addressof (arrayZ[length++]); return new (p) Type (std::forward (args)...); } + bool is_owned () const + { + return allocated != 0 && allocated != -1; + } + bool in_error () const { return allocated < 0; } void set_error () { @@ -271,27 +313,40 @@ struct hb_vector_t assert (allocated < 0); allocated = -(allocated + 1); } + void ensure_error () + { + if (!in_error ()) + set_error (); + } - template Type * - realloc_vector (unsigned new_allocated, hb_priority<0>) + _realloc (unsigned new_allocated) { if (!new_allocated) { - hb_free (arrayZ); + if (is_owned ()) + hb_free (arrayZ); return nullptr; } + if (!allocated && arrayZ) + { + /* If we have a non-null arrayZ but allocated is 0, then we are + * reallocating from a foreign array. */ + Type *new_array = (Type *) hb_malloc (new_allocated * sizeof (Type)); + if (unlikely (!new_array)) + return nullptr; + hb_memcpy ((void *) new_array, (const void *) arrayZ, length * sizeof (Type)); + return new_array; + } return (Type *) hb_realloc (arrayZ, new_allocated * sizeof (Type)); } - template Type * - realloc_vector (unsigned new_allocated, hb_priority<0>) + _malloc_move (unsigned new_allocated) { if (!new_allocated) { - hb_free (arrayZ); + if (is_owned ()) + hb_free (arrayZ); return nullptr; } Type *new_array = (Type *) hb_malloc (new_allocated * sizeof (Type)); @@ -303,22 +358,33 @@ struct hb_vector_t new_array[i] = std::move (arrayZ[i]); arrayZ[i].~Type (); } - hb_free (arrayZ); + if (is_owned ()) + hb_free (arrayZ); } return new_array; } + + template + Type * + realloc_vector (unsigned new_allocated, hb_priority<0>) + { + return _realloc (new_allocated); + } + template + Type * + realloc_vector (unsigned new_allocated, hb_priority<0>) + { + return _malloc_move (new_allocated); + } /* Specialization for types that can be moved using realloc(). */ template Type * realloc_vector (unsigned new_allocated, hb_priority<1>) { - if (!new_allocated) - { - hb_free (arrayZ); - return nullptr; - } - return (Type *) hb_realloc (arrayZ, new_allocated * sizeof (Type)); + return _realloc (new_allocated); } template other) { - assert ((int) (length + other.length) <= allocated); hb_memcpy ((void *) (arrayZ + length), (const void *) other.arrayZ, other.length * item_size); length += other.length; } @@ -362,7 +427,6 @@ struct hb_vector_t void copy_array (hb_array_t other) { - assert ((int) (length + other.length) <= allocated); hb_memcpy ((void *) (arrayZ + length), (const void *) other.arrayZ, other.length * item_size); length += other.length; } @@ -372,7 +436,6 @@ struct hb_vector_t void copy_array (hb_array_t other) { - assert ((int) (length + other.length) <= allocated); for (unsigned i = 0; i < other.length; i++) new (std::addressof (arrayZ[length + i])) Type (other.arrayZ[i]); length += other.length; @@ -385,7 +448,6 @@ struct hb_vector_t void copy_array (hb_array_t other) { - assert ((int) (length + other.length) <= allocated); for (unsigned i = 0; i < other.length; i++) { new (std::addressof (arrayZ[length + i])) Type (); @@ -398,12 +460,12 @@ struct hb_vector_t shrink_vector (unsigned size) { assert (size <= length); - if (!std::is_trivially_destructible::value) + if (!hb_is_trivially_destructible(Type)) { unsigned count = length - size; - Type *p = arrayZ + length - 1; + Type *p = arrayZ + length; while (count--) - p--->~Type (); + (--p)->~Type (); } length = size; } @@ -416,6 +478,7 @@ struct hb_vector_t } /* Allocate for size but don't adjust length. */ + HB_ALWAYS_INLINE_VECTOR_ALLOCS bool alloc (unsigned int size, bool exact=false) { if (unlikely (in_error ())) @@ -471,17 +534,64 @@ struct hb_vector_t return true; } + HB_ALWAYS_INLINE_VECTOR_ALLOCS bool alloc_exact (unsigned int size) { return alloc (size, true); } + HB_ALWAYS_INLINE_VECTOR_ALLOCS void clear () { resize (0); } - bool resize (int size_, bool initialize = true, bool exact = false) + template + HB_ALWAYS_INLINE_VECTOR_ALLOCS + bool allocate_from_pool (allocator_t *allocator, unsigned size, unsigned int initialize = true) + { + if (allocator) + { + assert (!length && !allocated); + arrayZ = (Type *) allocator->alloc (size * sizeof (Type), alignof (Type)); + if (unlikely (!arrayZ)) + { + set_error (); + return false; + } + if (initialize) + grow_vector (size, hb_prioritize); + else + length = size; + return true; + } + return resize_full ((int) size, initialize, true); + } + + template + HB_ALWAYS_INLINE_VECTOR_ALLOCS + bool duplicate_vector_from_pool (allocator_t *allocator, const hb_vector_t &other) + { + if (unlikely (!allocate_from_pool (allocator, other.length, false))) + return false; + length = 0; + copy_array (other.as_array ()); + return true; + } + + template + void shrink_back_to_pool (allocator_t *allocator, int size) + { + unsigned orig_length = length; + + shrink (size, false); + + if (allocator && !is_owned ()) + allocator->discard (arrayZ + length, (orig_length - length) * sizeof (Type)); + } + + HB_ALWAYS_INLINE_VECTOR_ALLOCS + bool resize_full (int size_, bool initialize, bool exact) { unsigned int size = size_ < 0 ? 0u : (unsigned int) size_; if (!alloc (size, exact)) @@ -501,9 +611,20 @@ struct hb_vector_t length = size; return true; } - bool resize_exact (int size_, bool initialize = true) + HB_ALWAYS_INLINE_VECTOR_ALLOCS + bool resize (int size_) { - return resize (size_, initialize, true); + return resize_full (size_, true, false); + } + HB_ALWAYS_INLINE_VECTOR_ALLOCS + bool resize_dirty (int size_) + { + return resize_full (size_, false, false); + } + HB_ALWAYS_INLINE_VECTOR_ALLOCS + bool resize_exact (int size_) + { + return resize_full (size_, true, true); } Type pop () @@ -544,7 +665,7 @@ struct hb_vector_t shrink_vector (size); - if (shrink_memory) + if (is_owned () && shrink_memory) alloc_exact (size); /* To force shrinking memory if needed. */ } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-version.h b/src/java.desktop/share/native/libharfbuzz/hb-version.h index e41286d2d8c..c673d1e3612 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-version.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-version.h @@ -41,26 +41,26 @@ HB_BEGIN_DECLS * * The major component of the library version available at compile-time. */ -#define HB_VERSION_MAJOR 11 +#define HB_VERSION_MAJOR 12 /** * HB_VERSION_MINOR: * * The minor component of the library version available at compile-time. */ -#define HB_VERSION_MINOR 2 +#define HB_VERSION_MINOR 3 /** * HB_VERSION_MICRO: * * The micro component of the library version available at compile-time. */ -#define HB_VERSION_MICRO 0 +#define HB_VERSION_MICRO 2 /** * HB_VERSION_STRING: * * A string literal containing the library version available at compile-time. */ -#define HB_VERSION_STRING "11.2.0" +#define HB_VERSION_STRING "12.3.2" /** * HB_VERSION_ATLEAST: diff --git a/src/java.desktop/share/native/libharfbuzz/hb.hh b/src/java.desktop/share/native/libharfbuzz/hb.hh index 8c430e5770d..7582abaa933 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb.hh @@ -89,7 +89,6 @@ #pragma GCC diagnostic error "-Wstring-conversion" #pragma GCC diagnostic error "-Wswitch-enum" #pragma GCC diagnostic error "-Wtautological-overlap-compare" -#pragma GCC diagnostic error "-Wuninitialized" #pragma GCC diagnostic error "-Wunneeded-internal-declaration" #pragma GCC diagnostic error "-Wunused" #pragma GCC diagnostic error "-Wunused-local-typedefs" @@ -110,11 +109,21 @@ #pragma GCC diagnostic warning "-Wformat-signedness" #pragma GCC diagnostic warning "-Wignored-pragma-optimize" #pragma GCC diagnostic warning "-Wlogical-op" -#pragma GCC diagnostic warning "-Wmaybe-uninitialized" #pragma GCC diagnostic warning "-Wmissing-format-attribute" +#pragma GCC diagnostic warning "-Wpessimizing-move" #pragma GCC diagnostic warning "-Wundef" #pragma GCC diagnostic warning "-Wunsafe-loop-optimizations" #pragma GCC diagnostic warning "-Wunused-but-set-variable" +#ifdef __clang__ +// The following are too buggy on gcc +// https://github.com/harfbuzz/harfbuzz/issues/5589 +// https://github.com/harfbuzz/harfbuzz/pull/5367 +#pragma GCC diagnostic warning "-Wmaybe-uninitialized" +#pragma GCC diagnostic warning "-Wuninitialized" +#else +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#pragma GCC diagnostic ignored "-Wuninitialized" +#endif #endif /* Ignored currently, but should be fixed at some point. */ @@ -136,6 +145,7 @@ #pragma GCC diagnostic ignored "-Wformat-nonliteral" #pragma GCC diagnostic ignored "-Wformat-zero-length" #pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#pragma GCC diagnostic ignored "-Wold-style-cast" #pragma GCC diagnostic ignored "-Wpacked" // Erratic impl in clang #pragma GCC diagnostic ignored "-Wrange-loop-analysis" // https://github.com/harfbuzz/harfbuzz/issues/2834 #pragma GCC diagnostic ignored "-Wstrict-aliasing" @@ -239,6 +249,8 @@ // clang defines it so no need. #ifdef __has_builtin #define hb_has_builtin __has_builtin +#elif defined(_MSC_VER) +#define hb_has_builtin(x) 0 #else #define hb_has_builtin(x) ((defined(__GNUC__) && __GNUC__ >= 5)) #endif @@ -314,6 +326,10 @@ #endif #endif +#ifndef HB_HOT +#define HB_HOT __attribute__((hot)) +#endif + /* * Borrowed from https://bugzilla.mozilla.org/show_bug.cgi?id=1215411 * HB_FALLTHROUGH is an annotation to suppress compiler warnings about switch @@ -553,4 +569,13 @@ extern "C" void hb_free_impl(void *ptr); #include "hb-vector.hh" // Requires: hb-array hb-null #include "hb-object.hh" // Requires: hb-atomic hb-mutex hb-vector + +/* Our src/test-*.cc use hb_assert(), such that it's not compiled out under NDEBUG. + * https://github.com/harfbuzz/harfbuzz/issues/5418 */ +#define hb_always_assert(x) \ + HB_STMT_START { \ + if (!(x)) { fprintf(stderr, "Assertion failed: %s, at %s:%d\n", #x, __FILE__, __LINE__); abort(); } \ + } HB_STMT_END + + #endif /* HB_HH */ diff --git a/src/java.desktop/unix/classes/sun/print/AttributeClass.java b/src/java.desktop/unix/classes/sun/print/AttributeClass.java index 10d0714a059..3db6e310dd2 100644 --- a/src/java.desktop/unix/classes/sun/print/AttributeClass.java +++ b/src/java.desktop/unix/classes/sun/print/AttributeClass.java @@ -174,6 +174,30 @@ public final class AttributeClass { } + /** + * Returns 3 int values. + * xres, yres, resolution as either dpi or dpcm + * The resolution is just a single byte of data. + */ + public int[] getIntResolutionValue() { + int[] res = {0, 0, 0}; + byte[] bufArray = (byte[])myValue; + if (bufArray != null) { + int nBytes = 4; // 32-bit signed integer + for (int j=0; j<2; j++) { // 2 set of integers + byte[] intBytes = new byte[nBytes]; + // REMIND: # bytes should be 8 + for (int i=0; i< nBytes; i++) { + //+ 1 because the 1st byte is length + intBytes[i] = bufArray[i+(4*j)+1]; + } + res[j] = convertToInt(intBytes); + } + res[2] = (int)bufArray[9]; + } + return res; + } + /** * Returns String value. */ diff --git a/src/java.desktop/unix/classes/sun/print/IPPPrintService.java b/src/java.desktop/unix/classes/sun/print/IPPPrintService.java index 2bf326fca57..8a3b872b107 100644 --- a/src/java.desktop/unix/classes/sun/print/IPPPrintService.java +++ b/src/java.desktop/unix/classes/sun/print/IPPPrintService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -141,7 +141,7 @@ public final class IPPPrintService implements PrintService, SunPrinterJobService private MediaSizeName[] mediaSizeNames; private CustomMediaSizeName[] customMediaSizeNames; private int defaultMediaIndex; - private int[] rawResolutions = null; + private int[] ppdResolutions = null; private PrinterResolution[] printerResolutions = null; private boolean isCupsPrinter; private boolean init; @@ -205,8 +205,7 @@ public final class IPPPrintService implements PrintService, SunPrinterJobService OrientationRequested.PORTRAIT, new PageRanges(1), //PresentationDirection, - // CUPS does not supply printer-resolution attribute - //new PrinterResolution(300, 300, PrinterResolution.DPI), + new PrinterResolution(300, 300, PrinterResolution.DPI), //PrintQuality.NORMAL, new RequestingUserName("", Locale.getDefault()), //SheetCollate.UNCOLLATED, //CUPS has no sheet collate? @@ -467,7 +466,9 @@ public final class IPPPrintService implements PrintService, SunPrinterJobService : getSupportedOutputBins(); customMediaSizeNames = cps.getCustomMediaSizeNames(); defaultMediaIndex = cps.getDefaultMediaIndex(); - rawResolutions = cps.getRawResolutions(); + if (ppdResolutions == null) { + ppdResolutions = cps.getRawResolutions(); + } } urlConnection.disconnect(); init = true; @@ -821,14 +822,7 @@ public final class IPPPrintService implements PrintService, SunPrinterJobService } } } else if (category == PrinterResolution.class) { - PrinterResolution[] supportedRes = getPrintResolutions(); - if (supportedRes == null) { - return null; - } - PrinterResolution []arr = - new PrinterResolution[supportedRes.length]; - System.arraycopy(supportedRes, 0, arr, 0, supportedRes.length); - return arr; + return getPrintResolutions(); } else if (category == OutputBin.class) { return Arrays.copyOf(outputBins, outputBins.length); } @@ -1137,8 +1131,6 @@ public final class IPPPrintService implements PrintService, SunPrinterJobService catList.add(Chromaticity.class); } - // CUPS does not report printer resolution via IPP but it - // may be gleaned from the PPD. PrinterResolution[] supportedRes = getPrintResolutions(); if (supportedRes != null && (supportedRes.length > 0)) { catList.add(PrinterResolution.class); @@ -1264,7 +1256,6 @@ public final class IPPPrintService implements PrintService, SunPrinterJobService } } - @Override public synchronized PrintServiceAttributeSet getAttributes() { if (!init) { @@ -1684,9 +1675,7 @@ public final class IPPPrintService implements PrintService, SunPrinterJobService } else if (category == PrinterResolution.class) { PrinterResolution[] supportedRes = getPrintResolutions(); if ((supportedRes != null) && (supportedRes.length > 0)) { - return supportedRes[0]; - } else { - return new PrinterResolution(300, 300, PrinterResolution.DPI); + return supportedRes[0]; } } else if (category == OutputBin.class) { if (attribClass != null) { @@ -1697,26 +1686,40 @@ public final class IPPPrintService implements PrintService, SunPrinterJobService return null; } + /* Called only from contexts that have called initAttributes(). + * Try IPP first, and if that produces nothing, fall back to the PPD + */ private PrinterResolution[] getPrintResolutions() { + int[] rawResolutions = null; if (printerResolutions == null) { - if (rawResolutions == null) { - printerResolutions = new PrinterResolution[0]; - } else { - int numRes = rawResolutions.length / 2; - PrinterResolution[] pres = new PrinterResolution[numRes]; - for (int i=0; i < numRes; i++) { - pres[i] = new PrinterResolution(rawResolutions[i*2], - rawResolutions[i*2+1], - PrinterResolution.DPI); - } - printerResolutions = pres; + AttributeClass attribClass = (getAttMap != null) ? + getAttMap.get("printer-resolution-supported") + : null; + if (attribClass != null) { + rawResolutions = attribClass.getIntResolutionValue(); } + if (rawResolutions == null) { + rawResolutions = ppdResolutions; + } + if (rawResolutions == null) { + rawResolutions = new int[] { 300, 300, 3 } ; + } + int numRes = rawResolutions.length / 3; + PrinterResolution[] pres = new PrinterResolution[numRes]; + for (int i = 0; i < numRes; i++) { + int units = (rawResolutions[i*3+2] == 4) ? PrinterResolution.DPCM : PrinterResolution.DPI; + pres[i] = new PrinterResolution(rawResolutions[i*3], + rawResolutions[i*3+1], + units); + } + printerResolutions = pres; } - return printerResolutions; + return printerResolutions.clone(); } private boolean isSupportedResolution(PrinterResolution res) { - PrinterResolution[] supportedRes = getPrintResolutions(); + PrinterResolution[] supportedRes = + (PrinterResolution[])getSupportedAttributeValues(PrinterResolution.class, null, null); if (supportedRes != null) { for (int i=0; iNewObject(env, intCls, intCtr, 3); + CHECK_NULL(dpi); // NOTE: cupsGetPPD returns a pointer to a filename of a temporary file. // unlink() must be called to remove the file after using it. @@ -672,6 +691,7 @@ Java_sun_print_CUPSPrinter_getResolutions(JNIEnv *env, CHECK_NULL(ryObj); (*env)->CallBooleanMethod(env, arrayList, arrListAddMID, rxObj); (*env)->CallBooleanMethod(env, arrayList, arrListAddMID, ryObj); + (*env)->CallBooleanMethod(env, arrayList, arrListAddMID, dpi); } for (i = 0; i < resolution->num_choices; i++) { @@ -700,6 +720,41 @@ Java_sun_print_CUPSPrinter_getResolutions(JNIEnv *env, CHECK_NULL(ryObj); (*env)->CallBooleanMethod(env, arrayList, arrListAddMID, rxObj); (*env)->CallBooleanMethod(env, arrayList, arrListAddMID, ryObj); + (*env)->CallBooleanMethod(env, arrayList, arrListAddMID, dpi); + } + } + + } else { + ppd_attr_t *defresolution = j2d_ppdFindAttr(ppd, "DefaultResolution", NULL); + if (defresolution == NULL) { + defresolution = j2d_ppdFindAttr(ppd, "Resolution", NULL); + } + if (defresolution != NULL) { + int matches = sscanf(defresolution->value, "%dx%ddpi", &defx, &defy); + if (matches == 2) { + if (defx <= 0 || defy <= 0) { + defx = 0; + defy = 0; + } + } else { + matches = sscanf(defresolution->value, "%ddpi", &defx); + if (matches == 1) { + if (defx <= 0) { + defx = 0; + } else { + defy = defx; + } + } + } + if (defx > 0) { + jobject rxObj, ryObj; + rxObj = (*env)->NewObject(env, intCls, intCtr, defx); + CHECK_NULL(rxObj); + ryObj = (*env)->NewObject(env, intCls, intCtr, defy); + CHECK_NULL(ryObj); + (*env)->CallBooleanMethod(env, arrayList, arrListAddMID, rxObj); + (*env)->CallBooleanMethod(env, arrayList, arrListAddMID, ryObj); + (*env)->CallBooleanMethod(env, arrayList, arrListAddMID, dpi); } } } diff --git a/src/java.desktop/unix/native/common/awt/utility/rect.h b/src/java.desktop/unix/native/common/awt/utility/rect.h index ceea38f4349..91b5a17ec58 100644 --- a/src/java.desktop/unix/native/common/awt/utility/rect.h +++ b/src/java.desktop/unix/native/common/awt/utility/rect.h @@ -28,7 +28,7 @@ #ifndef _AWT_RECT_H #define _AWT_RECT_H -#ifndef MACOSX +#if !defined(HEADLESS) && !defined(MACOSX) #include typedef XRectangle RECT_T; #else @@ -39,7 +39,7 @@ typedef struct { int width; int height; } RECT_T; -#endif /* !MACOSX */ +#endif /* !HEADLESS && !MACOSX */ #define RECT_EQ_X(r1,r2) ((r1).x==(r2).x && (r1).width==(r2).width) diff --git a/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c b/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c index 03dba969e8d..6ed23ca7541 100644 --- a/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c +++ b/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c @@ -602,6 +602,9 @@ GtkApi* gtk3_load(JNIEnv *env, const char* lib_name) fp_g_uuid_string_is_valid = //since: 2.52 dl_symbol("g_uuid_string_is_valid"); fp_g_variant_print = dl_symbol("g_variant_print"); // since 2.24 + + fp_g_settings_new = dl_symbol("g_settings_new"); // since 2.26 + fp_g_settings_get_string = dl_symbol("g_settings_get_string"); // since 2.26 } fp_g_string_printf = dl_symbol("g_string_printf"); fp_g_strconcat = dl_symbol("g_strconcat"); @@ -2987,6 +2990,37 @@ static GdkWindow* gtk3_get_window(void *widget) { return fp_gtk_widget_get_window((GtkWidget*)widget); } +static gboolean apply_theme_if_needed() { + if (!glib_version_2_68) { + return FALSE; + } + + GSettings *settings = fp_g_settings_new("org.gnome.desktop.interface"); + if (!settings) { + return FALSE; + } + + static gboolean wasDark = FALSE; + + gchar *scheme = fp_g_settings_get_string(settings, "color-scheme"); + const gboolean isDark = strcmp(scheme, "prefer-dark") == 0; + + fp_g_free(scheme); + fp_g_object_unref(settings); + + if (wasDark ^ isDark) { + GtkSettings* gtkSettings = fp_gtk_settings_get_default(); + if (!gtkSettings) { + return FALSE; + } + fp_g_object_set(gtkSettings, "gtk-application-prefer-dark-theme", isDark, NULL); + wasDark = isDark; + return TRUE; + } + + return FALSE; +} + static void gtk3_init(GtkApi* gtk) { gtk->version = GTK_3; @@ -2996,6 +3030,8 @@ static void gtk3_init(GtkApi* gtk) { gtk->gtk_check_version = fp_gtk_check_version; gtk->get_setting = >k3_get_setting; + gtk->apply_theme_if_needed = &apply_theme_if_needed; + gtk->paint_arrow = >k3_paint_arrow; gtk->paint_box = >k3_paint_box; gtk->paint_box_gap = >k3_paint_box_gap; diff --git a/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.h b/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.h index d3a83677dd6..637a3198e43 100644 --- a/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.h +++ b/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.h @@ -193,6 +193,7 @@ typedef void GtkMenuShell; typedef void GtkWidgetClass; typedef void PangoFontDescription; typedef void GtkSettings; +typedef void GSettings; typedef void GtkStyleProvider; typedef void cairo_pattern_t; typedef void cairo_t; @@ -633,6 +634,10 @@ static char* (*fp_pango_font_description_to_string)( const PangoFontDescription* fd); static GtkSettings* (*fp_gtk_settings_get_default)(); static GtkSettings* (*fp_gtk_widget_get_settings)(GtkWidget *widget); + +static GSettings *(*fp_g_settings_new)(const gchar *schema_id); +static gchar *(*fp_g_settings_get_string)(GSettings *settings, const gchar *key); + static GType (*fp_gtk_border_get_type)(); static void (*fp_gtk_arrow_set)(GtkWidget* arrow, GtkArrowType arrow_type, diff --git a/src/java.desktop/unix/native/libawt_xawt/awt/gtk_interface.h b/src/java.desktop/unix/native/libawt_xawt/awt/gtk_interface.h index 39be6a735d7..37422094202 100644 --- a/src/java.desktop/unix/native/libawt_xawt/awt/gtk_interface.h +++ b/src/java.desktop/unix/native/libawt_xawt/awt/gtk_interface.h @@ -541,6 +541,8 @@ typedef struct GtkApi { guint required_micro); jobject (*get_setting)(JNIEnv *env, Setting property); + gboolean (*apply_theme_if_needed)(); + void (*paint_arrow)(WidgetType widget_type, GtkStateType state_type, GtkShadowType shadow_type, const gchar *detail, gint x, gint y, gint width, gint height, diff --git a/src/java.desktop/unix/native/libawt_xawt/awt/swing_GTKEngine.c b/src/java.desktop/unix/native/libawt_xawt/awt/swing_GTKEngine.c index bb5c799f008..3b7b2880316 100644 --- a/src/java.desktop/unix/native/libawt_xawt/awt/swing_GTKEngine.c +++ b/src/java.desktop/unix/native/libawt_xawt/awt/swing_GTKEngine.c @@ -388,3 +388,17 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_nativeSetRangeValue( gtk->set_range_value(widget_type, value, min, max, visible); gtk->gdk_threads_leave(); } + +/* + * Class: com_sun_java_swing_plaf_gtk_GTKLookAndFeel + * Method: applyThemeIfNeeded + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL +Java_com_sun_java_swing_plaf_gtk_GTKLookAndFeel_applyThemeIfNeeded(JNIEnv *env, jobject this) { + gtk->gdk_threads_enter(); + const gboolean result = gtk->apply_theme_if_needed(); + gtk->gdk_threads_leave(); + + return result; +} diff --git a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/AnimationController.java b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/AnimationController.java index 4fb843543e3..06574d17641 100644 --- a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/AnimationController.java +++ b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/AnimationController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2026, Oracle and/or its affiliates. All rights reserved. * 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,8 +39,6 @@ import com.sun.java.swing.plaf.windows.TMSchema.Part; import com.sun.java.swing.plaf.windows.TMSchema.Prop; import com.sun.java.swing.plaf.windows.XPStyle.Skin; -import sun.awt.AppContext; - /** * A class to help mimic Vista theme animations. The only kind of * animation it handles for now is 'transition' animation (this seems @@ -68,8 +66,7 @@ final class AnimationController implements ActionListener, PropertyChangeListene Boolean.getBoolean("swing.disablevistaanimation"); - private static final Object ANIMATION_CONTROLLER_KEY = - new StringBuilder("ANIMATION_CONTROLLER_KEY"); + private static AnimationController animationController; private final Map> animationStateMap = new WeakHashMap>(); @@ -80,13 +77,10 @@ final class AnimationController implements ActionListener, PropertyChangeListene new javax.swing.Timer(1000/30, this); private static synchronized AnimationController getAnimationController() { - AppContext appContext = AppContext.getAppContext(); - Object obj = appContext.get(ANIMATION_CONTROLLER_KEY); - if (obj == null) { - obj = new AnimationController(); - appContext.put(ANIMATION_CONTROLLER_KEY, obj); + if (animationController == null) { + animationController = new AnimationController(); } - return (AnimationController) obj; + return animationController; } private AnimationController() { @@ -316,8 +310,7 @@ final class AnimationController implements ActionListener, PropertyChangeListene timer.stop(); UIManager.removePropertyChangeListener(this); synchronized (AnimationController.class) { - AppContext.getAppContext() - .put(ANIMATION_CONTROLLER_KEY, null); + animationController = null; } } diff --git a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsButtonUI.java b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsButtonUI.java index 0c86bd33e10..ee07276aa30 100644 --- a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsButtonUI.java +++ b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsButtonUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,8 +47,6 @@ import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicButtonUI; import javax.swing.plaf.basic.BasicGraphicsUtils; -import sun.awt.AppContext; - import static com.sun.java.swing.plaf.windows.TMSchema.Part; import static com.sun.java.swing.plaf.windows.TMSchema.State; import static com.sun.java.swing.plaf.windows.XPStyle.Skin; @@ -69,20 +67,13 @@ public final class WindowsButtonUI extends BasicButtonUI private boolean defaults_initialized = false; - private static final Object WINDOWS_BUTTON_UI_KEY = new Object(); + private static final ComponentUI UI = new WindowsButtonUI(); // ******************************** // Create PLAF // ******************************** public static ComponentUI createUI(JComponent c) { - AppContext appContext = AppContext.getAppContext(); - WindowsButtonUI windowsButtonUI = - (WindowsButtonUI) appContext.get(WINDOWS_BUTTON_UI_KEY); - if (windowsButtonUI == null) { - windowsButtonUI = new WindowsButtonUI(); - appContext.put(WINDOWS_BUTTON_UI_KEY, windowsButtonUI); - } - return windowsButtonUI; + return UI; } diff --git a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsCheckBoxUI.java b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsCheckBoxUI.java index 3c869efc97b..7cb2490fd76 100644 --- a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsCheckBoxUI.java +++ b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsCheckBoxUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,8 +30,6 @@ import javax.swing.JComponent; import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; -import sun.awt.AppContext; - /** * Windows check box. * @@ -43,7 +41,7 @@ public final class WindowsCheckBoxUI extends WindowsRadioButtonUI // of BasicCheckBoxUI because we want to pick up all the // painting changes made in WindowsRadioButtonUI. - private static final Object WINDOWS_CHECK_BOX_UI_KEY = new Object(); + private static final ComponentUI UI = new WindowsCheckBoxUI(); private static final String propertyPrefix = "CheckBox" + "."; @@ -53,14 +51,7 @@ public final class WindowsCheckBoxUI extends WindowsRadioButtonUI // Create PLAF // ******************************** public static ComponentUI createUI(JComponent c) { - AppContext appContext = AppContext.getAppContext(); - WindowsCheckBoxUI windowsCheckBoxUI = - (WindowsCheckBoxUI) appContext.get(WINDOWS_CHECK_BOX_UI_KEY); - if (windowsCheckBoxUI == null) { - windowsCheckBoxUI = new WindowsCheckBoxUI(); - appContext.put(WINDOWS_CHECK_BOX_UI_KEY, windowsCheckBoxUI); - } - return windowsCheckBoxUI; + return UI; } diff --git a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsLabelUI.java b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsLabelUI.java index 403468af0af..4283f743b97 100644 --- a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsLabelUI.java +++ b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsLabelUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,6 @@ import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicLabelUI; -import sun.awt.AppContext; import sun.swing.MnemonicHandler; import sun.swing.SwingUtilities2; @@ -43,20 +42,13 @@ import sun.swing.SwingUtilities2; */ public final class WindowsLabelUI extends BasicLabelUI { - private static final Object WINDOWS_LABEL_UI_KEY = new Object(); + private static final ComponentUI UI = new WindowsLabelUI(); // ******************************** // Create PLAF // ******************************** public static ComponentUI createUI(JComponent c) { - AppContext appContext = AppContext.getAppContext(); - WindowsLabelUI windowsLabelUI = - (WindowsLabelUI) appContext.get(WINDOWS_LABEL_UI_KEY); - if (windowsLabelUI == null) { - windowsLabelUI = new WindowsLabelUI(); - appContext.put(WINDOWS_LABEL_UI_KEY, windowsLabelUI); - } - return windowsLabelUI; + return UI; } @Override diff --git a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsMenuItemUI.java b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsMenuItemUI.java index 61f760d63c4..d15bc93a628 100644 --- a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsMenuItemUI.java +++ b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsMenuItemUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -238,6 +238,15 @@ public final class WindowsMenuItemUI extends BasicMenuItemUI { SwingUtilities3.paintAccText(g, lh, lr, disabledForeground, acceleratorSelectionForeground, acceleratorForeground); + if (lh.getCheckIcon() != null && lh.useCheckAndArrow()) { + Rectangle rect = lr.getArrowRect(); + if (menuItem.getComponentOrientation().isLeftToRight()) { + rect.x += lh.getAfterCheckIconGap(); + } else { + rect.x -= lh.getAfterCheckIconGap(); + } + lr.setArrowRect(rect); + } SwingUtilities3.paintArrowIcon(g, lh, lr, foreground); // Restore original graphics font and color diff --git a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsRadioButtonUI.java b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsRadioButtonUI.java index 2a784a470a4..c62a9ec8586 100644 --- a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsRadioButtonUI.java +++ b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsRadioButtonUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,14 +38,12 @@ import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicGraphicsUtils; import javax.swing.plaf.basic.BasicRadioButtonUI; -import sun.awt.AppContext; - /** * Windows rendition of the component. */ public class WindowsRadioButtonUI extends BasicRadioButtonUI { - private static final Object WINDOWS_RADIO_BUTTON_UI_KEY = new Object(); + private static final ComponentUI UI = new WindowsRadioButtonUI(); protected int dashedRectGapX; protected int dashedRectGapY; @@ -60,14 +58,7 @@ public class WindowsRadioButtonUI extends BasicRadioButtonUI // Create PLAF // ******************************** public static ComponentUI createUI(JComponent c) { - AppContext appContext = AppContext.getAppContext(); - WindowsRadioButtonUI windowsRadioButtonUI = - (WindowsRadioButtonUI) appContext.get(WINDOWS_RADIO_BUTTON_UI_KEY); - if (windowsRadioButtonUI == null) { - windowsRadioButtonUI = new WindowsRadioButtonUI(); - appContext.put(WINDOWS_RADIO_BUTTON_UI_KEY, windowsRadioButtonUI); - } - return windowsRadioButtonUI; + return UI; } // ******************************** diff --git a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsToggleButtonUI.java b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsToggleButtonUI.java index 5e94ebdb2cc..67eb5c1d6a0 100644 --- a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsToggleButtonUI.java +++ b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsToggleButtonUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,8 +38,6 @@ import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicGraphicsUtils; import javax.swing.plaf.basic.BasicToggleButtonUI; -import sun.awt.AppContext; - /** * A Windows toggle button. * @@ -54,19 +52,12 @@ public final class WindowsToggleButtonUI extends BasicToggleButtonUI protected Color focusColor; - private static final Object WINDOWS_TOGGLE_BUTTON_UI_KEY = new Object(); + private static final ComponentUI UI = new WindowsToggleButtonUI(); private boolean defaults_initialized = false; public static ComponentUI createUI(JComponent b) { - AppContext appContext = AppContext.getAppContext(); - WindowsToggleButtonUI windowsToggleButtonUI = - (WindowsToggleButtonUI) appContext.get(WINDOWS_TOGGLE_BUTTON_UI_KEY); - if (windowsToggleButtonUI == null) { - windowsToggleButtonUI = new WindowsToggleButtonUI(); - appContext.put(WINDOWS_TOGGLE_BUTTON_UI_KEY, windowsToggleButtonUI); - } - return windowsToggleButtonUI; + return UI; } diff --git a/src/java.desktop/windows/classes/sun/awt/windows/WPrinterJob.java b/src/java.desktop/windows/classes/sun/awt/windows/WPrinterJob.java index 01be8587685..1da9db3a35b 100644 --- a/src/java.desktop/windows/classes/sun/awt/windows/WPrinterJob.java +++ b/src/java.desktop/windows/classes/sun/awt/windows/WPrinterJob.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1733,6 +1733,10 @@ public final class WPrinterJob extends RasterPrinterJob if (isRangeSet) { attributes.add(new PageRanges(from, to)); setPageRange(from, to); + } else { + attributes.remove(PageRanges.class); + setPageRange(Pageable.UNKNOWN_NUMBER_OF_PAGES, + Pageable.UNKNOWN_NUMBER_OF_PAGES); } defaultCopies = false; attributes.add(new Copies(copies)); diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/quic/PeerConnIdManager.java b/src/java.net.http/share/classes/jdk/internal/net/http/quic/PeerConnIdManager.java index 065d045b57c..2bc759a920a 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/quic/PeerConnIdManager.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/quic/PeerConnIdManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ import java.nio.ByteBuffer; import java.util.ArrayDeque; import java.util.Collections; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.NavigableMap; import java.util.NavigableSet; @@ -276,6 +277,28 @@ final class PeerConnIdManager { } } + /** + * {@return the list of stateless reset tokens associated with active peer connection IDs} + */ + public List activeResetTokens() { + lock.lock(); + try { + // we only support one active connection ID at the time + PeerConnectionId cid = peerConnectionIds.get(activeConnIdSeq); + byte[] statelessResetToken = null; + if (cid != null) { + statelessResetToken = cid.getStatelessResetToken(); + } + if (statelessResetToken != null) { + return List.of(statelessResetToken); + } else { + return List.of(); + } + } finally { + lock.unlock(); + } + } + /** * {@return the active peer connection ID} */ diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/quic/QuicConnectionImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/quic/QuicConnectionImpl.java index 580bbe23d31..edb94d5929a 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/quic/QuicConnectionImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/quic/QuicConnectionImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1246,7 +1246,7 @@ public class QuicConnectionImpl extends QuicConnection implements QuicPacketRece final PacketSpace space = packetSpace(PacketNumberSpace.APPLICATION); final int maxDatagramSize = getMaxDatagramSize(); final QuicConnectionId peerConnectionId = peerConnectionId(); - final int dstIdLength = peerConnectionId().length(); + final int dstIdLength = peerConnectionId.length(); if (!canSend()) { return false; } @@ -1747,6 +1747,11 @@ public class QuicConnectionImpl extends QuicConnection implements QuicPacketRece return localConnIdManager.connectionIds(); } + @Override + public List activeResetTokens() { + return peerConnIdManager.activeResetTokens(); + } + LocalConnIdManager localConnectionIdManager() { return localConnIdManager; } @@ -2453,7 +2458,7 @@ public class QuicConnectionImpl extends QuicConnection implements QuicPacketRece } return; } - final QuicConnectionId currentPeerConnId = this.peerConnIdManager.getPeerConnId(); + final QuicConnectionId currentPeerConnId = peerConnectionId(); if (rt.sourceId().equals(currentPeerConnId)) { if (debug.on()) { debug.log("Invalid retry, same connection ID"); diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/quic/QuicEndpoint.java b/src/java.net.http/share/classes/jdk/internal/net/http/quic/QuicEndpoint.java index 91b4a678a23..ef342d4cb56 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/quic/QuicEndpoint.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/quic/QuicEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1572,14 +1572,14 @@ public abstract sealed class QuicEndpoint implements AutoCloseable private void dropPeerIssuedResetTokensFor(QuicPacketReceiver connection) { // remove references to this connection from the map which holds the peer issued // reset tokens - peerIssuedResetTokens.values().removeIf(conn -> connection == conn); + connection.activeResetTokens().forEach(this::forgetStatelessResetToken); } - // remap peer issued stateless token from connection `from` to connection `to` - private void remapPeerIssuedResetToken(QuicPacketReceiver from, QuicPacketReceiver to) { - assert from != null; - assert to != null; - peerIssuedResetTokens.replaceAll((tok, c) -> c == from ? to : c); + // remap peer issued stateless tokens to connection `newReceiver` + private void remapPeerIssuedResetToken(QuicPacketReceiver newReceiver) { + assert newReceiver != null; + newReceiver.activeResetTokens().forEach(resetToken -> + associateStatelessResetToken(resetToken, newReceiver)); } public void draining(final QuicConnectionImpl connection) { @@ -1588,9 +1588,10 @@ public abstract sealed class QuicEndpoint implements AutoCloseable final long idleTimeout = connection.peerPtoMs() * 3; // 3 PTO connection.localConnectionIdManager().close(); - DrainingConnection draining = new DrainingConnection(connection.connectionIds(), idleTimeout); + DrainingConnection draining = new DrainingConnection(connection.connectionIds(), + connection.activeResetTokens(), idleTimeout); // we can ignore stateless reset in the draining state. - remapPeerIssuedResetToken(connection, draining); + remapPeerIssuedResetToken(draining); connection.connectionIds().forEach((id) -> connections.compute(id, (i, r) -> remapDraining(i, r, draining))); @@ -1626,8 +1627,9 @@ public abstract sealed class QuicEndpoint implements AutoCloseable final long idleTimeout = connection.peerPtoMs() * 3; // 3 PTO connection.localConnectionIdManager().close(); - var closingConnection = new ClosingConnection(connection.connectionIds(), idleTimeout, datagram); - remapPeerIssuedResetToken(connection, closingConnection); + var closingConnection = new ClosingConnection(connection.connectionIds(), + connection.activeResetTokens(), idleTimeout, datagram); + remapPeerIssuedResetToken(closingConnection); connection.connectionIds().forEach((id) -> connections.compute(id, (i, r) -> remapClosing(i, r, closingConnection))); @@ -1745,6 +1747,7 @@ public abstract sealed class QuicEndpoint implements AutoCloseable // an instance of this class) final static long NO_IDLE_TIMEOUT = 2000; final List localConnectionIds; + private final List activeResetTokens; final long maxIdleTimeMs; final long id; int more = 1; @@ -1752,7 +1755,8 @@ public abstract sealed class QuicEndpoint implements AutoCloseable volatile Deadline deadline; volatile Deadline updatedDeadline; - ClosedConnection(List localConnectionIds, long maxIdleTimeMs) { + ClosedConnection(List localConnectionIds, List activeResetTokens, long maxIdleTimeMs) { + this.activeResetTokens = activeResetTokens; this.id = QuicTimerQueue.newEventId(); this.maxIdleTimeMs = maxIdleTimeMs == 0 ? NO_IDLE_TIMEOUT : maxIdleTimeMs; this.deadline = Deadline.MAX; @@ -1765,6 +1769,11 @@ public abstract sealed class QuicEndpoint implements AutoCloseable return localConnectionIds; } + @Override + public List activeResetTokens() { + return activeResetTokens; + } + @Override public final void processIncoming(SocketAddress source, ByteBuffer destConnId, HeadersType headersType, ByteBuffer buffer) { Deadline updated = updatedDeadline; @@ -1868,9 +1877,9 @@ public abstract sealed class QuicEndpoint implements AutoCloseable final ByteBuffer closePacket; - ClosingConnection(List localConnIdManager, long maxIdleTimeMs, + ClosingConnection(List localConnectionIds, List activeResetTokens, long maxIdleTimeMs, ByteBuffer closePacket) { - super(localConnIdManager, maxIdleTimeMs); + super(localConnectionIds, activeResetTokens, maxIdleTimeMs); this.closePacket = Objects.requireNonNull(closePacket); } @@ -1903,8 +1912,8 @@ public abstract sealed class QuicEndpoint implements AutoCloseable */ final class DrainingConnection extends ClosedConnection { - DrainingConnection(List localConnIdManager, long maxIdleTimeMs) { - super(localConnIdManager, maxIdleTimeMs); + DrainingConnection(List localConnectionIds, List activeResetTokens, long maxIdleTimeMs) { + super(localConnectionIds, activeResetTokens, maxIdleTimeMs); } @Override diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/quic/QuicPacketReceiver.java b/src/java.net.http/share/classes/jdk/internal/net/http/quic/QuicPacketReceiver.java index 6652b44de3a..72f622731f3 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/quic/QuicPacketReceiver.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/quic/QuicPacketReceiver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,6 +51,11 @@ public interface QuicPacketReceiver { */ List connectionIds(); + /** + * {@return a list of active peer stateless reset tokens for this connection) + */ + List activeResetTokens(); + /** * {@return the initial connection id assigned by the peer} * On the client side, this is always {@link Optional#empty()}. diff --git a/src/java.security.jgss/windows/man/kinit.md b/src/java.security.jgss/windows/man/kinit.md index 130bf7b007a..a32d6634e74 100644 --- a/src/java.security.jgss/windows/man/kinit.md +++ b/src/java.security.jgss/windows/man/kinit.md @@ -1,5 +1,5 @@ --- -# Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2026, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -79,34 +79,34 @@ will compromise your password. You can specify one of the following commands. After the command, specify the options for it. -`-A` +[`-A`]{#option-A} : Doesn't include addresses. -`-f` +[`-f`]{#option-f} : Issues a forwardable ticket. -`-p` +[`-p`]{#option-p} : Issues a proxiable ticket. -`-c` *cache\_name* +[`-c`]{#option-c} *cache\_name* : The cache name (for example, `FILE:D:\temp\mykrb5cc`). -`-l` *lifetime* +[`-l`]{#option-l} *lifetime* : Sets the lifetime of a ticket. The value can be one of "h:m[:s]", "NdNhNmNs", and "N". See the [MIT krb5 Time Duration definition]( http://web.mit.edu/kerberos/krb5-1.17/doc/basic/date_format.html#duration) for more information. -`-r` *renewable\_time* +[`-r`]{#option-r} *renewable\_time* : Sets the total lifetime that a ticket can be renewed. -`-R` +[`-R`]{#option-R} : Renews a ticket. -`-k` +[`-k`]{#option-k} : Uses keytab -`-t` *keytab\_filename* +[`-t`]{#option-t} *keytab\_filename* : The keytab name (for example, `D:\winnt\profiles\duke\krb5.keytab`). *principal* diff --git a/src/java.security.jgss/windows/man/klist.md b/src/java.security.jgss/windows/man/klist.md index 67c84e65dec..c4874f7dc67 100644 --- a/src/java.security.jgss/windows/man/klist.md +++ b/src/java.security.jgss/windows/man/klist.md @@ -1,5 +1,5 @@ --- -# Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2026, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ the contents of the credentials cache or keytab using the `klist` tool. The ## Commands -`-c` +[`-c`]{#option-c} : Specifies that the credential cache is to be listed. The following are the options for credential cache entries: @@ -62,7 +62,7 @@ the contents of the credentials cache or keytab using the `klist` tool. The `-n` : If the `-a` option is specified, don't reverse resolve addresses. -`-k` +[`-k`]{#option-k} : Specifies that key tab is to be listed. List the keytab entries. The following are the options for keytab entries: diff --git a/src/java.security.jgss/windows/man/ktab.md b/src/java.security.jgss/windows/man/ktab.md index d6817ab81cf..36e09d56e3e 100644 --- a/src/java.security.jgss/windows/man/ktab.md +++ b/src/java.security.jgss/windows/man/ktab.md @@ -1,5 +1,5 @@ --- -# Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2026, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -72,12 +72,12 @@ send a keytab file over a network in the clear. ## Commands and Options -`-l` \[`-e`\] \[`-t`\] +[`-l`]{#command-l} \[`-e`\] \[`-t`\] : Lists the keytab name and entries. When `-e` is specified, the encryption type for each entry is displayed. When `-t` is specified, the timestamp for each entry is displayed. -`-a` *principal\_name* \[*password*\] \[`-n` *kvno*\] \[`-s` *salt* \| `-f`\] \[`-append`\] +[`-a`]{#command-a} *principal\_name* \[*password*\] \[`-n` *kvno*\] \[`-s` *salt* \| `-f`\] \[`-append`\] : Adds new key entries to the keytab for the given principal name with an optional *password*. If a *kvno* is specified, new keys' Key Version Numbers equal to the value, otherwise, automatically incrementing the Key @@ -90,7 +90,7 @@ send a keytab file over a network in the clear. on the command line or in a script.** This tool will prompt for a password if it isn't specified. -`-d` *principal\_name* \[`-f`\] \[`-e` *etype*\] \[*kvno* \| `all`\| `old`\] +[`-d`]{#command-d} *principal\_name* \[`-f`\] \[`-e` *etype*\] \[*kvno* \| `all`\| `old`\] : Deletes key entries from the keytab for the specified principal. No changes are made to the Kerberos database. @@ -115,7 +115,7 @@ send a keytab file over a network in the clear. This option can be used with the `-l`, `-a` or `-d` commands. -`-k` *keytab name* +[`-k`]{#option-k} *keytab name* : Specifies the keytab name and path with the `FILE:` prefix. ## Examples diff --git a/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java b/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java index 998e8d037b4..4a1cd3aba78 100644 --- a/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java +++ b/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java @@ -26,11 +26,13 @@ package sun.tools.attach; import com.sun.tools.attach.AgentLoadException; import com.sun.tools.attach.AttachNotSupportedException; +import com.sun.tools.attach.AttachOperationFailedException; import com.sun.tools.attach.spi.AttachProvider; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -42,6 +44,7 @@ import java.util.regex.Pattern; import static java.nio.charset.StandardCharsets.UTF_8; import sun.jvmstat.monitor.MonitoredHost; +import sun.jvmstat.monitor.MonitorException; /* * Linux implementation of HotSpotVirtualMachine @@ -251,24 +254,26 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { return f; } - private String findTargetProcessTmpDirectory(long pid) throws AttachNotSupportedException { + private String findTargetProcessTmpDirectory(long pid) throws IOException { final var tmpOnProcPidRoot = PROC.resolve(Long.toString(pid)).resolve(ROOT_TMP); /* We need to handle at least 4 different cases: - * 1. Caller and target processes share PID namespace and root filesystem (host to host or container to - * container with both /tmp mounted between containers). - * 2. Caller and target processes share PID namespace and root filesystem but the target process has elevated - * privileges (host to host). - * 3. Caller and target processes share PID namespace but NOT root filesystem (container to container). - * 4. Caller and target processes share neither PID namespace nor root filesystem (host to container) + * 1. Caller and target processes share PID namespace and root + * filesystem (host to host or container to container with both /tmp + * mounted between containers). + * 2. Caller and target processes share PID namespace and root + * filesystem but the target process has elevated privileges + * (host to host). + * 3. Caller and target processes share PID namespace but NOT root + * filesystem (container to container). + * 4. Caller and target processes share neither PID namespace nor root + * filesystem (host to container) * - * if target is elevated, we cant use /proc//... so we have to fallback to /tmp, but that may not be shared - * with the target/attachee process, so we should check whether /tmp on both is same. This method would throw - * AttachNotSupportedException if they are different because we cannot make a connection with target VM. - * - * In addition, we can also check the target pid's signal masks to see if it catches SIGQUIT and only do so if in - * fact it does ... this reduces the risk of killing an innocent process in the current ns as opposed to - * attaching to the actual target JVM ... c.f: checkCatchesAndSendQuitTo() below. + * if target is elevated, we cant use /proc//... so we have to + * fallback to /tmp, but that may not be shared with the target/attachee + * process, so we should check whether /tmp on both is same. This method + * would throw AttachOperationFailedException if they are different + * because we cannot make a connection with target VM. */ try { @@ -277,7 +282,7 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { } else if (Files.isSameFile(tmpOnProcPidRoot, TMPDIR)) { return TMPDIR.toString(); } else { - throw new AttachNotSupportedException("Unable to access the filesystem of the target process"); + throw new AttachOperationFailedException("Unable to access the filesystem of the target process"); } } catch (IOException ioe) { try { @@ -290,15 +295,19 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { // even if we cannot access /proc//root. // The process with capsh/setcap would fall this pattern. return TMPDIR.toString(); - } else { - throw new AttachNotSupportedException("Unable to access the filesystem of the target process", ioe); } - } catch (AttachNotSupportedException e) { - // AttachNotSupportedException happened in above should go through - throw e; - } catch (Exception e) { - // Other exceptions would be wrapped with AttachNotSupportedException - throw new AttachNotSupportedException("Unable to access the filesystem of the target process", e); + // Throw original IOE if target process not found on localhost. + throw ioe; + } catch (URISyntaxException e) { + // URISyntaxException is defined as a checked exception at + // MonitoredHost.getMonitoredHost() if the URI string poorly + // formed. However "//localhost" is hard-coded at here, so the + // exception should not happen. + throw new AssertionError("Unexpected exception", e); + } catch (MonitorException e) { + // Other exceptions (happened at MonitoredHost) would be wrapped + // with AttachOperationFailedException. + throw new AttachOperationFailedException("Unable to find target proces", e); } } } diff --git a/src/jdk.attach/share/classes/com/sun/tools/attach/AttachNotSupportedException.java b/src/jdk.attach/share/classes/com/sun/tools/attach/AttachNotSupportedException.java index 725db3e7732..050c1030bf6 100644 --- a/src/jdk.attach/share/classes/com/sun/tools/attach/AttachNotSupportedException.java +++ b/src/jdk.attach/share/classes/com/sun/tools/attach/AttachNotSupportedException.java @@ -62,17 +62,4 @@ public class AttachNotSupportedException extends Exception { super(s); } - /** - * Constructs an AttachNotSupportedException with - * the specified cause. - * - * @param message the detail message. - * @param cause the cause of this exception. - * - * @since 27 - */ - public AttachNotSupportedException(String message, Throwable cause) { - super(message, cause); - } - } diff --git a/src/jdk.attach/share/classes/com/sun/tools/attach/AttachOperationFailedException.java b/src/jdk.attach/share/classes/com/sun/tools/attach/AttachOperationFailedException.java index cbc4410907c..3f26c02c304 100644 --- a/src/jdk.attach/share/classes/com/sun/tools/attach/AttachOperationFailedException.java +++ b/src/jdk.attach/share/classes/com/sun/tools/attach/AttachOperationFailedException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,4 +50,18 @@ public class AttachOperationFailedException extends IOException { public AttachOperationFailedException(String message) { super(message); } + + /** + * Constructs an AttachOperationFailedException with + * the specified cause. + * + * @param message the detail message. + * @param cause the cause of this exception. + * + * @since 27 + */ + public AttachOperationFailedException(String message, Throwable cause) { + super(message, cause); + } + } diff --git a/src/jdk.charsets/share/classes/sun/nio/cs/ext/EUC_JP.java.template b/src/jdk.charsets/share/classes/sun/nio/cs/ext/EUC_JP.java.template index 4fc0b2796ee..e4eb2feab9d 100644 --- a/src/jdk.charsets/share/classes/sun/nio/cs/ext/EUC_JP.java.template +++ b/src/jdk.charsets/share/classes/sun/nio/cs/ext/EUC_JP.java.template @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -309,7 +309,7 @@ public class EUC_JP try { if (enc0201.isASCIICompatible()) { - int n = JLA.uncheckedEncodeASCII(sa, sp, da, dp, Math.min(dl - dp, sl - sp)); + int n = JLA.encodeASCII(sa, sp, da, dp, Math.min(dl - dp, sl - sp)); sp += n; dp += n; } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java index 65ce640ef76..bc597876778 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java @@ -91,6 +91,8 @@ public class JavacTaskImpl extends BasicJavacTask { @Override @DefinedBy(Api.COMPILER) public Boolean call() { + if (used.get()) + throw new IllegalStateException(); return doCall().isOK(); } @@ -207,7 +209,6 @@ public class JavacTaskImpl extends BasicJavacTask { // init JavaCompiler and queues compiler = JavaCompiler.instance(context); compiler.keepComments = true; - compiler.genEndPos = true; notYetEntered = new HashMap<>(); if (forParse) { compiler.initProcessAnnotations(processors, args.getFileObjects(), args.getClassNames()); @@ -245,6 +246,8 @@ public class JavacTaskImpl extends BasicJavacTask { @Override @DefinedBy(Api.COMPILER_TREE) public Iterable parse() { + if (used.get()) + throw new IllegalStateException(); Pair, Throwable> result = invocationHelper(this::parseInternal); if (result.snd == null) { return result.fst; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java index 22ee2393a02..6bc5d358b6f 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java @@ -114,7 +114,6 @@ import com.sun.tools.javac.tree.DCTree.DCParam; import com.sun.tools.javac.tree.DCTree.DCReference; import com.sun.tools.javac.tree.DocCommentTable; import com.sun.tools.javac.tree.DocTreeMaker; -import com.sun.tools.javac.tree.EndPosTable; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCBlock; import com.sun.tools.javac.tree.JCTree.JCCatch; @@ -240,8 +239,7 @@ public class JavacTrees extends DocTrees { @Override @DefinedBy(Api.COMPILER_TREE) public long getEndPosition(CompilationUnitTree file, Tree tree) { - EndPosTable endPosTable = ((JCCompilationUnit) file).endPositions; - return TreeInfo.getEndPos((JCTree) tree, endPosTable); + return TreeInfo.getEndPos((JCTree) tree); } @Override @DefinedBy(Api.COMPILER_TREE) diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/LintMapper.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/LintMapper.java index 06caa70d478..4f33bb92b41 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/LintMapper.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/LintMapper.java @@ -35,7 +35,6 @@ import java.util.function.Consumer; import javax.tools.JavaFileObject; -import com.sun.tools.javac.tree.EndPosTable; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.TreeInfo; @@ -134,9 +133,9 @@ public class LintMapper { * @param sourceFile source file * @param tree top-level declaration (class, package, or module) */ - public void calculateLints(JavaFileObject sourceFile, JCTree tree, EndPosTable endPositions) { + public void calculateLints(JavaFileObject sourceFile, JCTree tree) { Assert.check(rootLint != null); - fileInfoMap.get(sourceFile).afterAttr(tree, endPositions); + fileInfoMap.get(sourceFile).afterAttr(tree); } /** @@ -184,15 +183,15 @@ public class LintMapper { rootRange = new LintRange(rootLint); for (JCTree decl : tree.defs) { if (isTopLevelDecl(decl)) - unmappedDecls.add(new Span(decl, tree.endPositions)); + unmappedDecls.add(new Span(decl)); } } // After attribution: Discard the span from "unmappedDecls" and populate the declaration's subtree under "rootRange" - void afterAttr(JCTree tree, EndPosTable endPositions) { + void afterAttr(JCTree tree) { for (Iterator i = unmappedDecls.iterator(); i.hasNext(); ) { if (i.next().contains(tree.pos())) { - rootRange.populateSubtree(tree, endPositions); + rootRange.populateSubtree(tree); i.remove(); return; } @@ -225,8 +224,8 @@ public class LintMapper { static final Span MAXIMAL = new Span(Integer.MIN_VALUE, Integer.MAX_VALUE); - Span(JCTree tree, EndPosTable endPositions) { - this(TreeInfo.getStartPos(tree), TreeInfo.getEndPos(tree, endPositions)); + Span(JCTree tree) { + this(TreeInfo.getStartPos(tree), TreeInfo.getEndPos(tree)); } boolean contains(DiagnosticPosition pos) { @@ -256,8 +255,8 @@ public class LintMapper { } // Create a node representing the given declaration and its corresponding Lint configuration - LintRange(JCTree tree, EndPosTable endPositions, Lint lint) { - this(new Span(tree, endPositions), lint, new LinkedList<>()); + LintRange(JCTree tree, Lint lint) { + this(new Span(tree), lint, new LinkedList<>()); } // Find the most specific node in this tree (including me) that contains the given position, if any @@ -277,7 +276,7 @@ public class LintMapper { // Populate a sparse subtree corresponding to the given nested declaration. // Only when the Lint configuration differs from the parent is a node added. - void populateSubtree(JCTree tree, EndPosTable endPositions) { + void populateSubtree(JCTree tree) { new TreeScanner() { private LintRange currentNode = LintRange.this; @@ -320,7 +319,7 @@ public class LintMapper { // Add a new node here and proceed final LintRange previousNode = currentNode; - currentNode = new LintRange(tree, endPositions, newLint); + currentNode = new LintRange(tree, newLint); previousNode.children.add(currentNode); try { recursor.accept(tree); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java index cc21113882f..cdd88b22510 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2762,8 +2762,7 @@ public class Attr extends JCTree.Visitor { clazzid1 = make.at(clazz.pos).Select(make.Type(encltype), ((JCIdent) clazzid).name); - EndPosTable endPosTable = this.env.toplevel.endPositions; - endPosTable.storeEnd(clazzid1, clazzid.getEndPosition(endPosTable)); + clazzid1.endpos = clazzid.getEndPosition(); if (clazz.hasTag(ANNOTATED_TYPE)) { JCAnnotatedType annoType = (JCAnnotatedType) clazz; List annos = annoType.annotations; @@ -4000,7 +3999,10 @@ public class Attr extends JCTree.Visitor { chk.checkCastable(tree.rhs.pos(), operator.type.getReturnType(), owntype); - chk.checkLossOfPrecision(tree.rhs.pos(), operand, owntype); + switch (tree.getTag()) { + case SL_ASG, SR_ASG, USR_ASG -> { } // we only use (at most) the lower 6 bits, so any integral type is OK + default -> chk.checkLossOfPrecision(tree.rhs.pos(), operand, owntype); + } chk.checkOutOfRangeShift(tree.rhs.pos(), operator, operand); } result = check(tree, owntype, KindSelector.VAL, resultInfo); @@ -4266,7 +4268,7 @@ public class Attr extends JCTree.Visitor { } List expectedRecordTypes; - if (site.tsym.kind == Kind.TYP && ((ClassSymbol) site.tsym).isRecord()) { + if (site.tsym instanceof ClassSymbol clazz && clazz.isRecord()) { ClassSymbol record = (ClassSymbol) site.tsym; expectedRecordTypes = record.getRecordComponents() .stream() @@ -5311,7 +5313,7 @@ public class Attr extends JCTree.Visitor { annotate.flush(); // Now that this tree is attributed, we can calculate the Lint configuration everywhere within it - lintMapper.calculateLints(env.toplevel.sourcefile, env.tree, env.toplevel.endPositions); + lintMapper.calculateLints(env.toplevel.sourcefile, env.tree); } public void attribPackage(DiagnosticPosition pos, PackageSymbol p) { diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ExhaustivenessComputer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ExhaustivenessComputer.java index bbc330832f3..2a0bab1e330 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ExhaustivenessComputer.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ExhaustivenessComputer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved. * 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,11 +41,17 @@ import com.sun.tools.javac.code.Kinds.Kind; import com.sun.tools.javac.code.Type.TypeVar; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.SequencedSet; +import java.util.function.Consumer; import java.util.function.Predicate; import java.util.stream.Collectors; +import java.util.stream.Stream; import static java.util.stream.Collectors.groupingBy; +import static com.sun.tools.javac.code.Flags.RECORD; /** A class to compute exhaustiveness of set of switch cases. * @@ -55,6 +61,14 @@ import static java.util.stream.Collectors.groupingBy; * deletion without notice. */ public class ExhaustivenessComputer { + private static final long DEFAULT_MAX_BASE_CHECKS = 4_000_000; + + //when baseChecks is set to a value different that this, the checks + //will be counter, and if too many will happen, the process will be stopped + //when baseChecks is set to this value, there's no counting, and the + //process will not continue as long as needed + private static final long NO_BASE_CHECKS_COUNTING = -1; + protected static final Context.Key exhaustivenessKey = new Context.Key<>(); private final Symtab syms; @@ -62,6 +76,8 @@ public class ExhaustivenessComputer { private final Check chk; private final Infer infer; private final Map, Boolean> isSubtypeCache = new HashMap<>(); + private final long maxBaseChecks; + private long baseChecks = NO_BASE_CHECKS_COUNTING; public static ExhaustivenessComputer instance(Context context) { ExhaustivenessComputer instance = context.get(exhaustivenessKey); @@ -77,9 +93,22 @@ public class ExhaustivenessComputer { types = Types.instance(context); chk = Check.instance(context); infer = Infer.instance(context); + Options options = Options.instance(context); + String baseChecks = options.get("exhaustivityMaxBaseChecks"); + long computedMaxBaseChecks = DEFAULT_MAX_BASE_CHECKS; + + if (baseChecks != null) { + try { + computedMaxBaseChecks = Long.parseLong(baseChecks); + } catch (NumberFormatException _) { + //ignore invalid values and use the default maximum number of checks + } + } + + maxBaseChecks = computedMaxBaseChecks; } - public boolean exhausts(JCExpression selector, List cases) { + public ExhaustivenessResult exhausts(JCExpression selector, List cases) { Set patternSet = new HashSet<>(); Map> enum2Constants = new HashMap<>(); Set booleanLiterals = new HashSet<>(Set.of(0, 1)); @@ -113,7 +142,7 @@ public class ExhaustivenessComputer { } if (types.unboxedTypeOrType(selector.type).hasTag(TypeTag.BOOLEAN) && booleanLiterals.isEmpty()) { - return true; + return ExhaustivenessResult.ofExhaustive(); } for (Entry> e : enum2Constants.entrySet()) { @@ -121,47 +150,77 @@ public class ExhaustivenessComputer { patternSet.add(new BindingPattern(e.getKey().type)); } } - Set patterns = patternSet; - Set> seenFallback = new HashSet<>(); - boolean useHashes = true; try { - boolean repeat = true; - while (repeat) { - Set updatedPatterns; - updatedPatterns = reduceBindingPatterns(selector.type, patterns); - updatedPatterns = reduceNestedPatterns(updatedPatterns, useHashes); - updatedPatterns = reduceRecordPatterns(updatedPatterns); - updatedPatterns = removeCoveredRecordPatterns(updatedPatterns); - repeat = !updatedPatterns.equals(patterns); - if (checkCovered(selector.type, patterns)) { - return true; - } - if (!repeat) { - //there may be situation like: - //class B permits S1, S2 - //patterns: R(S1, B), R(S2, S2) - //this might be joined to R(B, S2), as B could be rewritten to S2 - //but hashing in reduceNestedPatterns will not allow that - //disable the use of hashing, and use subtyping in - //reduceNestedPatterns to handle situations like this: - repeat = useHashes && seenFallback.add(updatedPatterns); - useHashes = false; - } else { - //if a reduction happened, make sure hashing in reduceNestedPatterns - //is enabled, as the hashing speeds up the process significantly: - useHashes = true; - } - patterns = updatedPatterns; + CoverageResult coveredResult = computeCoverage(selector.type, patternSet, PatternEquivalence.STRICT); + if (coveredResult.covered()) { + return ExhaustivenessResult.ofExhaustive(); } - return checkCovered(selector.type, patterns); + + Set details = + this.computeMissingPatternDescriptions(selector.type, coveredResult.incompletePatterns()) + .stream() + .flatMap(pd -> { + if (pd instanceof BindingPattern bp && enum2Constants.containsKey(bp.type.tsym)) { + Symbol enumType = bp.type.tsym; + return enum2Constants.get(enumType).stream().map(c -> new EnumConstantPattern(bp.type, c.name)); + } else { + return Stream.of(pd); + } + }) + .collect(Collectors.toSet()); + + return ExhaustivenessResult.ofDetails(details); } catch (CompletionFailure cf) { chk.completionError(selector.pos(), cf); - return true; //error recovery - } finally { - isSubtypeCache.clear(); + return ExhaustivenessResult.ofExhaustive(); //error recovery } } + /* Given the set of patterns, runs the reductions of it as long as possible. + * If the (reduced) set of patterns covers the given selector type, returns + * covered == true, and incompletePatterns == null. + * If the (reduced) set of patterns does not cover the given selector type, + * returns covered == false, and incompletePatterns == the reduced set of patterns. + */ + private CoverageResult computeCoverage(Type selectorType, Set patterns, PatternEquivalence patternEquivalence) { + Set updatedPatterns; + Set> seenPatterns = new HashSet<>(); + boolean useHashes = true; + boolean repeat = true; + do { + updatedPatterns = reduceBindingPatterns(selectorType, patterns); + updatedPatterns = reduceNestedPatterns(updatedPatterns, useHashes, patternEquivalence); + updatedPatterns = reduceRecordPatterns(updatedPatterns); + updatedPatterns = removeCoveredRecordPatterns(updatedPatterns); + repeat = !updatedPatterns.equals(patterns); + if (checkCovered(selectorType, patterns)) { + return new CoverageResult(true, null); + } + if (!repeat) { + //there may be situation like: + //class B permits S1, S2 + //patterns: R(S1, B), R(S2, S2) + //this might be joined to R(B, S2), as B could be rewritten to S2 + //but hashing in reduceNestedPatterns will not allow that + //disable the use of hashing, and use subtyping in + //reduceNestedPatterns to handle situations like this: + repeat = useHashes && seenPatterns.add(updatedPatterns); + useHashes = false; + } else { + //if a reduction happened, make sure hashing in reduceNestedPatterns + //is enabled, as the hashing speeds up the process significantly: + useHashes = true; + } + patterns = updatedPatterns; + } while (repeat); + if (checkCovered(selectorType, patterns)) { + return new CoverageResult(true, null); + } + return new CoverageResult(false, patterns); + } + + private record CoverageResult(boolean covered, Set incompletePatterns) {} + private boolean checkCovered(Type seltype, Iterable patterns) { for (Type seltypeComponent : components(seltype)) { for (PatternDescription pd : patterns) { @@ -215,6 +274,7 @@ public class ExhaustivenessComputer { if (clazz.isSealed() && clazz.isAbstract() && //if a binding pattern for clazz already exists, no need to analyze it again: !existingBindings.contains(clazz)) { + ListBuffer bindings = new ListBuffer<>(); //do not reduce to types unrelated to the selector type: Type clazzType = clazz.type; if (components(selectorType).stream() @@ -222,16 +282,7 @@ public class ExhaustivenessComputer { continue; } - Set permitted = allPermittedSubTypes(clazz, csym -> { - Type instantiated; - if (csym.type.allparams().isEmpty()) { - instantiated = csym.type; - } else { - instantiated = infer.instantiatePatternType(selectorType, csym); - } - - return instantiated != null && types.isCastable(selectorType, instantiated); - }); + Set permitted = allPermittedSubTypes(clazz, isApplicableSubtypePredicate(selectorType)); //the set of pending permitted subtypes needed to cover clazz: Set pendingPermitted = new HashSet<>(permitted); @@ -263,7 +314,7 @@ public class ExhaustivenessComputer { } if (pendingPermitted.isEmpty()) { - toAdd.add(new BindingPattern(clazz.type)); + toAdd.add(new BindingPattern(clazz.type, Set.of())); } } } @@ -304,6 +355,49 @@ public class ExhaustivenessComputer { return permitted; } + private Predicate isApplicableSubtypePredicate(Type targetType) { + return csym -> { + Type instantiated = instantiatePatternType(targetType, csym); + + return instantiated != null && types.isCastable(targetType, instantiated); + }; + } + + private Type instantiatePatternType(Type targetType, TypeSymbol csym) { + if (csym.type.allparams().isEmpty()) { + return csym.type; + } else { + return infer.instantiatePatternType(targetType, csym); + } + } + + private Set leafPermittedSubTypes(TypeSymbol root, Predicate accept) { + Set permitted = new HashSet<>(); + List permittedSubtypesClosure = baseClasses(root); + + while (permittedSubtypesClosure.nonEmpty()) { + ClassSymbol current = permittedSubtypesClosure.head; + + permittedSubtypesClosure = permittedSubtypesClosure.tail; + + current.complete(); + + if (current.isSealed() && current.isAbstract()) { + for (Type t : current.getPermittedSubclasses()) { + ClassSymbol csym = (ClassSymbol) t.tsym; + + if (accept.test(csym)) { + permittedSubtypesClosure = permittedSubtypesClosure.prepend(csym); + } + } + } else { + permitted.add(current); + } + } + + return permitted; + } + private List baseClasses(TypeSymbol root) { if (root instanceof ClassSymbol clazz) { return List.of(clazz); @@ -336,7 +430,8 @@ public class ExhaustivenessComputer { * as pattern hashes cannot be used to speed up the matching process */ private Set reduceNestedPatterns(Set patterns, - boolean useHashes) { + boolean useHashes, + PatternEquivalence patternEquivalence) { /* implementation note: * finding a sub-set of patterns that only differ in a single * column is time-consuming task, so this method speeds it up by: @@ -386,13 +481,13 @@ public class ExhaustivenessComputer { RecordPattern rpOther = candidatesArr[nextCandidate]; if (rpOne.recordType.tsym == rpOther.recordType.tsym && - nestedComponentsEquivalent(rpOne, rpOther, mismatchingCandidate, useHashes)) { + nestedComponentsEquivalent(rpOne, rpOther, mismatchingCandidate, useHashes, patternEquivalence)) { join.append(rpOther); } } var nestedPatterns = join.stream().map(rp -> rp.nested[mismatchingCandidateFin]).collect(Collectors.toSet()); - var updatedPatterns = reduceNestedPatterns(nestedPatterns, useHashes); + var updatedPatterns = reduceNestedPatterns(nestedPatterns, useHashes, patternEquivalence); updatedPatterns = reduceRecordPatterns(updatedPatterns); updatedPatterns = removeCoveredRecordPatterns(updatedPatterns); @@ -403,16 +498,11 @@ public class ExhaustivenessComputer { current.removeAll(join); } - for (PatternDescription nested : updatedPatterns) { - PatternDescription[] newNested = - Arrays.copyOf(rpOne.nested, rpOne.nested.length); - newNested[mismatchingCandidateFin] = nested; - RecordPattern nue = new RecordPattern(rpOne.recordType(), - rpOne.fullComponentTypes(), - newNested, - new HashSet<>(join)); - current.add(nue); - } + generatePatternsWithReplacedNestedPattern(rpOne, + mismatchingCandidateFin, + updatedPatterns, + Set.copyOf(join), + current::add); } } } @@ -434,11 +524,32 @@ public class ExhaustivenessComputer { * - it's type is a supertype of the existing pattern's type * - it was produced by a reduction from a record pattern that is equivalent to * the existing pattern + * - only if PatternEquivalence is LOOSE and the type is the same of the type + * of an existing record pattern (the binding pattern may stand in place of + * a record pattern). This is only used to compute the missing patterns that + * would make the original pattern set exhaustive. + * + * For example, having (with mismatchingCandidate == 0): + * existing: R(A _, Box(var _)) {} + * cadidate: R(B _, Box(var _)) {} + * these are always equivalent; as all nested patterns except of + * component 0 are exactly equivalent + * + * existing: R(A _, SubtypeOfBox _) {} + * cadidate: R(A _, Box _) {} + * this is only equivalent when useHashes == false; Box _ could be replaced + * with a more specific SubtypeOfBox _ + * + * existing: R(A _, Box(var _)) {} + * cadidate: R(A _, Box _) {} + * this is only equivalent when useHashes == false and patternEquivalence == LOOSE; + * Box _ is accepted in place of the more specific record pattern */ private boolean nestedComponentsEquivalent(RecordPattern existing, RecordPattern candidate, int mismatchingCandidate, - boolean useHashes) { + boolean useHashes, + PatternEquivalence patternEquivalence) { NEXT_NESTED: for (int i = 0; i < existing.nested.length; i++) { if (i != mismatchingCandidate) { @@ -457,22 +568,28 @@ public class ExhaustivenessComputer { return false; } } else if (existing.nested[i] instanceof RecordPattern nestedExisting) { - java.util.List pendingReplacedPatterns = - new ArrayList<>(nestedCandidate.sourcePatterns()); + if (patternEquivalence == PatternEquivalence.LOOSE) { + if (!isSubtypeErasure(nestedExisting.recordType(), nestedCandidate.type)) { + return false; + } + } else { + java.util.List pendingReplacedPatterns = + new ArrayList<>(nestedCandidate.sourcePatterns()); - while (!pendingReplacedPatterns.isEmpty()) { - PatternDescription currentReplaced = pendingReplacedPatterns.removeLast(); + while (!pendingReplacedPatterns.isEmpty()) { + PatternDescription currentReplaced = pendingReplacedPatterns.removeLast(); - if (nestedExisting.equals(currentReplaced)) { - //candidate.nested[i] is substitutable for existing.nested[i] - //continue with the next nested pattern: - continue NEXT_NESTED; + if (nestedExisting.equals(currentReplaced)) { + //candidate.nested[i] is substitutable for existing.nested[i] + //continue with the next nested pattern: + continue NEXT_NESTED; + } + + pendingReplacedPatterns.addAll(currentReplaced.sourcePatterns()); } - pendingReplacedPatterns.addAll(currentReplaced.sourcePatterns()); + return false; } - - return false; } else { return false; } @@ -563,6 +680,8 @@ public class ExhaustivenessComputer { } private boolean isBpCovered(Type componentType, PatternDescription newNested) { + reportCheck(); + if (newNested instanceof BindingPattern bp) { Type seltype = types.erasure(componentType); Type pattype = types.erasure(bp.type); @@ -574,9 +693,18 @@ public class ExhaustivenessComputer { return false; } - sealed interface PatternDescription { + protected void reportCheck() { + if (baseChecks != NO_BASE_CHECKS_COUNTING && + ++baseChecks > maxBaseChecks) { + throw new TooManyChecksException(null); + } + } + + public sealed interface PatternDescription { + public Type type(); public Set sourcePatterns(); } + public PatternDescription makePatternDescription(Type selectorType, JCPattern pattern) { if (pattern instanceof JCBindingPattern binding) { Type type = !selectorType.isPrimitive() && types.isSubtype(selectorType, binding.type) @@ -586,9 +714,7 @@ public class ExhaustivenessComputer { Type[] componentTypes; if (!record.type.isErroneous()) { - componentTypes = ((ClassSymbol) record.type.tsym).getRecordComponents() - .map(r -> types.memberType(record.type, r)) - .toArray(s -> new Type[s]); + componentTypes = instantiatedComponentTypes(record.type); } else { componentTypes = record.nested.map(t -> types.createErrorType(t.type)).toArray(s -> new Type[s]);; @@ -611,7 +737,7 @@ public class ExhaustivenessComputer { throw Assert.error(); } } - record BindingPattern(Type type, Set sourcePatterns) implements PatternDescription { + public record BindingPattern(Type type, Set sourcePatterns) implements PatternDescription { public BindingPattern(Type type) { this(type, Set.of()); @@ -631,7 +757,7 @@ public class ExhaustivenessComputer { return type.tsym + " _"; } } - record RecordPattern(Type recordType, int _hashCode, Type[] fullComponentTypes, PatternDescription[] nested, Set sourcePatterns) implements PatternDescription { + public record RecordPattern(Type recordType, int _hashCode, Type[] fullComponentTypes, PatternDescription[] nested, Set sourcePatterns) implements PatternDescription { public RecordPattern(Type recordType, Type[] fullComponentTypes, PatternDescription[] nested) { this(recordType, fullComponentTypes, nested, Set.of()); @@ -673,5 +799,450 @@ public class ExhaustivenessComputer { .map(pd -> pd.toString()) .collect(Collectors.joining(", ")) + ")"; } + + @Override + public Type type() { + return recordType; + } + } + + public record EnumConstantPattern(Type enumType, Name enumConstant) implements PatternDescription { + + @Override + public Type type() { + return enumType(); + } + + @Override + public Set sourcePatterns() { + return Set.of(); + } + public String toString() { + return enumType() + "." + enumConstant(); + } + } + + public record ExhaustivenessResult(boolean exhaustive, Set notExhaustiveDetails) { + public static ExhaustivenessResult ofExhaustive() { + return new ExhaustivenessResult(true, null); + } + public static ExhaustivenessResult ofDetails(Set notExhaustiveDetails) { + return new ExhaustivenessResult(false, notExhaustiveDetails != null ? notExhaustiveDetails : Set.of()); + } + } + + //computation of missing patterns: + protected Set computeMissingPatternDescriptions(Type selectorType, + Set incompletePatterns) { + if (maxBaseChecks == 0) { + return Set.of(); + } + try { + baseChecks = 0; + PatternDescription defaultPattern = new BindingPattern(selectorType); + return expandMissingPatternDescriptions(selectorType, + selectorType, + defaultPattern, + incompletePatterns, + Set.of(defaultPattern)); + } catch (TooManyChecksException ex) { + return ex.missingPatterns != null ? ex.missingPatterns : Set.of(); + } finally { + baseChecks = NO_BASE_CHECKS_COUNTING; + } + } + + private Set expandMissingPatternDescriptions(Type selectorType, + Type targetType, + PatternDescription toExpand, + Set basePatterns, + Set inMissingPatterns) { + try { + return doExpandMissingPatternDescriptions(selectorType, targetType, + toExpand, basePatterns, + inMissingPatterns); + } catch (TooManyChecksException ex) { + if (ex.missingPatterns == null) { + ex = new TooManyChecksException(inMissingPatterns); + } + throw ex; + } + } + + private Set doExpandMissingPatternDescriptions(Type selectorType, + Type targetType, + PatternDescription toExpand, + Set basePatterns, + Set inMissingPatterns) { + if (toExpand instanceof BindingPattern bp) { + if (bp.type.tsym.isSealed()) { + //try to replace binding patterns for sealed types with all their immediate permitted applicable types: + List permitted = ((ClassSymbol) bp.type.tsym).getPermittedSubclasses(); + Set applicableDirectPermittedPatterns = + permitted.stream() + .map(type -> type.tsym) + .filter(isApplicableSubtypePredicate(targetType)) + .map(csym -> new BindingPattern(types.erasure(csym.type))) + .collect(Collectors.toCollection(LinkedHashSet::new)); + + //remove the permitted subtypes that are not needed to achieve exhaustivity + boolean reduced = + removeUnnecessaryPatterns(selectorType, bp, basePatterns, inMissingPatterns, applicableDirectPermittedPatterns); + + if (!reduced && !hasMatchingRecordPattern(basePatterns, inMissingPatterns, toExpand)) { + //if all immediate permitted subtypes are needed + //give up, and simply use the current pattern: + return inMissingPatterns; + } + + Set currentMissingPatterns = + replace(inMissingPatterns, toExpand, applicableDirectPermittedPatterns); + + //try to recursively expand on each viable pattern: + for (PatternDescription viable : applicableDirectPermittedPatterns) { + currentMissingPatterns = expandMissingPatternDescriptions(selectorType, targetType, + viable, basePatterns, + currentMissingPatterns); + } + + return currentMissingPatterns; + } else if ((bp.type.tsym.flags_field & Flags.RECORD) != 0 && + //only expand record types into record patterns if there's a chance it may change the outcome + //i.e. there is a record pattern in at the spot in the original base patterns: + hasMatchingRecordPattern(basePatterns, inMissingPatterns, toExpand)) { + //if there is a binding pattern at a place where the original based patterns + //have a record pattern, try to expand the binding pattern into a record pattern + //create all possible combinations of record pattern components: + Type[] componentTypes = instantiatedComponentTypes(bp.type); + List> combinatorialNestedTypes = List.of(List.nil()); + + for (Type componentType : componentTypes) { + List applicableLeafPermittedSubtypes; + + if (componentType.tsym.isSealed()) { + applicableLeafPermittedSubtypes = + leafPermittedSubTypes(componentType.tsym, + isApplicableSubtypePredicate(componentType)) + .stream() + .map(csym -> instantiatePatternType(componentType, csym)) + .collect(List.collector()); + } else { + applicableLeafPermittedSubtypes = List.of(componentType); + } + + List> newCombinatorialNestedTypes = List.nil(); + + for (List existing : combinatorialNestedTypes) { + for (Type nue : applicableLeafPermittedSubtypes) { + newCombinatorialNestedTypes = newCombinatorialNestedTypes.prepend(existing.append(nue)); + } + } + + combinatorialNestedTypes = newCombinatorialNestedTypes; + } + + Set combinatorialPatterns = + combinatorialNestedTypes.stream() + .map(combination -> new RecordPattern(bp.type, + componentTypes, + combination.map(BindingPattern::new) + .toArray(PatternDescription[]::new))) + .collect(Collectors.toCollection(LinkedHashSet::new)); + + removeUnnecessaryPatterns(selectorType, bp, basePatterns, inMissingPatterns, combinatorialPatterns); + + CoverageResult coverageResult = computeCoverage(targetType, combinatorialPatterns, PatternEquivalence.LOOSE); + + if (!coverageResult.covered()) { + //use the partially merged/combined patterns: + combinatorialPatterns = coverageResult.incompletePatterns(); + } + + //combine sealed subtypes into the supertype, if all is covered. + //but preserve more specific record types in positions where there are record patterns in the original patterns + //this is particularly important for the case where the sealed supertype only has one permitted type, the record + //the base type could be used instead of the record otherwise, which would produce less specific missing pattern: + Set sortedCandidates = + partialSortPattern(combinatorialPatterns, basePatterns, replace(inMissingPatterns, toExpand, combinatorialPatterns)); + + removeUnnecessaryPatterns(selectorType, bp, basePatterns, inMissingPatterns, sortedCandidates); + + Set currentMissingPatterns = + replace(inMissingPatterns, toExpand, sortedCandidates); + + for (PatternDescription addedPattern : sortedCandidates) { + if (addedPattern instanceof RecordPattern addedRP) { + for (int c = 0; c < addedRP.nested.length; c++) { + currentMissingPatterns = expandMissingPatternDescriptions(selectorType, + addedRP.fullComponentTypes[c], + addedRP.nested[c], + basePatterns, + currentMissingPatterns); + } + } + } + + return currentMissingPatterns; + } + } + return inMissingPatterns; + } + + /* + * Inside any pattern in {@code in}, in any nesting depth, replace + * pattern {@code what} with patterns {@code to}. + */ + private Set replace(Iterable in, + PatternDescription what, + Collection to) { + Set result = new HashSet<>(); + + for (PatternDescription pd : in) { + Collection replaced = replace(pd, what, to); + if (replaced != null) { + result.addAll(replaced); + } else { + result.add(pd); + } + } + + return result; + } + //where: + //null: no change + private Collection replace(PatternDescription in, + PatternDescription what, + Collection to) { + if (in == what) { + return to; + } else if (in instanceof RecordPattern rp) { + for (int c = 0; c < rp.nested.length; c++) { + Collection replaced = replace(rp.nested[c], what, to); + if (replaced != null) { + Set withReplaced = new HashSet<>(); + + generatePatternsWithReplacedNestedPattern(rp, c, replaced, Set.of(), withReplaced::add); + + return replace(withReplaced, what, to); + } + } + return null; + } else { + return null; //binding patterns have no children + } + } + + /* Out of "candidates" remove patterns that are not necessary to achieve exhaustiveness. + * Note that iteration order of "candidates" is important - if the set contains + * two pattern, out of which either, but not both, is needed to achieve exhaustiveness, + * the first one in the iteration order will be removed. + */ + private boolean removeUnnecessaryPatterns(Type selectorType, + PatternDescription toExpand, + Set basePatterns, + Set inMissingPatterns, + Set candidates) { + boolean reduced = false; + + for (Iterator it = candidates.iterator(); it.hasNext(); ) { + PatternDescription current = it.next(); + Set reducedAdded = new HashSet<>(candidates); + + reducedAdded.remove(current); + + Set combinedPatterns = + Stream.concat(basePatterns.stream(), + replace(inMissingPatterns, toExpand, reducedAdded).stream()) + .collect(Collectors.toSet()); + + if (computeCoverage(selectorType, combinedPatterns, PatternEquivalence.LOOSE).covered()) { + it.remove(); + reduced = true; + } + } + + return reduced; + } + /* + * Sort patterns so that those that are preferred for removal are in front + * of those that are preferred to remain (when there's a choice). + */ + private SequencedSet partialSortPattern(Set candidates, + Set basePatterns, + Set missingPatterns) { + SequencedSet sortedCandidates = new LinkedHashSet<>(); + + while (!candidates.isEmpty()) { + PatternDescription mostSpecific = null; + for (PatternDescription current : candidates) { + if (mostSpecific == null || + shouldAppearBefore(current, mostSpecific, basePatterns, missingPatterns)) { + mostSpecific = current; + } + } + sortedCandidates.add(mostSpecific); + candidates.remove(mostSpecific); + } + return sortedCandidates; + } + //where: + //true iff pd1 should appear before pd2 + //false otherwise + private boolean shouldAppearBefore(PatternDescription pd1, + PatternDescription pd2, + Set basePatterns, + Set missingPatterns) { + if (pd1 instanceof RecordPattern rp1 && pd2 instanceof RecordPattern rp2) { + for (int c = 0; c < rp1.nested.length; c++) { + if (shouldAppearBefore((BindingPattern) rp1.nested[c], + (BindingPattern) rp2.nested[c], + basePatterns, + missingPatterns)) { + return true; + } + } + } else if (pd1 instanceof BindingPattern bp1 && pd2 instanceof BindingPattern bp2) { + Type t1 = bp1.type(); + Type t2 = bp2.type(); + boolean t1IsImportantRecord = + (t1.tsym.flags_field & RECORD) != 0 && + hasMatchingRecordPattern(basePatterns, missingPatterns, bp1); + boolean t2IsImportantRecord = + (t2.tsym.flags_field & RECORD) != 0 && + hasMatchingRecordPattern(basePatterns, missingPatterns, bp2); + if (t1IsImportantRecord && !t2IsImportantRecord) { + return false; + } + if (!t1IsImportantRecord && t2IsImportantRecord) { + return true; + } + if (!types.isSameType(t1, t2) && types.isSubtype(t1, t2)) { + return true; + } + } + + return false; + } + + /* + * Do the {@code basePatterns} have a record pattern at a place that corresponds to + * position of pattern {@code query} inside {@code missingPatterns}? + */ + private boolean hasMatchingRecordPattern(Set basePatterns, + Set missingPatterns, + PatternDescription query) { + PatternDescription root = findRootContaining(missingPatterns, query); + + if (root == null) { + return false; + } + return basePatternsHaveRecordPatternOnThisSpot(basePatterns, root, query); + } + //where: + private PatternDescription findRootContaining(Set rootPatterns, + PatternDescription added) { + for (PatternDescription pd : rootPatterns) { + if (isUnderRoot(pd, added)) { + return pd; + } + } + + return null; + } + + private boolean basePatternsHaveRecordPatternOnThisSpot(Set basePatterns, + PatternDescription rootPattern, + PatternDescription added) { + if (rootPattern == added) { + return basePatterns.stream().anyMatch(pd -> pd instanceof RecordPattern); + } + if (!(rootPattern instanceof RecordPattern rootPatternRecord)) { + return false; + } + int index = -1; + for (int c = 0; c < rootPatternRecord.nested.length; c++) { + if (isUnderRoot(rootPatternRecord.nested[c], added)) { + index = c; + break; + } + } + // 'index' must be one of rootPatternRecord.nested; if not, `isUnderRoot` is inconsistent. + Assert.check(index != (-1)); + + int indexFin = index; + Set filteredBasePatterns = + basePatterns.stream() + .filter(pd -> pd instanceof RecordPattern) + .map(rp -> (RecordPattern) rp) + .filter(rp -> types.isSameType(rp.recordType(), rootPatternRecord.recordType())) + .map(rp -> rp.nested[indexFin]) + .collect(Collectors.toSet()); + + return basePatternsHaveRecordPatternOnThisSpot(filteredBasePatterns, rootPatternRecord.nested[index], added); + } + + private boolean isUnderRoot(PatternDescription root, PatternDescription searchFor) { + if (root == searchFor) { + return true; + } else if (root instanceof RecordPattern rp) { + for (int c = 0; c < rp.nested.length; c++) { + if (isUnderRoot(rp.nested[c], searchFor)) { + return true; + } + } + } + return false; + } + + /* + * Using {@code basePattern} as a starting point, generate new {@code + * RecordPattern}s, such that all corresponding components but one, are the + * same. The component described by the {@code replaceComponent} index is + * replaced with all {@code PatternDescription}s taken from {@code + * updatedNestedPatterns} and the resulting {@code RecordPatterns}s are sent + * to {@code target}. + */ + private void generatePatternsWithReplacedNestedPattern(RecordPattern basePattern, + int replaceComponent, + Iterable updatedNestedPatterns, + Set sourcePatterns, + Consumer target) { + for (PatternDescription nested : updatedNestedPatterns) { + PatternDescription[] newNested = + Arrays.copyOf(basePattern.nested, basePattern.nested.length); + newNested[replaceComponent] = nested; + target.accept(new RecordPattern(basePattern.recordType(), + basePattern.fullComponentTypes(), + newNested, + sourcePatterns)); + } + } + + /* For a given record type, return the record's component types, with their + * types instatiated according to the exact record type. + */ + private Type[] instantiatedComponentTypes(Type recordType) { + Type[] componentTypes = ((ClassSymbol) recordType.tsym).getRecordComponents() + .map(r -> types.memberType(recordType, r)) + .toArray(s -> new Type[s]); + return componentTypes; + } + + /* The strictness of determining the equivalent of patterns, used in + * nestedComponentsEquivalent. + */ + private enum PatternEquivalence { + STRICT, + LOOSE; + } + + protected static class TooManyChecksException extends RuntimeException { + private static final long serialVersionUID = 0L; + private transient final Set missingPatterns; + + public TooManyChecksException(Set missingPatterns) { + super(null, null, false, false); + this.missingPatterns = missingPatterns; + } } } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java index e74aed6a357..cbcb474a37f 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,9 +50,15 @@ import static com.sun.tools.javac.code.Flags.BLOCK; import static com.sun.tools.javac.code.Kinds.Kind.*; import static com.sun.tools.javac.code.TypeTag.BOOLEAN; import static com.sun.tools.javac.code.TypeTag.VOID; +import com.sun.tools.javac.comp.ExhaustivenessComputer.BindingPattern; +import com.sun.tools.javac.comp.ExhaustivenessComputer.EnumConstantPattern; +import com.sun.tools.javac.comp.ExhaustivenessComputer.ExhaustivenessResult; +import com.sun.tools.javac.comp.ExhaustivenessComputer.PatternDescription; +import com.sun.tools.javac.comp.ExhaustivenessComputer.RecordPattern; import com.sun.tools.javac.resources.CompilerProperties.Fragments; import static com.sun.tools.javac.tree.JCTree.Tag.*; import com.sun.tools.javac.util.JCDiagnostic.Fragment; +import java.util.Arrays; /** This pass implements dataflow analysis for Java programs though * different AST visitor steps. Liveness analysis (see AliveAnalyzer) checks that @@ -696,9 +702,18 @@ public class Flow { tree.isExhaustive = tree.hasUnconditionalPattern || TreeInfo.isErrorEnumSwitch(tree.selector, tree.cases); if (exhaustiveSwitch) { - tree.isExhaustive |= exhaustiveness.exhausts(tree.selector, tree.cases); if (!tree.isExhaustive) { - log.error(tree, Errors.NotExhaustiveStatement); + ExhaustivenessResult exhaustivenessResult = exhaustiveness.exhausts(tree.selector, tree.cases); + + tree.isExhaustive = exhaustivenessResult.exhaustive(); + + if (!tree.isExhaustive) { + if (exhaustivenessResult.notExhaustiveDetails().isEmpty()) { + log.error(tree, Errors.NotExhaustiveStatement); + } else { + logNotExhaustiveError(tree.pos(), exhaustivenessResult, Errors.NotExhaustiveStatementDetails); + } + } } } if (!tree.hasUnconditionalPattern && !exhaustiveSwitch) { @@ -735,16 +750,54 @@ public class Flow { TreeInfo.isErrorEnumSwitch(tree.selector, tree.cases)) { tree.isExhaustive = true; } else { - tree.isExhaustive = exhaustiveness.exhausts(tree.selector, tree.cases); + ExhaustivenessResult exhaustivenessResult = exhaustiveness.exhausts(tree.selector, tree.cases); + + tree.isExhaustive = exhaustivenessResult.exhaustive(); + + if (!tree.isExhaustive) { + if (exhaustivenessResult.notExhaustiveDetails().isEmpty()) { + log.error(tree, Errors.NotExhaustive); + } else { + logNotExhaustiveError(tree.pos(), exhaustivenessResult, Errors.NotExhaustiveDetails); + } + } } - if (!tree.isExhaustive) { - log.error(tree, Errors.NotExhaustive); - } alive = prevAlive; alive = alive.or(resolveYields(tree, prevPendingExits)); } + private void logNotExhaustiveError(DiagnosticPosition pos, + ExhaustivenessResult exhaustivenessResult, + Error errorKey) { + List details = + exhaustivenessResult.notExhaustiveDetails() + .stream() + .map(this::patternToDiagnostic) + .sorted((d1, d2) -> d1.toString() + .compareTo(d2.toString())) + .collect(List.collector()); + JCDiagnostic main = diags.error(null, log.currentSource(), pos, errorKey); + JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, details); + log.report(d); + } + + private JCDiagnostic patternToDiagnostic(PatternDescription desc) { + Type patternType = types.erasure(desc.type()); + return diags.fragment(switch (desc) { + case BindingPattern _ -> + Fragments.BindingPattern(patternType); + case RecordPattern rp -> + Fragments.RecordPattern(patternType, + Arrays.stream(rp.nested()) + .map(this::patternToDiagnostic) + .toList()); + case EnumConstantPattern ep -> + Fragments.EnumConstantPattern(patternType, + ep.enumConstant()); + }); + } + public void visitTry(JCTry tree) { ListBuffer prevPendingExits = pendingExits; pendingExits = new ListBuffer<>(); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java index 2db3435a382..69161fd682c 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java @@ -48,7 +48,6 @@ import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.jvm.Target; -import com.sun.tools.javac.tree.EndPosTable; import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Flags.BLOCK; @@ -156,10 +155,6 @@ public class Lower extends TreeTranslator { */ Env attrEnv; - /** A hash table mapping syntax trees to their ending source positions. - */ - EndPosTable endPosTable; - /* ************************************************************************ * Global mappings *************************************************************************/ @@ -2059,8 +2054,8 @@ public class Lower extends TreeTranslator { } else { make_at(tree.pos()); T result = super.translate(tree); - if (endPosTable != null && result != tree) { - endPosTable.replaceTree(tree, result); + if (result != null && result != tree) { + result.endpos = tree.endpos; } return result; } @@ -4352,7 +4347,6 @@ public class Lower extends TreeTranslator { try { attrEnv = env; this.make = make; - endPosTable = env.toplevel.endPositions; currentClass = null; currentRestype = null; currentMethodDef = null; @@ -4382,7 +4376,6 @@ public class Lower extends TreeTranslator { // note that recursive invocations of this method fail hard attrEnv = null; this.make = null; - endPosTable = null; currentClass = null; currentRestype = null; currentMethodDef = null; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/CRTable.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/CRTable.java index 2cd4142c748..3092d16469d 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/CRTable.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/CRTable.java @@ -32,7 +32,6 @@ import com.sun.tools.javac.tree.*; import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.List; import com.sun.tools.javac.tree.JCTree.*; -import com.sun.tools.javac.tree.EndPosTable; import com.sun.tools.javac.tree.JCTree.JCSwitchExpression; /** This class contains the CharacterRangeTable for some method @@ -57,10 +56,6 @@ implements CRTFlags { */ private Map positions = new HashMap<>(); - /** The object for ending positions stored in the parser. - */ - private EndPosTable endPosTable; - /** The tree of the method this table is intended for. * We should traverse this tree to get source ranges. */ @@ -68,9 +63,8 @@ implements CRTFlags { /** Constructor */ - public CRTable(JCTree.JCMethodDecl tree, EndPosTable endPosTable) { + public CRTable(JCTree.JCMethodDecl tree) { this.methodTree = tree; - this.endPosTable = endPosTable; } /** Create a new CRTEntry and add it to the entries. @@ -584,7 +578,7 @@ implements CRTFlags { */ public int endPos(JCTree tree) { if (tree == null) return Position.NOPOS; - return TreeInfo.getEndPos(tree, endPosTable); + return TreeInfo.getEndPos(tree); } } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java index e40a2fbfcea..688ea1bd720 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java @@ -45,7 +45,6 @@ import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.jvm.Code.*; import com.sun.tools.javac.jvm.Items.*; import com.sun.tools.javac.resources.CompilerProperties.Errors; -import com.sun.tools.javac.tree.EndPosTable; import com.sun.tools.javac.tree.JCTree.*; import static com.sun.tools.javac.code.Flags.*; @@ -162,11 +161,6 @@ public class Gen extends JCTree.Visitor { */ private int nerrs = 0; - /** An object containing mappings of syntax trees to their - * ending source positions. - */ - EndPosTable endPosTable; - boolean inCondSwitchExpression; Chain switchExpressionTrueChain; Chain switchExpressionFalseChain; @@ -455,7 +449,7 @@ public class Gen extends JCTree.Visitor { JCStatement init = make.at(vdef.pos()). Assignment(sym, vdef.init); initCode.append(init); - endPosTable.replaceTree(vdef, init); + init.endpos = vdef.endpos; initTAs.addAll(getAndRemoveNonFieldTAs(sym)); } else if (sym.getConstValue() == null) { // Initialize class (static) variables only if @@ -463,7 +457,7 @@ public class Gen extends JCTree.Visitor { JCStatement init = make.at(vdef.pos). Assignment(sym, vdef.init); clinitCode.append(init); - endPosTable.replaceTree(vdef, init); + init.endpos = vdef.endpos; clinitTAs.addAll(getAndRemoveNonFieldTAs(sym)); } else { checkStringConstant(vdef.init.pos(), sym.getConstValue()); @@ -1027,8 +1021,7 @@ public class Gen extends JCTree.Visitor { varDebugInfo, stackMap, debugCode, - genCrt ? new CRTable(tree, env.toplevel.endPositions) - : null, + genCrt ? new CRTable(tree) : null, syms, types, poolWriter); @@ -2478,7 +2471,6 @@ public class Gen extends JCTree.Visitor { attrEnv = env; ClassSymbol c = cdef.sym; this.toplevel = env.toplevel; - this.endPosTable = toplevel.endPositions; /* method normalizeDefs() can add references to external classes into the constant pool */ cdef.defs = normalizeDefs(cdef.defs, c); @@ -2508,7 +2500,6 @@ public class Gen extends JCTree.Visitor { attrEnv = null; this.env = null; toplevel = null; - endPosTable = null; nerrs = 0; qualifiedSymbolCache.clear(); } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java index 2469dc9e031..94292d9a348 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java @@ -438,8 +438,6 @@ public class JavaCompiler { sourceOutput = options.isSet(PRINTSOURCE); // used to be -s lineDebugInfo = options.isUnset(G_CUSTOM) || options.isSet(G_CUSTOM, "lines"); - genEndPos = options.isSet(XJCOV) || - context.get(DiagnosticListener.class) != null; devVerbose = options.isSet("dev"); processPcks = options.isSet("process.packages"); werrorAny = options.isSet(WERROR) || options.isSet(WERROR_CUSTOM, Option.LINT_CUSTOM_ALL); @@ -504,10 +502,6 @@ public class JavaCompiler { */ public boolean lineDebugInfo; - /** Switch: should we store the ending positions? - */ - public boolean genEndPos; - /** Switch: should we debug ignored exceptions */ protected boolean devVerbose; @@ -655,9 +649,8 @@ public class JavaCompiler { TaskEvent e = new TaskEvent(TaskEvent.Kind.PARSE, filename); taskListener.started(e); keepComments = true; - genEndPos = true; } - Parser parser = parserFactory.newParser(content, keepComments(), genEndPos, + Parser parser = parserFactory.newParser(content, keepComments(), lineDebugInfo, filename.isNameCompatible("module-info", Kind.SOURCE)); tree = parser.parseCompilationUnit(); if (verbose) { @@ -697,10 +690,7 @@ public class JavaCompiler { public JCTree.JCCompilationUnit parse(JavaFileObject filename) { JavaFileObject prev = log.useSource(filename); try { - JCTree.JCCompilationUnit t = parse(filename, readSource(filename)); - if (t.endPositions != null) - log.setEndPosTable(filename, t.endPositions); - return t; + return parse(filename, readSource(filename)); } finally { log.useSource(prev); } @@ -1162,7 +1152,6 @@ public class JavaCompiler { options.put("parameters", "parameters"); reader.saveParameterNames = true; keepComments = true; - genEndPos = true; if (!taskListener.isEmpty()) taskListener.started(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING)); deferredDiagnosticHandler = log.new DeferredDiagnosticHandler(); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java index f40cb0fb6b7..babe372e7dc 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java @@ -33,7 +33,6 @@ import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle; import com.sun.tools.javac.resources.CompilerProperties.Errors; import com.sun.tools.javac.resources.CompilerProperties.LintWarnings; import com.sun.tools.javac.resources.CompilerProperties.Warnings; -import com.sun.tools.javac.tree.EndPosTable; import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.JCDiagnostic.*; @@ -1215,7 +1214,7 @@ public class JavaTokenizer extends UnicodeReader { this.cs = cs; this.pos = new SimpleDiagnosticPosition(pos) { @Override - public int getEndPosition(EndPosTable endPosTable) { + public int getEndPosition() { return endPos; } }; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java index d658275d4dc..e78537c10f5 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java @@ -110,8 +110,7 @@ public class JavacParser implements Parser { /** The name table. */ private Names names; - /** End position mappings container */ - protected final AbstractEndPosTable endPosTable; + protected int errorEndPos = Position.NOPOS; /** A map associating "other nearby documentation comments" * with the preferred documentation comment for a declaration. */ @@ -167,9 +166,8 @@ public class JavacParser implements Parser { protected JavacParser(ParserFactory fac, Lexer S, boolean keepDocComments, - boolean keepLineMap, - boolean keepEndPositions) { - this(fac, S, keepDocComments, keepLineMap, keepEndPositions, false); + boolean keepLineMap) { + this(fac, S, keepDocComments, keepLineMap, false); } /** Construct a parser from a given scanner, tree factory and log. @@ -179,7 +177,6 @@ public class JavacParser implements Parser { Lexer S, boolean keepDocComments, boolean keepLineMap, - boolean keepEndPositions, boolean parseModuleInfo) { this.S = S; nextToken(); // prime the pump @@ -194,7 +191,6 @@ public class JavacParser implements Parser { this.docComments = newDocCommentTable(keepDocComments, fac); this.keepLineMap = keepLineMap; this.errorTree = F.Erroneous(); - this.endPosTable = newEndPosTable(keepEndPositions); this.allowYieldStatement = Feature.SWITCH_EXPRESSION.allowedInSource(source); this.allowRecords = Feature.RECORDS.allowedInSource(source); this.allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source); @@ -218,19 +214,12 @@ public class JavacParser implements Parser { this.parseModuleInfo = false; this.docComments = parser.docComments; this.errorTree = F.Erroneous(); - this.endPosTable = newEndPosTable(false); this.allowYieldStatement = Feature.SWITCH_EXPRESSION.allowedInSource(source); this.allowRecords = Feature.RECORDS.allowedInSource(source); this.allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source); updateUnexpectedTopLevelDefinitionStartError(false); } - protected AbstractEndPosTable newEndPosTable(boolean keepEndPositions) { - return keepEndPositions - ? new SimpleEndPosTable() - : new MinimalEndPosTable(); - } - protected DocCommentTable newDocCommentTable(boolean keepDocComments, ParserFactory fac) { return keepDocComments ? new LazyDocCommentTable(fac) : null; } @@ -667,7 +656,7 @@ public class JavacParser implements Parser { var src = log.currentSource(); return c.getStyle() == Comment.CommentStyle.JAVADOC_LINE && c.getPos().getStartPosition() == 0 && - src.getLineNumber(pos.getEndPosition(src.getEndPosTable())) == 1; + src.getLineNumber(pos.getEndPosition()) == 1; } /** @@ -681,23 +670,26 @@ public class JavacParser implements Parser { /* -------- source positions ------- */ protected void setErrorEndPos(int errPos) { - endPosTable.setErrorEndPos(errPos); + if (errPos > errorEndPos) { + errorEndPos = errPos; + } } /** * Store ending position for a tree, the value of which is the greater of - * last error position in {@link #endPosTable} and the given ending position. + * {@link #errorEndPos} and the given ending position. * @param tree tree node * @param endpos the ending position to associate with {@code tree} * @return {@code tree} */ protected T storeEnd(T tree, int endpos) { - return endPosTable.storeEnd(tree, endpos); + tree.endpos = Math.max(endpos, errorEndPos); + return tree; } /** * Store current token's ending position for a tree, the value of which - * will be the greater of last error position in {@link #endPosTable} + * will be the greater of {@link #errorEndPos} * and the ending position of the current token. * @param tree tree node */ @@ -707,7 +699,7 @@ public class JavacParser implements Parser { /** * Store current token's ending position for a tree, the value of which - * will be the greater of last error position in {@link #endPosTable} + * will be the greater of {@link #errorEndPos} * and the ending position of the previous token. * @param tree tree node */ @@ -733,7 +725,7 @@ public class JavacParser implements Parser { * @param tree The tree node */ public int getEndPos(JCTree tree) { - return endPosTable.getEndPos(tree); + return tree.endpos; } @@ -1269,7 +1261,7 @@ public class JavacParser implements Parser { JCAnnotation typeAnno = F.at(decl.pos) .TypeAnnotation(decl.annotationType, decl.args); - endPosTable.replaceTree(decl, typeAnno); + typeAnno.endpos = decl.endpos; return typeAnno; }); type = insertAnnotationsToMostInner(type, typeAnnos, false); @@ -1358,7 +1350,7 @@ public class JavacParser implements Parser { } else { JCExpression t = F.at(litBuf.first().getStartPosition()).Literal(TypeTag.CLASS, litBuf.stream().map(lit -> (String)lit.getValue()).collect(Collectors.joining())); - storeEnd(t, litBuf.last().getEndPosition(endPosTable)); + storeEnd(t, litBuf.last().getEndPosition()); opStack.prepend(t); return true; } @@ -1654,7 +1646,7 @@ public class JavacParser implements Parser { } // typeArgs saved for next loop iteration. t = toP(F.at(pos).Select(t, ident())); - if (token.pos <= endPosTable.errorEndPos && + if (token.pos <= errorEndPos && token.kind == MONKEYS_AT) { //error recovery, case like: //int i = expr. @@ -1878,7 +1870,7 @@ public class JavacParser implements Parser { tyannos = typeAnnotationsOpt(); } t = toP(F.at(pos1).Select(t, ident(true))); - if (token.pos <= endPosTable.errorEndPos && + if (token.pos <= errorEndPos && token.kind == MONKEYS_AT) { //error recovery, case like: //int i = expr. @@ -2533,7 +2525,7 @@ public class JavacParser implements Parser { int pos = token.pos; nextToken(); accept(CLASS); - if (token.pos == endPosTable.errorEndPos) { + if (token.pos == errorEndPos) { // error recovery Name name; if (LAX_IDENTIFIER.test(token.kind)) { @@ -2867,7 +2859,7 @@ public class JavacParser implements Parser { // error recovery if (token.pos == lastErrPos) return stats.toList(); - if (token.pos <= endPosTable.errorEndPos) { + if (token.pos <= errorEndPos) { skip(false, true, true, true); lastErrPos = token.pos; } @@ -4045,7 +4037,7 @@ public class JavacParser implements Parser { boolean firstTypeDecl = true; // have we seen a class, enum, or interface declaration yet? boolean isImplicitClass = false; OUTER: while (token.kind != EOF) { - if (token.pos <= endPosTable.errorEndPos) { + if (token.pos <= errorEndPos) { // error recovery skip(firstTypeDecl, false, false, false); if (token.kind == EOF) @@ -4156,7 +4148,6 @@ public class JavacParser implements Parser { toplevel.docComments = docComments; if (keepLineMap) toplevel.lineMap = S.getLineMap(); - toplevel.endPositions = this.endPosTable; return toplevel; } @@ -4576,7 +4567,7 @@ public class JavacParser implements Parser { hasStructuralErrors = true; } defs.append(enumeratorDeclaration(enumName)); - if (token.pos <= endPosTable.errorEndPos) { + if (token.pos <= errorEndPos) { // error recovery skip(false, true, true, false); } else { @@ -4599,7 +4590,7 @@ public class JavacParser implements Parser { wasError = false; defs.appendList(classOrInterfaceOrRecordBodyDeclaration(null, enumName, false, false)); - if (token.pos <= endPosTable.errorEndPos) { + if (token.pos <= errorEndPos) { // error recovery skip(false, true, true, false); } @@ -4696,7 +4687,7 @@ public class JavacParser implements Parser { */ List classInterfaceOrRecordBody(Name className, boolean isInterface, boolean isRecord) { accept(LBRACE); - if (token.pos <= endPosTable.errorEndPos) { + if (token.pos <= errorEndPos) { // error recovery skip(false, true, false, false); if (token.kind == LBRACE) @@ -4707,7 +4698,7 @@ public class JavacParser implements Parser { ListBuffer defs = new ListBuffer<>(); while (token.kind != RBRACE && token.kind != EOF) { defs.appendList(classOrInterfaceOrRecordBodyDeclaration(null, className, isInterface, isRecord)); - if (token.pos <= endPosTable.errorEndPos) { + if (token.pos <= errorEndPos) { // error recovery skip(false, true, true, false); } @@ -5067,7 +5058,7 @@ public class JavacParser implements Parser { boolean unclosedParameterList; if (!isRecord || name != names.init || token.kind == LPAREN) { params = formalParameters(); - unclosedParameterList = token.pos == endPosTable.errorEndPos; + unclosedParameterList = token.pos == errorEndPos; if (!isVoid) type = bracketsOpt(type); if (token.kind == THROWS) { nextToken(); @@ -5093,7 +5084,7 @@ public class JavacParser implements Parser { defaultValue = null; accept(SEMI, tk -> Errors.Expected2(LBRACE, SEMI)); } - if (token.pos <= endPosTable.errorEndPos) { + if (token.pos <= errorEndPos) { // error recovery // look if there is a probable missing opening brace, // and if yes, parse as a block @@ -5631,70 +5622,4 @@ public class JavacParser implements Parser { unexpectedTopLevelDefinitionStartError = Errors.Expected3(CLASS, INTERFACE, ENUM); } } - - /** - * A straightforward {@link EndPosTable} implementation. - */ - protected static class SimpleEndPosTable extends AbstractEndPosTable { - - private final IntHashTable endPosMap = new IntHashTable(); - - @Override - public T storeEnd(T tree, int endpos) { - endPosMap.put(tree, Math.max(endpos, errorEndPos)); - return tree; - } - - @Override - public int getEndPos(JCTree tree) { - int value = endPosMap.get(tree); - // As long as Position.NOPOS==-1, this just returns value. - return (value == -1) ? Position.NOPOS : value; - } - - @Override - public int replaceTree(JCTree oldTree, JCTree newTree) { - int pos = endPosMap.remove(oldTree); - if (pos != -1 && newTree != null) { - storeEnd(newTree, pos); - } - return pos; - } - } - - /** - * A minimal implementation that only stores what's required. - */ - protected static class MinimalEndPosTable extends SimpleEndPosTable { - - @Override - public T storeEnd(T tree, int endpos) { - switch (tree.getTag()) { - case MODULEDEF: - case PACKAGEDEF: - case CLASSDEF: - case METHODDEF: - case VARDEF: - break; - default: - return tree; - } - return super.storeEnd(tree, endpos); - } - } - - protected abstract static class AbstractEndPosTable implements EndPosTable { - - /** - * Store the last error position. - */ - public int errorEndPos = Position.NOPOS; - - @Override - public void setErrorEndPos(int errPos) { - if (errPos > errorEndPos) { - errorEndPos = errPos; - } - } - } } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/ParserFactory.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/ParserFactory.java index f9e187315ba..d06dd2cacda 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/ParserFactory.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/ParserFactory.java @@ -28,7 +28,6 @@ package com.sun.tools.javac.parser; import java.util.Locale; import com.sun.tools.javac.api.JavacTrees; -import com.sun.tools.javac.code.Lint; import com.sun.tools.javac.code.Preview; import com.sun.tools.javac.code.Source; import com.sun.tools.javac.tree.DocTreeMaker; @@ -89,13 +88,9 @@ public class ParserFactory { this.trees = JavacTrees.instance(context); } - public JavacParser newParser(CharSequence input, boolean keepDocComments, boolean keepEndPos, boolean keepLineMap) { - return newParser(input, keepDocComments, keepEndPos, keepLineMap, false); - } - - public JavacParser newParser(CharSequence input, boolean keepDocComments, boolean keepEndPos, boolean keepLineMap, boolean parseModuleInfo) { + public JavacParser newParser(CharSequence input, boolean keepDocComments, boolean keepLineMap, boolean parseModuleInfo) { Lexer lexer = scannerFactory.newScanner(input, keepDocComments); - return new JavacParser(this, lexer, keepDocComments, keepLineMap, keepEndPos, parseModuleInfo); + return new JavacParser(this, lexer, keepDocComments, keepLineMap, parseModuleInfo); } public JavacTrees getTrees() { diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties index 2ba9122c04a..bb81916becb 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -1476,6 +1476,26 @@ compiler.err.not.exhaustive=\ compiler.err.not.exhaustive.statement=\ the switch statement does not cover all possible input values +compiler.err.not.exhaustive.details=\ + the switch expression does not cover all possible input values\n\ + missing patterns: + +compiler.err.not.exhaustive.statement.details=\ + the switch statement does not cover all possible input values\n\ + missing patterns: + +# 0: type +compiler.misc.binding.pattern=\ + {0} _ + +# 0: type, 1: list of diagnostic +compiler.misc.record.pattern=\ + {0}({1}) + +# 0: type, 1: name +compiler.misc.enum.constant.pattern=\ + {0}.{1} + compiler.err.initializer.must.be.able.to.complete.normally=\ initializer must be able to complete normally diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DCTree.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DCTree.java index a999786f119..023e5c74b3a 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DCTree.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DCTree.java @@ -305,7 +305,7 @@ public abstract class DCTree implements DocTree { } @Override - public int getEndPosition(EndPosTable endPosTable) { + public int getEndPosition() { return comment.getSourcePos(end); } }; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/EndPosTable.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/EndPosTable.java deleted file mode 100644 index 83fe402c0a7..00000000000 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/EndPosTable.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.tools.javac.tree; - -import com.sun.tools.javac.util.Position; - -/** - * Specifies the methods to access a mappings of syntax trees to end positions. - * - *

    - * Implementations must store end positions for at least these node types: - *

      - *
    • {@link JCTree.JCModuleDecl} - *
    • {@link JCTree.JCPackageDecl} - *
    • {@link JCTree.JCClassDecl} - *
    • {@link JCTree.JCMethodDecl} - *
    • {@link JCTree.JCVariableDecl} - *
    - * - *

    This is NOT part of any supported API. - * If you write code that depends on this, you do so at your own - * risk. This code and its internal interfaces are subject to change - * or deletion without notice.

    - */ -public interface EndPosTable { - - /** - * This method will return the end position of a given tree, otherwise a - * Positions.NOPOS will be returned. - * @param tree JCTree - * @return position of the source tree or Positions.NOPOS for non-existent mapping - */ - int getEndPos(JCTree tree); - - /** - * Store ending position for a tree, the value of which is the greater of - * last error position and the given ending position. - * @param tree The tree. - * @param endpos The ending position to associate with the tree. - * @return the {@code tree} - */ - T storeEnd(T tree, int endpos); - - /** - * Set the error position during the parsing phases, the value of which - * will be set only if it is greater than the last stored error position. - * @param errPos The error position - */ - void setErrorEndPos(int errPos); - - /** - * Give an old tree and a new tree, the old tree will be replaced with - * the new tree, the position of the new tree will be that of the old - * tree. - * @param oldtree a JCTree to be replaced - * @param newtree a JCTree to be replaced with, or null to just remove {@code oldtree} - * @return position of the old tree or Positions.NOPOS for non-existent mapping - */ - int replaceTree(JCTree oldtree, JCTree newtree); -} diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java index 6501fd5d96c..e0a99a6f103 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java @@ -431,6 +431,10 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { */ public int pos; + /* The (encoded) end position in the source file. @see util.Position. + */ + public int endpos = Position.NOPOS; + /* The type of this node. */ public Type type; @@ -514,8 +518,8 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { } // for default DiagnosticPosition - public int getEndPosition(EndPosTable endPosTable) { - return noNoPos(TreeInfo.getEndPos(this, endPosTable)); + public int getEndPosition() { + return noNoPos(TreeInfo.getEndPos(this)); } private int noNoPos(int position) { @@ -552,9 +556,6 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { /** A table that stores all documentation comments indexed by the tree * nodes they refer to. defined only if option -s is set. */ public DocCommentTable docComments = null; - /* An object encapsulating ending positions of source ranges indexed by - * the tree nodes they belong to. Defined only if option -Xjcov is set. */ - public EndPosTable endPositions = null; protected JCCompilationUnit(List defs) { this.defs = defs; } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java index 3f73bfd2296..aa616f3f580 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java @@ -31,7 +31,6 @@ import com.sun.source.tree.Tree; import com.sun.source.util.TreePath; import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Symbol.RecordComponent; -import com.sun.tools.javac.comp.AttrContext; import com.sun.tools.javac.comp.Env; import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*; @@ -647,18 +646,13 @@ public class TreeInfo { /** The end position of given tree, given a table of end positions generated by the parser */ - public static int getEndPos(JCTree tree, EndPosTable endPosTable) { + public static int getEndPos(JCTree tree) { if (tree == null) return Position.NOPOS; - if (endPosTable == null) { - // fall back on limited info in the tree - return endPos(tree); - } - - int mapPos = endPosTable.getEndPos(tree); - if (mapPos != Position.NOPOS) - return mapPos; + int endpos = tree.endpos; + if (endpos != Position.NOPOS) + return endpos; switch(tree.getTag()) { case BITOR_ASG: case BITXOR_ASG: case BITAND_ASG: @@ -678,57 +672,57 @@ public class TreeInfo { case COMPL: case PREINC: case PREDEC: - return getEndPos(((JCOperatorExpression) tree).getOperand(RIGHT), endPosTable); + return getEndPos(((JCOperatorExpression) tree).getOperand(RIGHT)); case CASE: - return getEndPos(((JCCase) tree).stats.last(), endPosTable); + return getEndPos(((JCCase) tree).stats.last()); case CATCH: - return getEndPos(((JCCatch) tree).body, endPosTable); + return getEndPos(((JCCatch) tree).body); case CONDEXPR: - return getEndPos(((JCConditional) tree).falsepart, endPosTable); + return getEndPos(((JCConditional) tree).falsepart); case FORLOOP: - return getEndPos(((JCForLoop) tree).body, endPosTable); + return getEndPos(((JCForLoop) tree).body); case FOREACHLOOP: - return getEndPos(((JCEnhancedForLoop) tree).body, endPosTable); + return getEndPos(((JCEnhancedForLoop) tree).body); case IF: { JCIf node = (JCIf)tree; if (node.elsepart == null) { - return getEndPos(node.thenpart, endPosTable); + return getEndPos(node.thenpart); } else { - return getEndPos(node.elsepart, endPosTable); + return getEndPos(node.elsepart); } } case LABELLED: - return getEndPos(((JCLabeledStatement) tree).body, endPosTable); + return getEndPos(((JCLabeledStatement) tree).body); case MODIFIERS: - return getEndPos(((JCModifiers) tree).annotations.last(), endPosTable); + return getEndPos(((JCModifiers) tree).annotations.last()); case SYNCHRONIZED: - return getEndPos(((JCSynchronized) tree).body, endPosTable); + return getEndPos(((JCSynchronized) tree).body); case TOPLEVEL: - return getEndPos(((JCCompilationUnit) tree).defs.last(), endPosTable); + return getEndPos(((JCCompilationUnit) tree).defs.last()); case TRY: { JCTry node = (JCTry)tree; if (node.finalizer != null) { - return getEndPos(node.finalizer, endPosTable); + return getEndPos(node.finalizer); } else if (!node.catchers.isEmpty()) { - return getEndPos(node.catchers.last(), endPosTable); + return getEndPos(node.catchers.last()); } else { - return getEndPos(node.body, endPosTable); + return getEndPos(node.body); } } case WILDCARD: - return getEndPos(((JCWildcard) tree).inner, endPosTable); + return getEndPos(((JCWildcard) tree).inner); case TYPECAST: - return getEndPos(((JCTypeCast) tree).expr, endPosTable); + return getEndPos(((JCTypeCast) tree).expr); case TYPETEST: - return getEndPos(((JCInstanceOf) tree).pattern, endPosTable); + return getEndPos(((JCInstanceOf) tree).pattern); case WHILELOOP: - return getEndPos(((JCWhileLoop) tree).body, endPosTable); + return getEndPos(((JCWhileLoop) tree).body); case ANNOTATED_TYPE: - return getEndPos(((JCAnnotatedType) tree).underlyingType, endPosTable); + return getEndPos(((JCAnnotatedType) tree).underlyingType); case ERRONEOUS: { JCErroneous node = (JCErroneous)tree; if (node.errs != null && node.errs.nonEmpty()) - return getEndPos(node.errs.last(), endPosTable); + return getEndPos(node.errs.last()); } } return Position.NOPOS; @@ -745,8 +739,8 @@ public class TreeInfo { public JCTree getTree() { return tree; } public int getStartPosition() { return TreeInfo.getStartPos(tree); } public int getPreferredPosition() { return endPos; } - public int getEndPosition(EndPosTable endPosTable) { - return TreeInfo.getEndPos(tree, endPosTable); + public int getEndPosition() { + return TreeInfo.getEndPos(tree); } }; } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/DiagnosticSource.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/DiagnosticSource.java index baae3101811..3339900733f 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/DiagnosticSource.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/DiagnosticSource.java @@ -31,7 +31,6 @@ import java.nio.CharBuffer; import javax.tools.JavaFileObject; import com.sun.tools.javac.file.JavacFileManager; -import com.sun.tools.javac.tree.EndPosTable; import static com.sun.tools.javac.util.LayoutCharacters.*; @@ -127,16 +126,6 @@ public class DiagnosticSource { } } - public EndPosTable getEndPosTable() { - return endPosTable; - } - - public void setEndPosTable(EndPosTable t) { - if (endPosTable != null && endPosTable != t) - throw new IllegalStateException("endPosTable already set"); - endPosTable = t; - } - /** Find the line in the buffer that contains the current position * @param pos Character offset into the buffer */ @@ -197,8 +186,6 @@ public class DiagnosticSource { /** The underlying file object. */ protected JavaFileObject fileObject; - protected EndPosTable endPosTable; - /** A soft reference to the content of the file object. */ protected SoftReference refBuf; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/IntHashTable.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/IntHashTable.java deleted file mode 100644 index 409dc703d60..00000000000 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/IntHashTable.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.tools.javac.util; - -/** - * A hash table that maps Object to int. - * - * This is a custom hash table optimised for the Object {@literal ->} int - * maps. This is done to avoid unnecessary object allocation in the image set. - * - * @author Charles Turner - * @author Per Bothner - */ -public class IntHashTable { - private static final int DEFAULT_INITIAL_SIZE = 64; - protected Object[] objs; // the domain set - protected int[] ints; // the image set - protected int mask; // used to clip int's into the domain - protected int num_bindings; // the number of mappings (including DELETED) - private static final Object DELETED = new Object(); - - /** - * Construct an Object {@literal ->} int hash table. - * - * The default size of the hash table is 64 mappings. - */ - public IntHashTable() { - objs = new Object[DEFAULT_INITIAL_SIZE]; - ints = new int[DEFAULT_INITIAL_SIZE]; - mask = DEFAULT_INITIAL_SIZE - 1; - } - - /** - * Construct an Object {@literal ->} int hash table with a specified amount of mappings. - * @param capacity The number of default mappings in this hash table. - */ - public IntHashTable(int capacity) { - int log2Size = 4; - while (capacity > (1 << log2Size)) { - log2Size++; - } - capacity = 1 << log2Size; - objs = new Object[capacity]; - ints = new int[capacity]; - mask = capacity - 1; - } - - /** - * Compute the hash code of a given object. - * - * @param key The object whose hash code is to be computed. - * @return zero if the object is null, otherwise the identityHashCode - */ - protected int hash(Object key) { - return System.identityHashCode(key); - } - - /** - * Find either the index of a key's value, or the index of an available space. - * - * @param key The key to whose index you want to find. - * @return Either the index of the key's value, or an index pointing to - * unoccupied space. - */ - protected int lookup(Object key) { - Object node; - int hash = hash(key); - int hash1 = hash ^ (hash >>> 15); - int hash2 = (hash ^ (hash << 6)) | 1; //ensure coprimeness - int deleted = -1; - for (int i = hash1 & mask;; i = (i + hash2) & mask) { - node = objs[i]; - if (node == key) - return i; - if (node == null) - return deleted >= 0 ? deleted : i; - if (node == DELETED && deleted < 0) - deleted = i; - } - } - - /** - * Return the value to which the specified key is mapped. - * - * @param key The key to whose value you want to find. - * @return A non-negative integer if the value is found. - * Otherwise, it is -1. - */ - public int get(Object key) { - int index = lookup(key); - Object node = objs[index]; - return node == null || node == DELETED ? -1 : ints[index]; - } - - /** - * Associates the specified key with the specified value in this map. - * - * @param key key with which the specified value is to be associated. - * @param value value to be associated with the specified key. - * @return previous value associated with specified key, or -1 if there was - * no mapping for key. - */ - public int put(Object key, int value) { - int index = lookup(key); - Object old = objs[index]; - if (old == null || old == DELETED) { - objs[index] = key; - ints[index] = value; - if (old != DELETED) - num_bindings++; - if (3 * num_bindings >= 2 * objs.length) - rehash(); - return -1; - } else { // update existing mapping - int oldValue = ints[index]; - ints[index] = value; - return oldValue; - } - } - - /** - * Remove the mapping(key and value) of the specified key. - * - * @param key the key to whose value you want to remove. - * @return the removed value associated with the specified key, - * or -1 if there was no mapping for the specified key. - */ - public int remove(Object key) { - int index = lookup(key); - Object old = objs[index]; - if (old == null || old == DELETED) - return -1; - objs[index] = DELETED; - return ints[index]; - } - - /** - * Expand the hash table when it exceeds the load factor. - * - * Rehash the existing objects. - */ - protected void rehash() { - Object[] oldObjsTable = objs; - int[] oldIntsTable = ints; - int newCapacity = oldObjsTable.length << 1; - objs = new Object[newCapacity]; - ints = new int[newCapacity]; - mask = newCapacity - 1; - num_bindings = 0; // this is recomputed below - Object key; - for (int i = oldIntsTable.length; --i >= 0;) { - key = oldObjsTable[i]; - if (key != null && key != DELETED) - put(key, oldIntsTable[i]); - } - } - - /** - * Removes all mappings from this map. - */ - public void clear() { - for (int i = objs.length; --i >= 0;) { - objs[i] = null; - } - num_bindings = 0; - } -} diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/JCDiagnostic.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/JCDiagnostic.java index c9f529eae55..328183c0cb3 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/JCDiagnostic.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/JCDiagnostic.java @@ -38,7 +38,6 @@ import javax.tools.JavaFileObject; import com.sun.tools.javac.api.DiagnosticFormatter; import com.sun.tools.javac.code.Lint.LintCategory; import com.sun.tools.javac.code.Type; -import com.sun.tools.javac.tree.EndPosTable; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.util.DefinedBy.Api; @@ -364,10 +363,8 @@ public class JCDiagnostic implements Diagnostic { /** Get the position within the file that most accurately defines the * location for the diagnostic. */ int getPreferredPosition(); - /** If there is a tree node, and if endPositions are available, get - * the end position of the tree node. Otherwise, just returns the - * same as getPreferredPosition(). */ - int getEndPosition(EndPosTable endPosTable); + /** If there is a tree node, get the end position of the tree node. */ + int getEndPosition(); /** Get the position that determines which Lint configuration applies. */ default int getLintPosition() { return getStartPosition(); @@ -389,8 +386,8 @@ public class JCDiagnostic implements Diagnostic { return orig.getPreferredPosition(); } @Override - public int getEndPosition(EndPosTable endPosTable) { - return orig.getEndPosition(endPosTable); + public int getEndPosition() { + return orig.getEndPosition(); } @Override public int getLintPosition() { @@ -421,7 +418,7 @@ public class JCDiagnostic implements Diagnostic { return pos; } - public int getEndPosition(EndPosTable endPosTable) { + public int getEndPosition() { return pos; } @@ -747,7 +744,7 @@ public class JCDiagnostic implements Diagnostic { } protected int getIntEndPosition() { - return (position == null ? Position.NOPOS : position.getEndPosition(source.getEndPosTable())); + return (position == null ? Position.NOPOS : position.getEndPosition()); } @DefinedBy(Api.COMPILER) diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java index a4109a35ccb..b061d2283a0 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java @@ -55,7 +55,6 @@ import com.sun.tools.javac.comp.AttrContext; import com.sun.tools.javac.comp.Env; import com.sun.tools.javac.main.Main; import com.sun.tools.javac.main.Option; -import com.sun.tools.javac.tree.EndPosTable; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.TreeInfo; @@ -594,11 +593,6 @@ public class Log extends AbstractLog { return diagListener != null; } - public void setEndPosTable(JavaFileObject name, EndPosTable endPosTable) { - Assert.checkNonNull(name); - getSource(name).setEndPosTable(endPosTable); - } - /** Return current sourcefile. */ public JavaFileObject currentSourceFile() { diff --git a/src/jdk.compiler/share/data/symbols/java.base-Q.sym.txt b/src/jdk.compiler/share/data/symbols/java.base-Q.sym.txt index 29ecd9f0304..9166b505c51 100644 --- a/src/jdk.compiler/share/data/symbols/java.base-Q.sym.txt +++ b/src/jdk.compiler/share/data/symbols/java.base-Q.sym.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -429,6 +429,10 @@ innerclass innerClass java/io/ObjectOutputStream$PutField outerClass java/io/Obj innerclass innerClass java/util/AbstractMap$SimpleImmutableEntry outerClass java/util/AbstractMap innerClassName SimpleImmutableEntry flags 9 innerclass innerClass java/util/concurrent/ConcurrentHashMap$CollectionView outerClass java/util/concurrent/ConcurrentHashMap innerClassName CollectionView flags 408 +class name java/util/concurrent/CopyOnWriteArraySet +header extends java/util/AbstractSet implements java/io/Serializable flags 21 signature Ljava/util/AbstractSet;Ljava/io/Serializable; +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 + class name java/util/concurrent/StructuredTaskScope -method name open descriptor (Ljava/util/concurrent/StructuredTaskScope$Joiner;Ljava/util/function/Function;)Ljava/util/concurrent/StructuredTaskScope; method name open descriptor (Ljava/util/concurrent/StructuredTaskScope$Joiner;Ljava/util/function/UnaryOperator;)Ljava/util/concurrent/StructuredTaskScope; flags 9 signature (Ljava/util/concurrent/StructuredTaskScope$Joiner<-TT;+TR;>;Ljava/util/function/UnaryOperator;)Ljava/util/concurrent/StructuredTaskScope; diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Cipher.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Cipher.java index 9c923b76215..39827af42e5 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Cipher.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Cipher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1198,7 +1198,9 @@ final class P11Cipher extends CipherSpi { } private void handleException(PKCS11Exception e) - throws ShortBufferException, IllegalBlockSizeException { + throws ShortBufferException, IllegalBlockSizeException, + BadPaddingException { + if (e.match(CKR_BUFFER_TOO_SMALL)) { throw (ShortBufferException) (new ShortBufferException().initCause(e)); @@ -1206,6 +1208,9 @@ final class P11Cipher extends CipherSpi { e.match(CKR_ENCRYPTED_DATA_LEN_RANGE)) { throw (IllegalBlockSizeException) (new IllegalBlockSizeException(e.toString()).initCause(e)); + } else if (e.match(CKR_ENCRYPTED_DATA_INVALID)) { + throw (BadPaddingException) + (new BadPaddingException(e.toString()).initCause(e)); } } diff --git a/src/jdk.hotspot.agent/linux/native/libsaproc/DwarfParser.cpp b/src/jdk.hotspot.agent/linux/native/libsaproc/DwarfParser.cpp index 8df08c49e09..6c94992e1e2 100644 --- a/src/jdk.hotspot.agent/linux/native/libsaproc/DwarfParser.cpp +++ b/src/jdk.hotspot.agent/linux/native/libsaproc/DwarfParser.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2020, 2021, NTT DATA. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, NTT DATA. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -219,16 +219,3 @@ JNIEXPORT jint JNICALL Java_sun_jvm_hotspot_debugger_linux_amd64_DwarfParser_get DwarfParser *parser = reinterpret_cast(get_dwarf_context(env, this_obj)); return parser->get_bp_cfa_offset(); } - -/* - * Class: sun_jvm_hotspot_debugger_linux_amd64_DwarfParser - * Method: isBPOffsetAvailable - * Signature: ()Z - */ -extern "C" -JNIEXPORT jboolean JNICALL Java_sun_jvm_hotspot_debugger_linux_amd64_DwarfParser_isBPOffsetAvailable - (JNIEnv *env, jobject this_obj) { - DwarfParser *parser = reinterpret_cast(get_dwarf_context(env, this_obj)); - return parser->is_bp_offset_available(); -} - diff --git a/src/jdk.hotspot.agent/linux/native/libsaproc/dwarf.cpp b/src/jdk.hotspot.agent/linux/native/libsaproc/dwarf.cpp index a0c54230530..2636bdf691a 100644 --- a/src/jdk.hotspot.agent/linux/native/libsaproc/dwarf.cpp +++ b/src/jdk.hotspot.agent/linux/native/libsaproc/dwarf.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2020, NTT DATA. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, NTT DATA. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -99,12 +99,11 @@ bool DwarfParser::process_cie(unsigned char *start_of_entry, uint32_t id) { // Clear state _current_pc = 0L; - _cfa_reg = RSP; + _cfa_reg = MAX_VALUE; _return_address_reg = RA; _cfa_offset = 0; - _ra_cfa_offset = 0; - _bp_cfa_offset = 0; - _bp_offset_available = false; + _ra_cfa_offset = 8; + _bp_cfa_offset = INT_MAX; parse_dwarf_instructions(0L, static_cast(-1L), end); @@ -119,8 +118,8 @@ void DwarfParser::parse_dwarf_instructions(uintptr_t begin, uintptr_t pc, const /* for remember state */ enum DWARF_Register rem_cfa_reg = MAX_VALUE; int rem_cfa_offset = 0; - int rem_ra_cfa_offset = 0; - int rem_bp_cfa_offset = 0; + int rem_ra_cfa_offset = 8; + int rem_bp_cfa_offset = INT_MAX; while ((_buf < end) && (_current_pc < pc)) { unsigned char op = *_buf++; @@ -147,7 +146,6 @@ void DwarfParser::parse_dwarf_instructions(uintptr_t begin, uintptr_t pc, const enum DWARF_Register reg = static_cast(opa); if (reg == RBP) { _bp_cfa_offset = operand1 * _data_factor; - _bp_offset_available = true; } else if (reg == RA) { _ra_cfa_offset = operand1 * _data_factor; } @@ -184,6 +182,14 @@ void DwarfParser::parse_dwarf_instructions(uintptr_t begin, uintptr_t pc, const } break; } + case 0x07: { // DW_CFA_undefined + enum DWARF_Register reg = static_cast(read_leb(false)); + // We are only interested in BP here because CFA and RA should not be undefined. + if (reg == RBP) { + _bp_cfa_offset = INT_MAX; + } + break; + } case 0x0d: {// DW_CFA_def_cfa_register _cfa_reg = static_cast(read_leb(false)); break; diff --git a/src/jdk.hotspot.agent/linux/native/libsaproc/dwarf.hpp b/src/jdk.hotspot.agent/linux/native/libsaproc/dwarf.hpp index a047ffae247..a2692738ce1 100644 --- a/src/jdk.hotspot.agent/linux/native/libsaproc/dwarf.hpp +++ b/src/jdk.hotspot.agent/linux/native/libsaproc/dwarf.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2020, NTT DATA. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, NTT DATA. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -73,7 +73,6 @@ class DwarfParser { int _cfa_offset; int _ra_cfa_offset; int _bp_cfa_offset; - bool _bp_offset_available; uintptr_t read_leb(bool sign); uint64_t get_entry_length(); @@ -86,15 +85,14 @@ class DwarfParser { DwarfParser(lib_info *lib) : _lib(lib), _buf(NULL), _encoding(0), - _cfa_reg(RSP), + _cfa_reg(MAX_VALUE), _return_address_reg(RA), _code_factor(0), _data_factor(0), _current_pc(0L), _cfa_offset(0), - _ra_cfa_offset(0), - _bp_cfa_offset(0), - _bp_offset_available(false) {}; + _ra_cfa_offset(8), + _bp_cfa_offset(INT_MAX) {}; ~DwarfParser() {} bool process_dwarf(const uintptr_t pc); @@ -102,7 +100,6 @@ class DwarfParser { int get_cfa_offset() { return _cfa_offset; } int get_ra_cfa_offset() { return _ra_cfa_offset; } int get_bp_cfa_offset() { return _bp_cfa_offset; } - bool is_bp_offset_available() { return _bp_offset_available; } bool is_in(long pc) { return (_lib->exec_start <= pc) && (pc < _lib->exec_end); diff --git a/src/jdk.hotspot.agent/linux/native/libsaproc/symtab.c b/src/jdk.hotspot.agent/linux/native/libsaproc/symtab.c index 07cbb46d045..c8f3fb2ed4c 100644 --- a/src/jdk.hotspot.agent/linux/native/libsaproc/symtab.c +++ b/src/jdk.hotspot.agent/linux/native/libsaproc/symtab.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -550,14 +550,33 @@ uintptr_t search_symbol(struct symtab* symtab, uintptr_t base, return (uintptr_t) NULL; } +static bool is_in(uintptr_t offset, struct elf_symbol* sym) { + if (sym->size == 0 && offset == sym->offset) { + // offset points to the top of the symbol. + // Some functions have size 0. For example, __restore_rt() (signal trampoline + // in glibc) would be detected as out of the function incorrectly, even if it + // points to the top of the instruction address, because the size of + // __restore_rt() is 0 (you can see this with "readelf -s libc.so.6" when + // debug symbols are available). + // Hence we need to treat this as a special case if the function size is 0, + // only the exact symbol address should be treated as inside. + return true; + } else if (offset >= sym->offset && offset < sym->offset + sym->size) { + // offset is in address range of the symbol + return true; + } + + // offset is out of address range of the symbol + return false; +} + const char* nearest_symbol(struct symtab* symtab, uintptr_t offset, uintptr_t* poffset) { int n = 0; if (!symtab) return NULL; for (; n < symtab->num_symbols; n++) { struct elf_symbol* sym = &(symtab->symbols[n]); - if (sym->name != NULL && - offset >= sym->offset && offset < sym->offset + sym->size) { + if (sym->name != NULL && is_in(offset, sym)) { if (poffset) *poffset = (offset - sym->offset); return sym->name; } diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java index e3543503216..15f6615421c 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, Red Hat Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -81,11 +81,7 @@ class LinuxCDebugger implements CDebugger { String cpu = dbg.getCPU(); if (cpu.equals("amd64")) { AMD64ThreadContext context = (AMD64ThreadContext) thread.getContext(); - Address sp = context.getRegisterAsAddress(AMD64ThreadContext.RSP); - if (sp == null) return null; - Address pc = context.getRegisterAsAddress(AMD64ThreadContext.RIP); - if (pc == null) return null; - return LinuxAMD64CFrame.getTopFrame(dbg, sp, pc, context); + return LinuxAMD64CFrame.getTopFrame(dbg, context); } else if (cpu.equals("ppc64")) { PPC64ThreadContext context = (PPC64ThreadContext) thread.getContext(); Address sp = context.getRegisterAsAddress(PPC64ThreadContext.SP); diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebugger.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebugger.java index 1106d846eca..a53b8a0a282 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebugger.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebugger.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2026, Oracle and/or its affiliates. All rights reserved. * 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,14 @@ import sun.jvm.hotspot.debugger.cdbg.*; by the architecture-specific subpackages. */ public interface LinuxDebugger extends JVMDebugger { + // SIGHANDLER_NAMES holds the name of signal handler. + public static final List SIGHANDLER_NAMES = List.of( + // For AMD64 + // - sysdeps/unix/sysv/linux/x86_64/libc_sigaction.c in glibc + // - gdb/amd64-linux-tdep.c in GDB + "__restore_rt" + ); + public String addressValueToString(long address) throws DebuggerException; public boolean readJBoolean(long address) throws DebuggerException; public byte readJByte(long address) throws DebuggerException; @@ -52,6 +60,7 @@ public interface LinuxDebugger extends JVMDebugger { public long[] getThreadIntegerRegisterSet(int lwp_id) throws DebuggerException; public long getAddressValue(Address addr) throws DebuggerException; public Address findLibPtrByAddress(Address pc); + public boolean isSignalTrampoline(Address pc); // For LinuxCDebugger public List getThreadList(); diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebuggerLocal.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebuggerLocal.java index 261df12c8f1..9a75511e44d 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebuggerLocal.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebuggerLocal.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -130,6 +130,12 @@ public class LinuxDebuggerLocal extends DebuggerBase implements LinuxDebugger { : new LinuxAddress(this, ptr); } + @Override + public boolean isSignalTrampoline(Address pc) { + var sym = lookup(getAddressValue(pc)); + return sym == null ? false : SIGHANDLER_NAMES.contains(sym.getName()); + } + // Note on Linux threads are really processes. When target process is // attached by a serviceability agent thread, only that thread can do // ptrace operations on the target. This is because from kernel's point diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/amd64/DwarfParser.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/amd64/DwarfParser.java index 3b63ee0a21e..53351c918d3 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/amd64/DwarfParser.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/amd64/DwarfParser.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2020, NTT DATA. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, NTT DATA. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -66,9 +66,15 @@ public class DwarfParser { processDwarf0(pc.asLongValue()); } + /** + * @return true if BP offset is declared in DWARF instructions. + */ + public boolean isBPOffsetAvailable() { + return getBasePointerOffsetFromCFA() != Integer.MAX_VALUE; + } + public native int getCFARegister(); public native int getCFAOffset(); public native int getReturnAddressOffsetFromCFA(); public native int getBasePointerOffsetFromCFA(); - public native boolean isBPOffsetAvailable(); } diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/amd64/LinuxAMD64CFrame.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/amd64/LinuxAMD64CFrame.java index 612203634f3..4d3d9d5998d 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/amd64/LinuxAMD64CFrame.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/amd64/LinuxAMD64CFrame.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved. * 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,12 @@ package sun.jvm.hotspot.debugger.linux.amd64; +import java.util.function.Function; + import sun.jvm.hotspot.debugger.*; import sun.jvm.hotspot.debugger.amd64.*; import sun.jvm.hotspot.debugger.linux.*; +import sun.jvm.hotspot.debugger.linux.amd64.*; import sun.jvm.hotspot.debugger.cdbg.*; import sun.jvm.hotspot.debugger.cdbg.basic.*; import sun.jvm.hotspot.runtime.*; @@ -34,9 +37,12 @@ import sun.jvm.hotspot.runtime.amd64.*; public final class LinuxAMD64CFrame extends BasicCFrame { - public static LinuxAMD64CFrame getTopFrame(LinuxDebugger dbg, Address rsp, Address rip, ThreadContext context) { + private static LinuxAMD64CFrame getFrameFromReg(LinuxDebugger dbg, Function getreg) { + Address rip = getreg.apply(AMD64ThreadContext.RIP); + Address rsp = getreg.apply(AMD64ThreadContext.RSP); + Address rbp = getreg.apply(AMD64ThreadContext.RBP); Address libptr = dbg.findLibPtrByAddress(rip); - Address cfa = context.getRegisterAsAddress(AMD64ThreadContext.RBP); + Address cfa = null; DwarfParser dwarf = null; if (libptr != null) { // Native frame @@ -47,41 +53,47 @@ public final class LinuxAMD64CFrame extends BasicCFrame { // DWARF processing should succeed when the frame is native // but it might fail if Common Information Entry (CIE) has language // personality routine and/or Language Specific Data Area (LSDA). - return new LinuxAMD64CFrame(dbg, rsp, cfa, rip, dwarf, true); + return new LinuxAMD64CFrame(dbg, rsp, rbp, cfa, rip, dwarf, true); } - cfa = context.getRegisterAsAddress(dwarf.getCFARegister()) - .addOffsetTo(dwarf.getCFAOffset()); + cfa = getreg.apply(dwarf.getCFARegister()) + .addOffsetTo(dwarf.getCFAOffset()); } - return (cfa == null) ? null - : new LinuxAMD64CFrame(dbg, rsp, cfa, rip, dwarf); + return (rbp == null && cfa == null) + ? null + : new LinuxAMD64CFrame(dbg, rsp, rbp, cfa, rip, dwarf); } - private LinuxAMD64CFrame(LinuxDebugger dbg, Address rsp, Address cfa, Address rip, DwarfParser dwarf) { - this(dbg, rsp, cfa, rip, dwarf, false); + public static LinuxAMD64CFrame getTopFrame(LinuxDebugger dbg, ThreadContext context) { + return getFrameFromReg(dbg, context::getRegisterAsAddress); } - private LinuxAMD64CFrame(LinuxDebugger dbg, Address rsp, Address cfa, Address rip, DwarfParser dwarf, boolean finalFrame) { - this(dbg, rsp, cfa, rip, dwarf, finalFrame, false); + private LinuxAMD64CFrame(LinuxDebugger dbg, Address rsp, Address rbp, Address cfa, Address rip, DwarfParser dwarf) { + this(dbg, rsp, rbp, cfa, rip, dwarf, false); } - private LinuxAMD64CFrame(LinuxDebugger dbg, Address rsp, Address cfa, Address rip, DwarfParser dwarf, boolean finalFrame, boolean use1ByteBeforeToLookup) { + private LinuxAMD64CFrame(LinuxDebugger dbg, Address rsp, Address rbp, Address cfa, Address rip, DwarfParser dwarf, boolean use1ByteBeforeToLookup) { super(dbg.getCDebugger()); this.rsp = rsp; + this.rbp = rbp; this.cfa = cfa; this.rip = rip; this.dbg = dbg; this.dwarf = dwarf; - this.finalFrame = finalFrame; this.use1ByteBeforeToLookup = use1ByteBeforeToLookup; } // override base class impl to avoid ELF parsing public ClosestSymbol closestSymbolToPC() { Address symAddr = use1ByteBeforeToLookup ? pc().addOffsetTo(-1) : pc(); - // try native lookup in debugger. - return dbg.lookup(dbg.getAddressValue(symAddr)); + var sym = dbg.lookup(dbg.getAddressValue(symAddr)); + + // Returns a special symbol if the address is signal handler, + // otherwise returns closest symbol generated by LinuxDebugger. + return dbg.isSignalTrampoline(symAddr) + ? new ClosestSymbol(sym.getName() + " ", 0) + : sym; } public Address pc() { @@ -89,77 +101,74 @@ public final class LinuxAMD64CFrame extends BasicCFrame { } public Address localVariableBase() { - return cfa; + return (dwarf != null && dwarf.isBPOffsetAvailable()) + ? cfa.addOffsetTo(dwarf.getBasePointerOffsetFromCFA()) + : rbp; } - private Address getNextPC(boolean useDwarf) { + private Address getNextPC() { try { - long offs = useDwarf ? dwarf.getReturnAddressOffsetFromCFA() - : ADDRESS_SIZE; - return cfa.getAddressAt(offs); + return dwarf == null + ? rbp.getAddressAt(ADDRESS_SIZE) // Java frame + : cfa.getAddressAt(dwarf.getReturnAddressOffsetFromCFA()); // Native frame } catch (UnmappedAddressException | UnalignedAddressException e) { return null; } } - private boolean isValidFrame(Address nextCFA, boolean isNative) { - // CFA should never be null. - // nextCFA must be greater than current CFA, if frame is native. - // Java interpreter frames can share the CFA (frame pointer). - return nextCFA != null && - (!isNative || (isNative && nextCFA.greaterThan(cfa))); + private boolean isValidFrame(Address nextCFA, Address nextRBP) { + // Both CFA and RBP must not be null. + if (nextCFA == null && nextRBP == null) { + return false; + } + + // RBP must not be null if CFA is null - it happens between Java frame and Native frame. + // We cannot validate RBP value because it might be used as GPR. Thus returns true + // if RBP is not null. + if (nextCFA == null && nextRBP != null) { + return true; + } + + // nextCFA must be greater than current CFA. + if (nextCFA != null && nextCFA.greaterThanOrEqual(cfa)) { + return true; + } + + // Otherwise, the frame is not valid. + return false; } private Address getNextRSP() { - // next RSP should be previous slot of return address. - var bp = dwarf == null ? cfa.addOffsetTo(ADDRESS_SIZE) // top of BP points callser BP - : cfa.addOffsetTo(dwarf.getReturnAddressOffsetFromCFA()); - return bp.addOffsetTo(ADDRESS_SIZE); + return dwarf == null ? rbp.addOffsetTo(2 * ADDRESS_SIZE) // Java frame - skip saved BP and RA + : cfa.addOffsetTo(dwarf.getReturnAddressOffsetFromCFA()) + .addOffsetTo(ADDRESS_SIZE); // Native frame } - private Address getNextCFA(DwarfParser nextDwarf, ThreadContext context, Address senderFP, Address senderPC) { - Address nextCFA; - boolean isNative = false; - - if (senderFP == null) { - senderFP = cfa.getAddressAt(0); // RBP by default + private Address getNextRBP(Address senderFP) { + if (senderFP != null) { + return senderFP; + } else if (dwarf == null) { // Current frame is Java + return rbp.getAddressAt(0); + } else { // Current frame is Native + return dwarf.isBPOffsetAvailable() + ? cfa.getAddressAt(dwarf.getBasePointerOffsetFromCFA()) + : rbp; } + } - if (VM.getVM().getCodeCache().contains(senderPC)) { // Next frame is Java - nextCFA = (dwarf == null) ? senderFP // Current frame is Java - : cfa.getAddressAt(dwarf.getBasePointerOffsetFromCFA()); // Current frame is Native - } else { // Next frame is Native - if (VM.getVM().getCodeCache().contains(pc())) { // Current frame is Java - nextCFA = senderFP.addOffsetTo(-nextDwarf.getBasePointerOffsetFromCFA()); - } else { // Current frame is Native - if (nextDwarf == null) { // maybe runtime entrypoint (_start()) - throw new DebuggerException("nextDwarf is null even though native call"); - } - - isNative = true; - int nextCFAReg = nextDwarf.getCFARegister(); - if (nextCFAReg == AMD64ThreadContext.RBP) { - Address rbp = dwarf.isBPOffsetAvailable() ? cfa.addOffsetTo(dwarf.getBasePointerOffsetFromCFA()) - : context.getRegisterAsAddress(AMD64ThreadContext.RBP); - Address nextRBP = rbp.getAddressAt(0); - nextCFA = nextRBP.addOffsetTo(-nextDwarf.getBasePointerOffsetFromCFA()); - } else if (nextCFAReg == AMD64ThreadContext.RSP) { - nextCFA = getNextRSP().addOffsetTo(nextDwarf.getCFAOffset()); - } else { - throw new DebuggerException("Unsupported CFA register: " + nextCFAReg); - } - } - } - - // Sanity check for next CFA address - try { - nextCFA.getAddressAt(0); - } catch (Exception e) { - // return null if next CFA address is invalid + private Address getNextCFA(DwarfParser nextDwarf, Address senderFP, Address senderPC) { + if (nextDwarf == null) { // Next frame is Java + // CFA is not available on Java frame return null; } - return isValidFrame(nextCFA, isNative) ? nextCFA : null; + // Next frame is Native + int nextCFAReg = nextDwarf.getCFARegister(); + return switch(nextCFAReg){ + case AMD64ThreadContext.RBP -> getNextRBP(senderFP).addOffsetTo(nextDwarf.getCFAOffset()); + case AMD64ThreadContext.RSP -> getNextRSP().addOffsetTo(nextDwarf.getCFAOffset()); + default -> throw new DebuggerException("Unsupported CFA register: " + nextCFAReg); + }; } @Override @@ -169,8 +178,10 @@ public final class LinuxAMD64CFrame extends BasicCFrame { @Override public CFrame sender(ThreadProxy th, Address sp, Address fp, Address pc) { - if (finalFrame) { - return null; + if (dbg.isSignalTrampoline(pc())) { + // RSP points signal context + // https://github.com/torvalds/linux/blob/v6.17/arch/x86/kernel/signal.c#L94 + return getFrameFromReg(dbg, r -> LinuxAMD64ThreadContext.getRegFromSignalTrampoline(this.rsp, r.intValue())); } ThreadContext context = th.getContext(); @@ -179,8 +190,7 @@ public final class LinuxAMD64CFrame extends BasicCFrame { if (nextRSP == null) { return null; } - - Address nextPC = pc != null ? pc : getNextPC(dwarf != null); + Address nextPC = pc != null ? pc : getNextPC(); if (nextPC == null) { return null; } @@ -203,11 +213,23 @@ public final class LinuxAMD64CFrame extends BasicCFrame { } } + Address nextRBP = getNextRBP(fp); + try { - Address nextCFA = getNextCFA(nextDwarf, context, fp, nextPC); - return new LinuxAMD64CFrame(dbg, nextRSP, nextCFA, nextPC, nextDwarf, false, fallback); - } catch (DebuggerException _) { - return null; + Address nextCFA = getNextCFA(nextDwarf, fp, nextPC); + return isValidFrame(nextCFA, nextRBP) + ? new LinuxAMD64CFrame(dbg, nextRSP, nextRBP, nextCFA, nextPC, nextDwarf, fallback) + : null; + } catch (DebuggerException e) { + if (dbg.isSignalTrampoline(nextPC)) { + // We can through the caller frame if it is signal trampoline. + // getNextCFA() might fail because DwarfParser cannot find out CFA register. + return new LinuxAMD64CFrame(dbg, nextRSP, nextRBP, null, nextPC, nextDwarf, fallback); + } + + // Rethrow the original exception if getNextCFA() failed + // and the caller is not signal trampoline. + throw e; } } @@ -231,16 +253,16 @@ public final class LinuxAMD64CFrame extends BasicCFrame { @Override public Frame toFrame() { - return new AMD64Frame(rsp, cfa, rip); + return new AMD64Frame(rsp, localVariableBase(), rip); } // package/class internals only private static final int ADDRESS_SIZE = 8; private Address rsp; + private Address rbp; private Address rip; private Address cfa; private LinuxDebugger dbg; private DwarfParser dwarf; - private boolean finalFrame; private boolean use1ByteBeforeToLookup; } diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/amd64/LinuxAMD64ThreadContext.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/amd64/LinuxAMD64ThreadContext.java index 3884bab796b..8b2a7301cf2 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/amd64/LinuxAMD64ThreadContext.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/amd64/LinuxAMD64ThreadContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved. * 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 @@ package sun.jvm.hotspot.debugger.linux.amd64; import sun.jvm.hotspot.debugger.*; import sun.jvm.hotspot.debugger.amd64.*; import sun.jvm.hotspot.debugger.linux.*; +import sun.jvm.hotspot.runtime.*; public class LinuxAMD64ThreadContext extends AMD64ThreadContext { private LinuxDebugger debugger; @@ -43,4 +44,23 @@ public class LinuxAMD64ThreadContext extends AMD64ThreadContext { public Address getRegisterAsAddress(int index) { return debugger.newAddress(getRegister(index)); } + + public static Address getRegFromSignalTrampoline(Address sp, int index) { + // ucontext_t is located at top of stack. + // See definition of rt_sigframe in arch/x86/include/asm/sigframe.h + // in Linux Kernel. + Address addrUCMContext = sp.addOffsetTo(40); // offsetof(ucontext_t, uc_mcontext) = 40 + Address addrGRegs = addrUCMContext; // gregs is located at top of ucontext_t + + // They are from sys/ucontext.h + final int REG_RBP = 10; + final int REG_RSP = 15; + final int REG_RIP = 16; + return switch(index) { + case AMD64ThreadContext.RBP -> addrGRegs.getAddressAt(REG_RBP * VM.getVM().getAddressSize()); + case AMD64ThreadContext.RSP -> addrGRegs.getAddressAt(REG_RSP * VM.getVM().getAddressSize()); + case AMD64ThreadContext.RIP -> addrGRegs.getAddressAt(REG_RIP * VM.getVM().getAddressSize()); + default -> throw new IllegalArgumentException("Unsupported register index: " + index); + }; + } } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/AbstractMask.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/AbstractMask.java index 30297b24db0..5b762edfd3b 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/AbstractMask.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/AbstractMask.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -73,7 +73,7 @@ abstract class AbstractMask extends VectorMask { int laneCount = vsp.laneCount(); i = VectorIntrinsics.checkFromIndexSize(i, laneCount, bits.length); VectorSupport.store( - vsp.maskType(), vsp.elementType(), laneCount, + vsp.maskType(), vsp.laneTypeOrdinal(), laneCount, bits, (long) i + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET, false, this, bits, i, (c, idx, s) -> System.arraycopy(s.getBits(), 0, c, (int) idx, s.length())); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/AbstractShuffle.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/AbstractShuffle.java index 19ee4bb0074..075400a0d4a 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/AbstractShuffle.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/AbstractShuffle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,7 +53,7 @@ abstract class AbstractShuffle extends VectorShuffle { @ForceInline final AbstractVector toBitsVectorTemplate() { AbstractSpecies dsp = vspecies().asIntegral(); - Class etype = dsp.elementType(); + int etype = dsp.laneTypeOrdinal(); Class rvtype = dsp.dummyVector().getClass(); return VectorSupport.convert(VectorSupport.VECTOR_OP_REINTERPRET, getClass(), etype, length(), diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/AbstractSpecies.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/AbstractSpecies.java index bdc72c64ce5..0f9edbe450c 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/AbstractSpecies.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/AbstractSpecies.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -144,6 +144,12 @@ abstract class AbstractSpecies extends jdk.internal.vm.vector.VectorSupport.V return (Class) laneType.elementType; } + @ForceInline + @SuppressWarnings("unchecked") + //NOT FINAL: SPECIALIZED + int laneTypeOrdinal() { + return laneType.ordinal(); + } // FIXME: appeal to general method (see https://bugs.openjdk.org/browse/JDK-6176992) // replace usages of this method and remove @ForceInline diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/AbstractVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/AbstractVector.java index 350931cd443..80260c2bd30 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/AbstractVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/AbstractVector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -84,6 +84,9 @@ abstract class AbstractVector extends Vector { /*package-private*/ abstract AbstractSpecies vspecies(); + /*package-private*/ + abstract int laneTypeOrdinal(); + @Override @ForceInline public final VectorSpecies species() { @@ -182,7 +185,44 @@ abstract class AbstractVector extends Vector { final AbstractVector asVectorRawTemplate(LaneType laneType) { // NOTE: This assumes that convert0('X') // respects REGISTER_ENDIAN order. - return convert0('X', vspecies().withLanes(laneType)); + return convert0('X', vspecies().withLanes(laneType)).swapIfNeeded(vspecies()); + } + + @ForceInline + protected static VectorShuffle normalizeSubLanesForSpecies(AbstractSpecies targetSpecies, int subLanesPerSrc) { + final int lanes = targetSpecies.laneCount(); + + if ((lanes % subLanesPerSrc) != 0) { + throw new IllegalArgumentException("laneCount " + lanes + " not divisible by subLanesPerSrc " + subLanesPerSrc); + } + + // Each group corresponds to one source lane. + // For each group, reverse the lanes inside that group. + final int groups = lanes / subLanesPerSrc; + int[] map = new int[lanes]; + for (int g = 0; g < groups; ++g) { + int base = g * subLanesPerSrc; + for (int j = 0; j < subLanesPerSrc; ++j) { + map[base + j] = base + (subLanesPerSrc - 1 - j); + } + } + return VectorShuffle.fromArray(targetSpecies, map, 0); + } + + @ForceInline + protected final int subLanesToSwap(AbstractSpecies srcSpecies) { + if (java.nio.ByteOrder.nativeOrder() != ByteOrder.BIG_ENDIAN) { + return -1; + } + int sBytes = srcSpecies.elementSize(); + int tBytes = vspecies().elementSize(); + + // No lane reordering needed for same size or widening reinterprets + if (sBytes == tBytes || (sBytes % tBytes) != 0) { + return -1; + } + int subLanesPerSrc = sBytes / tBytes; + return subLanesPerSrc; } /*package-private*/ @@ -199,9 +239,9 @@ abstract class AbstractVector extends Vector { /*package-private*/ @ForceInline final VectorShuffle bitsToShuffleTemplate(AbstractSpecies dsp) { - Class etype = vspecies().elementType(); + int etype = vspecies().laneTypeOrdinal(); Class dvtype = dsp.shuffleType(); - Class dtype = dsp.asIntegral().elementType(); + int dtype = dsp.asIntegral().laneTypeOrdinal(); int dlength = dsp.dummyVector().length(); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, getClass(), etype, length(), @@ -242,6 +282,9 @@ abstract class AbstractVector extends Vector { /*package-private*/ abstract AbstractVector maybeSwap(ByteOrder bo); + /*package-private*/ + abstract AbstractVector swapIfNeeded(AbstractSpecies srcSpecies); + /*package-private*/ @ForceInline VectorShuffle swapBytesShuffle() { @@ -722,10 +765,10 @@ abstract class AbstractVector extends Vector { AbstractVector convert0(char kind, AbstractSpecies rsp) { // Derive some JIT-time constants: Class vtype; - Class etype; // fill in after switch (constant) + int etype; // fill in after switch (constant) int vlength; // fill in after switch (mark type profile?) Class rvtype; // fill in after switch (mark type profile) - Class rtype; + int rtype; int rlength; switch (kind) { case 'Z': // lane-wise size change, maybe with sign clip @@ -733,9 +776,9 @@ abstract class AbstractVector extends Vector { AbstractSpecies vsp = this.vspecies(); AbstractSpecies vspi = vsp.asIntegral(); AbstractVector biti = vspi == vsp ? this : this.convert0('X', vspi); - rtype = rspi.elementType(); + rtype = rspi.laneTypeOrdinal(); rlength = rspi.laneCount(); - etype = vspi.elementType(); + etype = vspi.laneTypeOrdinal(); vlength = vspi.laneCount(); rvtype = rspi.dummyVector().getClass(); vtype = vspi.dummyVector().getClass(); @@ -747,9 +790,9 @@ abstract class AbstractVector extends Vector { AbstractVector::defaultUCast); return (rspi == rsp ? bitv.check0(rsp) : bitv.convert0('X', rsp)); case 'C': // lane-wise cast (but not identity) - rtype = rsp.elementType(); + rtype = rsp.laneTypeOrdinal(); rlength = rsp.laneCount(); - etype = this.elementType(); // (profile) + etype = this.vspecies().laneTypeOrdinal(); // (profile) vlength = this.length(); // (profile) rvtype = rsp.dummyVector().getClass(); // (profile) vtype = this.getClass(); @@ -759,9 +802,9 @@ abstract class AbstractVector extends Vector { this, rsp, AbstractVector::defaultCast); case 'X': // reinterpret cast, not lane-wise if lane sizes differ - rtype = rsp.elementType(); + rtype = rsp.laneTypeOrdinal(); rlength = rsp.laneCount(); - etype = this.elementType(); // (profile) + etype = this.vspecies().laneTypeOrdinal(); // (profile) vlength = this.length(); // (profile) rvtype = rsp.dummyVector().getClass(); // (profile) vtype = this.getClass(); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte128Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte128Vector.java index 3569ed00f1f..0b710938ede 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte128Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte128Vector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class Byte128Vector extends ByteVector { return (byte[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -541,7 +548,7 @@ final class Byte128Vector extends ByteVector { @ForceInline public byte laneHelper(int i) { return (byte) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { byte[] vecarr = vec.vec(); @@ -576,7 +583,7 @@ final class Byte128Vector extends ByteVector { @ForceInline public Byte128Vector withLaneHelper(int i, byte e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)e, (v, ix, bits) -> { byte[] res = v.vec().clone(); @@ -680,8 +687,8 @@ final class Byte128Vector extends ByteVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -691,7 +698,7 @@ final class Byte128Vector extends ByteVector { /*package-private*/ Byte128Mask indexPartiallyInUpperRange(long offset, long limit) { return (Byte128Mask) VectorSupport.indexPartiallyInUpperRange( - Byte128Mask.class, byte.class, VLENGTH, offset, limit, + Byte128Mask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (Byte128Mask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -707,7 +714,7 @@ final class Byte128Vector extends ByteVector { @ForceInline public Byte128Mask compress() { return (Byte128Mask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - Byte128Vector.class, Byte128Mask.class, ETYPE, VLENGTH, null, this, + Byte128Vector.class, Byte128Mask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -719,7 +726,7 @@ final class Byte128Vector extends ByteVector { public Byte128Mask and(VectorMask mask) { Objects.requireNonNull(mask); Byte128Mask m = (Byte128Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, Byte128Mask.class, null, byte.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, Byte128Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -729,7 +736,7 @@ final class Byte128Vector extends ByteVector { public Byte128Mask or(VectorMask mask) { Objects.requireNonNull(mask); Byte128Mask m = (Byte128Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, Byte128Mask.class, null, byte.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, Byte128Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -739,7 +746,7 @@ final class Byte128Vector extends ByteVector { public Byte128Mask xor(VectorMask mask) { Objects.requireNonNull(mask); Byte128Mask m = (Byte128Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, Byte128Mask.class, null, byte.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, Byte128Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -749,21 +756,21 @@ final class Byte128Vector extends ByteVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Byte128Mask.class, byte.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Byte128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Byte128Mask.class, byte.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Byte128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Byte128Mask.class, byte.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Byte128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -773,7 +780,7 @@ final class Byte128Vector extends ByteVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Byte128Mask.class, byte.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Byte128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -783,7 +790,7 @@ final class Byte128Vector extends ByteVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(Byte128Mask.class, byte.class, VLENGTH, + return VectorSupport.extract(Byte128Mask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -792,7 +799,7 @@ final class Byte128Vector extends ByteVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, Byte128Mask.class, byte.class, VLENGTH, + return VectorSupport.test(BT_ne, Byte128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((Byte128Mask)m).getBits())); } @@ -800,7 +807,7 @@ final class Byte128Vector extends ByteVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, Byte128Mask.class, byte.class, VLENGTH, + return VectorSupport.test(BT_overflow, Byte128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((Byte128Mask)m).getBits())); } @@ -808,7 +815,7 @@ final class Byte128Vector extends ByteVector { @ForceInline /*package-private*/ static Byte128Mask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(Byte128Mask.class, byte.class, VLENGTH, + return VectorSupport.fromBitsCoerced(Byte128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte256Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte256Vector.java index 70a3306731e..6b0e57f8b8f 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte256Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte256Vector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class Byte256Vector extends ByteVector { return (byte[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -557,7 +564,7 @@ final class Byte256Vector extends ByteVector { @ForceInline public byte laneHelper(int i) { return (byte) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { byte[] vecarr = vec.vec(); @@ -608,7 +615,7 @@ final class Byte256Vector extends ByteVector { @ForceInline public Byte256Vector withLaneHelper(int i, byte e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)e, (v, ix, bits) -> { byte[] res = v.vec().clone(); @@ -712,8 +719,8 @@ final class Byte256Vector extends ByteVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -723,7 +730,7 @@ final class Byte256Vector extends ByteVector { /*package-private*/ Byte256Mask indexPartiallyInUpperRange(long offset, long limit) { return (Byte256Mask) VectorSupport.indexPartiallyInUpperRange( - Byte256Mask.class, byte.class, VLENGTH, offset, limit, + Byte256Mask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (Byte256Mask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -739,7 +746,7 @@ final class Byte256Vector extends ByteVector { @ForceInline public Byte256Mask compress() { return (Byte256Mask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - Byte256Vector.class, Byte256Mask.class, ETYPE, VLENGTH, null, this, + Byte256Vector.class, Byte256Mask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -751,7 +758,7 @@ final class Byte256Vector extends ByteVector { public Byte256Mask and(VectorMask mask) { Objects.requireNonNull(mask); Byte256Mask m = (Byte256Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, Byte256Mask.class, null, byte.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, Byte256Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -761,7 +768,7 @@ final class Byte256Vector extends ByteVector { public Byte256Mask or(VectorMask mask) { Objects.requireNonNull(mask); Byte256Mask m = (Byte256Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, Byte256Mask.class, null, byte.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, Byte256Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -771,7 +778,7 @@ final class Byte256Vector extends ByteVector { public Byte256Mask xor(VectorMask mask) { Objects.requireNonNull(mask); Byte256Mask m = (Byte256Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, Byte256Mask.class, null, byte.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, Byte256Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -781,21 +788,21 @@ final class Byte256Vector extends ByteVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Byte256Mask.class, byte.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Byte256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Byte256Mask.class, byte.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Byte256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Byte256Mask.class, byte.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Byte256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -805,7 +812,7 @@ final class Byte256Vector extends ByteVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Byte256Mask.class, byte.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Byte256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -815,7 +822,7 @@ final class Byte256Vector extends ByteVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(Byte256Mask.class, byte.class, VLENGTH, + return VectorSupport.extract(Byte256Mask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -824,7 +831,7 @@ final class Byte256Vector extends ByteVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, Byte256Mask.class, byte.class, VLENGTH, + return VectorSupport.test(BT_ne, Byte256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((Byte256Mask)m).getBits())); } @@ -832,7 +839,7 @@ final class Byte256Vector extends ByteVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, Byte256Mask.class, byte.class, VLENGTH, + return VectorSupport.test(BT_overflow, Byte256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((Byte256Mask)m).getBits())); } @@ -840,7 +847,7 @@ final class Byte256Vector extends ByteVector { @ForceInline /*package-private*/ static Byte256Mask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(Byte256Mask.class, byte.class, VLENGTH, + return VectorSupport.fromBitsCoerced(Byte256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte512Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte512Vector.java index a093fe18289..b1df6949e3a 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte512Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte512Vector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class Byte512Vector extends ByteVector { return (byte[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -589,7 +596,7 @@ final class Byte512Vector extends ByteVector { @ForceInline public byte laneHelper(int i) { return (byte) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { byte[] vecarr = vec.vec(); @@ -672,7 +679,7 @@ final class Byte512Vector extends ByteVector { @ForceInline public Byte512Vector withLaneHelper(int i, byte e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)e, (v, ix, bits) -> { byte[] res = v.vec().clone(); @@ -776,8 +783,8 @@ final class Byte512Vector extends ByteVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -787,7 +794,7 @@ final class Byte512Vector extends ByteVector { /*package-private*/ Byte512Mask indexPartiallyInUpperRange(long offset, long limit) { return (Byte512Mask) VectorSupport.indexPartiallyInUpperRange( - Byte512Mask.class, byte.class, VLENGTH, offset, limit, + Byte512Mask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (Byte512Mask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -803,7 +810,7 @@ final class Byte512Vector extends ByteVector { @ForceInline public Byte512Mask compress() { return (Byte512Mask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - Byte512Vector.class, Byte512Mask.class, ETYPE, VLENGTH, null, this, + Byte512Vector.class, Byte512Mask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -815,7 +822,7 @@ final class Byte512Vector extends ByteVector { public Byte512Mask and(VectorMask mask) { Objects.requireNonNull(mask); Byte512Mask m = (Byte512Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, Byte512Mask.class, null, byte.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, Byte512Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -825,7 +832,7 @@ final class Byte512Vector extends ByteVector { public Byte512Mask or(VectorMask mask) { Objects.requireNonNull(mask); Byte512Mask m = (Byte512Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, Byte512Mask.class, null, byte.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, Byte512Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -835,7 +842,7 @@ final class Byte512Vector extends ByteVector { public Byte512Mask xor(VectorMask mask) { Objects.requireNonNull(mask); Byte512Mask m = (Byte512Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, Byte512Mask.class, null, byte.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, Byte512Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -845,21 +852,21 @@ final class Byte512Vector extends ByteVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Byte512Mask.class, byte.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Byte512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Byte512Mask.class, byte.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Byte512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Byte512Mask.class, byte.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Byte512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -869,7 +876,7 @@ final class Byte512Vector extends ByteVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Byte512Mask.class, byte.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Byte512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -879,7 +886,7 @@ final class Byte512Vector extends ByteVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(Byte512Mask.class, byte.class, VLENGTH, + return VectorSupport.extract(Byte512Mask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -888,7 +895,7 @@ final class Byte512Vector extends ByteVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, Byte512Mask.class, byte.class, VLENGTH, + return VectorSupport.test(BT_ne, Byte512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((Byte512Mask)m).getBits())); } @@ -896,7 +903,7 @@ final class Byte512Vector extends ByteVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, Byte512Mask.class, byte.class, VLENGTH, + return VectorSupport.test(BT_overflow, Byte512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((Byte512Mask)m).getBits())); } @@ -904,7 +911,7 @@ final class Byte512Vector extends ByteVector { @ForceInline /*package-private*/ static Byte512Mask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(Byte512Mask.class, byte.class, VLENGTH, + return VectorSupport.fromBitsCoerced(Byte512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte64Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte64Vector.java index cd75ee9f610..dfd16e1812a 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte64Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte64Vector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class Byte64Vector extends ByteVector { return (byte[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -533,7 +540,7 @@ final class Byte64Vector extends ByteVector { @ForceInline public byte laneHelper(int i) { return (byte) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { byte[] vecarr = vec.vec(); @@ -560,7 +567,7 @@ final class Byte64Vector extends ByteVector { @ForceInline public Byte64Vector withLaneHelper(int i, byte e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)e, (v, ix, bits) -> { byte[] res = v.vec().clone(); @@ -664,8 +671,8 @@ final class Byte64Vector extends ByteVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -675,7 +682,7 @@ final class Byte64Vector extends ByteVector { /*package-private*/ Byte64Mask indexPartiallyInUpperRange(long offset, long limit) { return (Byte64Mask) VectorSupport.indexPartiallyInUpperRange( - Byte64Mask.class, byte.class, VLENGTH, offset, limit, + Byte64Mask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (Byte64Mask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -691,7 +698,7 @@ final class Byte64Vector extends ByteVector { @ForceInline public Byte64Mask compress() { return (Byte64Mask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - Byte64Vector.class, Byte64Mask.class, ETYPE, VLENGTH, null, this, + Byte64Vector.class, Byte64Mask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -703,7 +710,7 @@ final class Byte64Vector extends ByteVector { public Byte64Mask and(VectorMask mask) { Objects.requireNonNull(mask); Byte64Mask m = (Byte64Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, Byte64Mask.class, null, byte.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, Byte64Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -713,7 +720,7 @@ final class Byte64Vector extends ByteVector { public Byte64Mask or(VectorMask mask) { Objects.requireNonNull(mask); Byte64Mask m = (Byte64Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, Byte64Mask.class, null, byte.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, Byte64Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -723,7 +730,7 @@ final class Byte64Vector extends ByteVector { public Byte64Mask xor(VectorMask mask) { Objects.requireNonNull(mask); Byte64Mask m = (Byte64Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, Byte64Mask.class, null, byte.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, Byte64Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -733,21 +740,21 @@ final class Byte64Vector extends ByteVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Byte64Mask.class, byte.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Byte64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Byte64Mask.class, byte.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Byte64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Byte64Mask.class, byte.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Byte64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -757,7 +764,7 @@ final class Byte64Vector extends ByteVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Byte64Mask.class, byte.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Byte64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -767,7 +774,7 @@ final class Byte64Vector extends ByteVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(Byte64Mask.class, byte.class, VLENGTH, + return VectorSupport.extract(Byte64Mask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -776,7 +783,7 @@ final class Byte64Vector extends ByteVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, Byte64Mask.class, byte.class, VLENGTH, + return VectorSupport.test(BT_ne, Byte64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((Byte64Mask)m).getBits())); } @@ -784,7 +791,7 @@ final class Byte64Vector extends ByteVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, Byte64Mask.class, byte.class, VLENGTH, + return VectorSupport.test(BT_overflow, Byte64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((Byte64Mask)m).getBits())); } @@ -792,7 +799,7 @@ final class Byte64Vector extends ByteVector { @ForceInline /*package-private*/ static Byte64Mask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(Byte64Mask.class, byte.class, VLENGTH, + return VectorSupport.fromBitsCoerced(Byte64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteMaxVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteMaxVector.java index 3ac62409a95..8c3cc68cece 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteMaxVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteMaxVector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class ByteMaxVector extends ByteVector { return (byte[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -526,7 +533,7 @@ final class ByteMaxVector extends ByteVector { @ForceInline public byte laneHelper(int i) { return (byte) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { byte[] vecarr = vec.vec(); @@ -546,7 +553,7 @@ final class ByteMaxVector extends ByteVector { @ForceInline public ByteMaxVector withLaneHelper(int i, byte e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)e, (v, ix, bits) -> { byte[] res = v.vec().clone(); @@ -650,8 +657,8 @@ final class ByteMaxVector extends ByteVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -661,7 +668,7 @@ final class ByteMaxVector extends ByteVector { /*package-private*/ ByteMaxMask indexPartiallyInUpperRange(long offset, long limit) { return (ByteMaxMask) VectorSupport.indexPartiallyInUpperRange( - ByteMaxMask.class, byte.class, VLENGTH, offset, limit, + ByteMaxMask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (ByteMaxMask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -677,7 +684,7 @@ final class ByteMaxVector extends ByteVector { @ForceInline public ByteMaxMask compress() { return (ByteMaxMask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - ByteMaxVector.class, ByteMaxMask.class, ETYPE, VLENGTH, null, this, + ByteMaxVector.class, ByteMaxMask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -689,7 +696,7 @@ final class ByteMaxVector extends ByteVector { public ByteMaxMask and(VectorMask mask) { Objects.requireNonNull(mask); ByteMaxMask m = (ByteMaxMask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, ByteMaxMask.class, null, byte.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, ByteMaxMask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -699,7 +706,7 @@ final class ByteMaxVector extends ByteVector { public ByteMaxMask or(VectorMask mask) { Objects.requireNonNull(mask); ByteMaxMask m = (ByteMaxMask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, ByteMaxMask.class, null, byte.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, ByteMaxMask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -709,7 +716,7 @@ final class ByteMaxVector extends ByteVector { public ByteMaxMask xor(VectorMask mask) { Objects.requireNonNull(mask); ByteMaxMask m = (ByteMaxMask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, ByteMaxMask.class, null, byte.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, ByteMaxMask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -719,21 +726,21 @@ final class ByteMaxVector extends ByteVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, ByteMaxMask.class, byte.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, ByteMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, ByteMaxMask.class, byte.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, ByteMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, ByteMaxMask.class, byte.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, ByteMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -743,7 +750,7 @@ final class ByteMaxVector extends ByteVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, ByteMaxMask.class, byte.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, ByteMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -753,7 +760,7 @@ final class ByteMaxVector extends ByteVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(ByteMaxMask.class, byte.class, VLENGTH, + return VectorSupport.extract(ByteMaxMask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -762,7 +769,7 @@ final class ByteMaxVector extends ByteVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, ByteMaxMask.class, byte.class, VLENGTH, + return VectorSupport.test(BT_ne, ByteMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((ByteMaxMask)m).getBits())); } @@ -770,7 +777,7 @@ final class ByteMaxVector extends ByteVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, ByteMaxMask.class, byte.class, VLENGTH, + return VectorSupport.test(BT_overflow, ByteMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((ByteMaxMask)m).getBits())); } @@ -778,7 +785,7 @@ final class ByteMaxVector extends ByteVector { @ForceInline /*package-private*/ static ByteMaxMask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(ByteMaxMask.class, byte.class, VLENGTH, + return VectorSupport.fromBitsCoerced(ByteMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteVector.java index 02e15d5f8dd..64d8e3a8252 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteVector.java @@ -59,6 +59,10 @@ public abstract class ByteVector extends AbstractVector { static final ValueLayout.OfByte ELEMENT_LAYOUT = ValueLayout.JAVA_BYTE.withByteAlignment(1); + static final int LANE_TYPE_ORDINAL = LT_BYTE; + + static final int LANEBITS_TYPE_ORDINAL = LT_BYTE; + @ForceInline static int opCode(Operator op) { return VectorOperators.opCode(op, VO_OPCODE_VALID, FORBID_OPCODE_KIND); @@ -573,7 +577,7 @@ public abstract class ByteVector extends AbstractVector { @ForceInline public static ByteVector zero(VectorSpecies species) { ByteSpecies vsp = (ByteSpecies) species; - return VectorSupport.fromBitsCoerced(vsp.vectorType(), byte.class, species.length(), + return VectorSupport.fromBitsCoerced(vsp.vectorType(), LANE_TYPE_ORDINAL, species.length(), 0, MODE_BROADCAST, vsp, ((bits_, s_) -> s_.rvOp(i -> bits_))); } @@ -695,7 +699,7 @@ public abstract class ByteVector extends AbstractVector { } int opc = opCode(op); return VectorSupport.unaryOp( - opc, getClass(), null, byte.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, null, UN_IMPL.find(op, opc, ByteVector::unaryOperations)); } @@ -723,7 +727,7 @@ public abstract class ByteVector extends AbstractVector { } int opc = opCode(op); return VectorSupport.unaryOp( - opc, getClass(), maskClass, byte.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, m, UN_IMPL.find(op, opc, ByteVector::unaryOperations)); } @@ -796,7 +800,7 @@ public abstract class ByteVector extends AbstractVector { int opc = opCode(op); return VectorSupport.binaryOp( - opc, getClass(), null, byte.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, that, null, BIN_IMPL.find(op, opc, ByteVector::binaryOperations)); } @@ -847,7 +851,7 @@ public abstract class ByteVector extends AbstractVector { int opc = opCode(op); return VectorSupport.binaryOp( - opc, getClass(), maskClass, byte.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, that, m, BIN_IMPL.find(op, opc, ByteVector::binaryOperations)); } @@ -1034,7 +1038,7 @@ public abstract class ByteVector extends AbstractVector { e &= SHIFT_MASK; int opc = opCode(op); return VectorSupport.broadcastInt( - opc, getClass(), null, byte.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, e, null, BIN_INT_IMPL.find(op, opc, ByteVector::broadcastIntOperations)); } @@ -1055,7 +1059,7 @@ public abstract class ByteVector extends AbstractVector { e &= SHIFT_MASK; int opc = opCode(op); return VectorSupport.broadcastInt( - opc, getClass(), maskClass, byte.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, e, m, BIN_INT_IMPL.find(op, opc, ByteVector::broadcastIntOperations)); } @@ -1132,7 +1136,7 @@ public abstract class ByteVector extends AbstractVector { } int opc = opCode(op); return VectorSupport.ternaryOp( - opc, getClass(), null, byte.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, that, tother, null, TERN_IMPL.find(op, opc, ByteVector::ternaryOperations)); } @@ -1172,7 +1176,7 @@ public abstract class ByteVector extends AbstractVector { } int opc = opCode(op); return VectorSupport.ternaryOp( - opc, getClass(), maskClass, byte.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, that, tother, m, TERN_IMPL.find(op, opc, ByteVector::ternaryOperations)); } @@ -2070,7 +2074,7 @@ public abstract class ByteVector extends AbstractVector { that.check(this); int opc = opCode(op); return VectorSupport.compare( - opc, getClass(), maskType, byte.class, length(), + opc, getClass(), maskType, laneTypeOrdinal(), length(), this, that, null, (cond, v0, v1, m1) -> { AbstractMask m @@ -2092,7 +2096,7 @@ public abstract class ByteVector extends AbstractVector { m.check(maskType, this); int opc = opCode(op); return VectorSupport.compare( - opc, getClass(), maskType, byte.class, length(), + opc, getClass(), maskType, laneTypeOrdinal(), length(), this, that, m, (cond, v0, v1, m1) -> { AbstractMask cmpM @@ -2223,7 +2227,7 @@ public abstract class ByteVector extends AbstractVector { blendTemplate(Class maskType, ByteVector v, M m) { v.check(this); return VectorSupport.blend( - getClass(), maskType, byte.class, length(), + getClass(), maskType, laneTypeOrdinal(), length(), this, v, m, (v0, v1, m_) -> v0.bOp(v1, m_, (i, a, b) -> b)); } @@ -2240,7 +2244,7 @@ public abstract class ByteVector extends AbstractVector { // make sure VLENGTH*scale doesn't overflow: vsp.checkScale(scale); return VectorSupport.indexVector( - getClass(), byte.class, length(), + getClass(), laneTypeOrdinal(), length(), this, scale, vsp, (v, scale_, s) -> { @@ -2432,7 +2436,7 @@ public abstract class ByteVector extends AbstractVector { ByteVector rearrangeTemplate(Class shuffletype, S shuffle) { Objects.requireNonNull(shuffle); return VectorSupport.rearrangeOp( - getClass(), shuffletype, null, byte.class, length(), + getClass(), shuffletype, null, laneTypeOrdinal(), length(), this, shuffle, null, (v1, s_, m_) -> v1.uOp((i, a) -> { int ei = Integer.remainderUnsigned(s_.laneSource(i), v1.length()); @@ -2459,7 +2463,7 @@ public abstract class ByteVector extends AbstractVector { Objects.requireNonNull(shuffle); m.check(masktype, this); return VectorSupport.rearrangeOp( - getClass(), shuffletype, masktype, byte.class, length(), + getClass(), shuffletype, masktype, laneTypeOrdinal(), length(), this, shuffle, m, (v1, s_, m_) -> v1.uOp((i, a) -> { int ei = Integer.remainderUnsigned(s_.laneSource(i), v1.length()); @@ -2485,7 +2489,7 @@ public abstract class ByteVector extends AbstractVector { VectorMask valid = shuffle.laneIsValid(); ByteVector r0 = VectorSupport.rearrangeOp( - getClass(), shuffletype, null, byte.class, length(), + getClass(), shuffletype, null, laneTypeOrdinal(), length(), this, shuffle, null, (v0, s_, m_) -> v0.uOp((i, a) -> { int ei = Integer.remainderUnsigned(s_.laneSource(i), v0.length()); @@ -2493,7 +2497,7 @@ public abstract class ByteVector extends AbstractVector { })); ByteVector r1 = VectorSupport.rearrangeOp( - getClass(), shuffletype, null, byte.class, length(), + getClass(), shuffletype, null, laneTypeOrdinal(), length(), v, shuffle, null, (v1, s_, m_) -> v1.uOp((i, a) -> { int ei = Integer.remainderUnsigned(s_.laneSource(i), v1.length()); @@ -2543,7 +2547,7 @@ public abstract class ByteVector extends AbstractVector { ByteVector compressTemplate(Class masktype, M m) { m.check(masktype, this); return (ByteVector) VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_COMPRESS, getClass(), masktype, - byte.class, length(), this, m, + laneTypeOrdinal(), length(), this, m, (v1, m1) -> compressHelper(v1, m1)); } @@ -2562,7 +2566,7 @@ public abstract class ByteVector extends AbstractVector { ByteVector expandTemplate(Class masktype, M m) { m.check(masktype, this); return (ByteVector) VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_EXPAND, getClass(), masktype, - byte.class, length(), this, m, + laneTypeOrdinal(), length(), this, m, (v1, m1) -> expandHelper(v1, m1)); } @@ -2577,7 +2581,7 @@ public abstract class ByteVector extends AbstractVector { /*package-private*/ @ForceInline final ByteVector selectFromTemplate(ByteVector v) { - return (ByteVector)VectorSupport.selectFromOp(getClass(), null, byte.class, + return (ByteVector)VectorSupport.selectFromOp(getClass(), null, laneTypeOrdinal(), length(), this, v, null, (v1, v2, _m) -> v2.rearrange(v1.toShuffle())); @@ -2597,7 +2601,7 @@ public abstract class ByteVector extends AbstractVector { ByteVector selectFromTemplate(ByteVector v, Class masktype, M m) { m.check(masktype, this); - return (ByteVector)VectorSupport.selectFromOp(getClass(), masktype, byte.class, + return (ByteVector)VectorSupport.selectFromOp(getClass(), masktype, laneTypeOrdinal(), length(), this, v, m, (v1, v2, _m) -> v2.rearrange(v1.toShuffle(), _m)); @@ -2615,7 +2619,7 @@ public abstract class ByteVector extends AbstractVector { /*package-private*/ @ForceInline final ByteVector selectFromTemplate(ByteVector v1, ByteVector v2) { - return VectorSupport.selectFromTwoVectorOp(getClass(), byte.class, length(), this, v1, v2, + return VectorSupport.selectFromTwoVectorOp(getClass(), laneTypeOrdinal(), length(), this, v1, v2, (vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)); } @@ -2835,7 +2839,7 @@ public abstract class ByteVector extends AbstractVector { } int opc = opCode(op); return fromBits(VectorSupport.reductionCoerced( - opc, getClass(), maskClass, byte.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, m, REDUCE_IMPL.find(op, opc, ByteVector::reductionOperations))); } @@ -2853,7 +2857,7 @@ public abstract class ByteVector extends AbstractVector { } int opc = opCode(op); return fromBits(VectorSupport.reductionCoerced( - opc, getClass(), null, byte.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, null, REDUCE_IMPL.find(op, opc, ByteVector::reductionOperations))); } @@ -3145,7 +3149,7 @@ public abstract class ByteVector extends AbstractVector { } return VectorSupport.loadWithMap( - vectorType, null, byte.class, vsp.laneCount(), + vectorType, null, LANE_TYPE_ORDINAL, vsp.laneCount(), lsp.vectorType(), lsp.length(), a, ARRAY_BASE, vix0, vix1, vix2, vix3, null, a, offset, indexMap, mapOffset, vsp, @@ -3480,7 +3484,7 @@ public abstract class ByteVector extends AbstractVector { offset = checkFromIndexSize(offset, length(), a.length); ByteSpecies vsp = vspecies(); VectorSupport.store( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, this, a, offset, @@ -3634,7 +3638,7 @@ public abstract class ByteVector extends AbstractVector { ByteSpecies vsp = vspecies(); ByteVector normalized = this.and((byte) 1); VectorSupport.store( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), a, booleanArrayAddress(a, offset), false, normalized, a, offset, @@ -3847,7 +3851,7 @@ public abstract class ByteVector extends AbstractVector { ByteVector fromArray0Template(byte[] a, int offset) { ByteSpecies vsp = vspecies(); return VectorSupport.load( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, a, offset, vsp, (arr, off, s) -> s.ldOp(arr, (int) off, @@ -3864,7 +3868,7 @@ public abstract class ByteVector extends AbstractVector { m.check(species()); ByteSpecies vsp = vspecies(); return VectorSupport.loadMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, m, offsetInRange, a, offset, vsp, (arr, off, s, vm) -> s.ldOp(arr, (int) off, vm, @@ -3920,7 +3924,7 @@ public abstract class ByteVector extends AbstractVector { } return VectorSupport.loadWithMap( - vectorType, maskClass, byte.class, vsp.laneCount(), + vectorType, maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), lsp.vectorType(), lsp.length(), a, ARRAY_BASE, vix0, vix1, vix2, vix3, m, a, offset, indexMap, mapOffset, vsp, @@ -3937,7 +3941,7 @@ public abstract class ByteVector extends AbstractVector { ByteVector fromBooleanArray0Template(boolean[] a, int offset) { ByteSpecies vsp = vspecies(); return VectorSupport.load( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), a, booleanArrayAddress(a, offset), false, a, offset, vsp, (arr, off, s) -> s.ldOp(arr, (int) off, @@ -3954,7 +3958,7 @@ public abstract class ByteVector extends AbstractVector { m.check(species()); ByteSpecies vsp = vspecies(); return VectorSupport.loadMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), a, booleanArrayAddress(a, offset), false, m, offsetInRange, a, offset, vsp, (arr, off, s, vm) -> s.ldOp(arr, (int) off, vm, @@ -3968,7 +3972,7 @@ public abstract class ByteVector extends AbstractVector { ByteVector fromMemorySegment0Template(MemorySegment ms, long offset) { ByteSpecies vsp = vspecies(); return ScopedMemoryAccess.loadFromMemorySegment( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), (AbstractMemorySegmentImpl) ms, offset, vsp, (msp, off, s) -> { return s.ldLongOp((MemorySegment) msp, off, ByteVector::memorySegmentGet); @@ -3984,7 +3988,7 @@ public abstract class ByteVector extends AbstractVector { ByteSpecies vsp = vspecies(); m.check(vsp); return ScopedMemoryAccess.loadFromMemorySegmentMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), (AbstractMemorySegmentImpl) ms, offset, m, vsp, offsetInRange, (msp, off, s, vm) -> { return s.ldLongOp((MemorySegment) msp, off, vm, ByteVector::memorySegmentGet); @@ -4002,7 +4006,7 @@ public abstract class ByteVector extends AbstractVector { void intoArray0Template(byte[] a, int offset) { ByteSpecies vsp = vspecies(); VectorSupport.store( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, this, a, offset, (arr, off, v) @@ -4019,7 +4023,7 @@ public abstract class ByteVector extends AbstractVector { m.check(species()); ByteSpecies vsp = vspecies(); VectorSupport.storeMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, this, m, a, offset, (arr, off, v, vm) @@ -4038,7 +4042,7 @@ public abstract class ByteVector extends AbstractVector { ByteSpecies vsp = vspecies(); ByteVector normalized = this.and((byte) 1); VectorSupport.storeMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), a, booleanArrayAddress(a, offset), false, normalized, m, a, offset, (arr, off, v, vm) @@ -4051,7 +4055,7 @@ public abstract class ByteVector extends AbstractVector { void intoMemorySegment0(MemorySegment ms, long offset) { ByteSpecies vsp = vspecies(); ScopedMemoryAccess.storeIntoMemorySegment( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), this, (AbstractMemorySegmentImpl) ms, offset, (msp, off, v) -> { @@ -4068,7 +4072,7 @@ public abstract class ByteVector extends AbstractVector { ByteSpecies vsp = vspecies(); m.check(vsp); ScopedMemoryAccess.storeIntoMemorySegmentMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), this, m, (AbstractMemorySegmentImpl) ms, offset, (msp, off, v, vm) -> { @@ -4101,6 +4105,14 @@ public abstract class ByteVector extends AbstractVector { return this; } + /*package-private*/ + @Override + @ForceInline + final + ByteVector swapIfNeeded(AbstractSpecies srcSpecies) { + return this; + } + static final int ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_BYTE_INDEX_SCALE); static final long ARRAY_BASE = @@ -4281,7 +4293,7 @@ public abstract class ByteVector extends AbstractVector { final ByteVector broadcastBits(long bits) { return (ByteVector) VectorSupport.fromBitsCoerced( - vectorType, byte.class, laneCount, + vectorType, laneTypeOrdinal(), laneCount, bits, MODE_BROADCAST, this, (bits_, s_) -> s_.rvOp(i -> bits_)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double128Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double128Vector.java index eaf77d59a23..f00efcf5163 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double128Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double128Vector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class Double128Vector extends DoubleVector { return (double[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -516,7 +523,7 @@ final class Double128Vector extends DoubleVector { @ForceInline public long laneHelper(int i) { return (long) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { double[] vecarr = vec.vec(); @@ -537,7 +544,7 @@ final class Double128Vector extends DoubleVector { @ForceInline public Double128Vector withLaneHelper(int i, double e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)Double.doubleToRawLongBits(e), (v, ix, bits) -> { double[] res = v.vec().clone(); @@ -641,8 +648,8 @@ final class Double128Vector extends DoubleVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -652,7 +659,7 @@ final class Double128Vector extends DoubleVector { /*package-private*/ Double128Mask indexPartiallyInUpperRange(long offset, long limit) { return (Double128Mask) VectorSupport.indexPartiallyInUpperRange( - Double128Mask.class, double.class, VLENGTH, offset, limit, + Double128Mask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (Double128Mask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -668,7 +675,7 @@ final class Double128Vector extends DoubleVector { @ForceInline public Double128Mask compress() { return (Double128Mask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - Double128Vector.class, Double128Mask.class, ETYPE, VLENGTH, null, this, + Double128Vector.class, Double128Mask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -680,7 +687,7 @@ final class Double128Vector extends DoubleVector { public Double128Mask and(VectorMask mask) { Objects.requireNonNull(mask); Double128Mask m = (Double128Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, Double128Mask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, Double128Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -690,7 +697,7 @@ final class Double128Vector extends DoubleVector { public Double128Mask or(VectorMask mask) { Objects.requireNonNull(mask); Double128Mask m = (Double128Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, Double128Mask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, Double128Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -700,7 +707,7 @@ final class Double128Vector extends DoubleVector { public Double128Mask xor(VectorMask mask) { Objects.requireNonNull(mask); Double128Mask m = (Double128Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, Double128Mask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, Double128Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -710,21 +717,21 @@ final class Double128Vector extends DoubleVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Double128Mask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Double128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Double128Mask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Double128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Double128Mask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Double128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -734,7 +741,7 @@ final class Double128Vector extends DoubleVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Double128Mask.class, long.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Double128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -744,7 +751,7 @@ final class Double128Vector extends DoubleVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(Double128Mask.class, double.class, VLENGTH, + return VectorSupport.extract(Double128Mask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -753,7 +760,7 @@ final class Double128Vector extends DoubleVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, Double128Mask.class, long.class, VLENGTH, + return VectorSupport.test(BT_ne, Double128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((Double128Mask)m).getBits())); } @@ -761,7 +768,7 @@ final class Double128Vector extends DoubleVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, Double128Mask.class, long.class, VLENGTH, + return VectorSupport.test(BT_overflow, Double128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((Double128Mask)m).getBits())); } @@ -769,7 +776,7 @@ final class Double128Vector extends DoubleVector { @ForceInline /*package-private*/ static Double128Mask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(Double128Mask.class, long.class, VLENGTH, + return VectorSupport.fromBitsCoerced(Double128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double256Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double256Vector.java index cf9c8794ce4..0f145bf06e2 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double256Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double256Vector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class Double256Vector extends DoubleVector { return (double[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -518,7 +525,7 @@ final class Double256Vector extends DoubleVector { @ForceInline public long laneHelper(int i) { return (long) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { double[] vecarr = vec.vec(); @@ -541,7 +548,7 @@ final class Double256Vector extends DoubleVector { @ForceInline public Double256Vector withLaneHelper(int i, double e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)Double.doubleToRawLongBits(e), (v, ix, bits) -> { double[] res = v.vec().clone(); @@ -645,8 +652,8 @@ final class Double256Vector extends DoubleVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -656,7 +663,7 @@ final class Double256Vector extends DoubleVector { /*package-private*/ Double256Mask indexPartiallyInUpperRange(long offset, long limit) { return (Double256Mask) VectorSupport.indexPartiallyInUpperRange( - Double256Mask.class, double.class, VLENGTH, offset, limit, + Double256Mask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (Double256Mask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -672,7 +679,7 @@ final class Double256Vector extends DoubleVector { @ForceInline public Double256Mask compress() { return (Double256Mask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - Double256Vector.class, Double256Mask.class, ETYPE, VLENGTH, null, this, + Double256Vector.class, Double256Mask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -684,7 +691,7 @@ final class Double256Vector extends DoubleVector { public Double256Mask and(VectorMask mask) { Objects.requireNonNull(mask); Double256Mask m = (Double256Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, Double256Mask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, Double256Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -694,7 +701,7 @@ final class Double256Vector extends DoubleVector { public Double256Mask or(VectorMask mask) { Objects.requireNonNull(mask); Double256Mask m = (Double256Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, Double256Mask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, Double256Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -704,7 +711,7 @@ final class Double256Vector extends DoubleVector { public Double256Mask xor(VectorMask mask) { Objects.requireNonNull(mask); Double256Mask m = (Double256Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, Double256Mask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, Double256Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -714,21 +721,21 @@ final class Double256Vector extends DoubleVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Double256Mask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Double256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Double256Mask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Double256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Double256Mask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Double256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -738,7 +745,7 @@ final class Double256Vector extends DoubleVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Double256Mask.class, long.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Double256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -748,7 +755,7 @@ final class Double256Vector extends DoubleVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(Double256Mask.class, double.class, VLENGTH, + return VectorSupport.extract(Double256Mask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -757,7 +764,7 @@ final class Double256Vector extends DoubleVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, Double256Mask.class, long.class, VLENGTH, + return VectorSupport.test(BT_ne, Double256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((Double256Mask)m).getBits())); } @@ -765,7 +772,7 @@ final class Double256Vector extends DoubleVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, Double256Mask.class, long.class, VLENGTH, + return VectorSupport.test(BT_overflow, Double256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((Double256Mask)m).getBits())); } @@ -773,7 +780,7 @@ final class Double256Vector extends DoubleVector { @ForceInline /*package-private*/ static Double256Mask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(Double256Mask.class, long.class, VLENGTH, + return VectorSupport.fromBitsCoerced(Double256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double512Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double512Vector.java index a7a86c25841..581a3ac7329 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double512Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double512Vector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class Double512Vector extends DoubleVector { return (double[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -522,7 +529,7 @@ final class Double512Vector extends DoubleVector { @ForceInline public long laneHelper(int i) { return (long) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { double[] vecarr = vec.vec(); @@ -549,7 +556,7 @@ final class Double512Vector extends DoubleVector { @ForceInline public Double512Vector withLaneHelper(int i, double e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)Double.doubleToRawLongBits(e), (v, ix, bits) -> { double[] res = v.vec().clone(); @@ -653,8 +660,8 @@ final class Double512Vector extends DoubleVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -664,7 +671,7 @@ final class Double512Vector extends DoubleVector { /*package-private*/ Double512Mask indexPartiallyInUpperRange(long offset, long limit) { return (Double512Mask) VectorSupport.indexPartiallyInUpperRange( - Double512Mask.class, double.class, VLENGTH, offset, limit, + Double512Mask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (Double512Mask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -680,7 +687,7 @@ final class Double512Vector extends DoubleVector { @ForceInline public Double512Mask compress() { return (Double512Mask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - Double512Vector.class, Double512Mask.class, ETYPE, VLENGTH, null, this, + Double512Vector.class, Double512Mask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -692,7 +699,7 @@ final class Double512Vector extends DoubleVector { public Double512Mask and(VectorMask mask) { Objects.requireNonNull(mask); Double512Mask m = (Double512Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, Double512Mask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, Double512Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -702,7 +709,7 @@ final class Double512Vector extends DoubleVector { public Double512Mask or(VectorMask mask) { Objects.requireNonNull(mask); Double512Mask m = (Double512Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, Double512Mask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, Double512Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -712,7 +719,7 @@ final class Double512Vector extends DoubleVector { public Double512Mask xor(VectorMask mask) { Objects.requireNonNull(mask); Double512Mask m = (Double512Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, Double512Mask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, Double512Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -722,21 +729,21 @@ final class Double512Vector extends DoubleVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Double512Mask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Double512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Double512Mask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Double512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Double512Mask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Double512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -746,7 +753,7 @@ final class Double512Vector extends DoubleVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Double512Mask.class, long.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Double512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -756,7 +763,7 @@ final class Double512Vector extends DoubleVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(Double512Mask.class, double.class, VLENGTH, + return VectorSupport.extract(Double512Mask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -765,7 +772,7 @@ final class Double512Vector extends DoubleVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, Double512Mask.class, long.class, VLENGTH, + return VectorSupport.test(BT_ne, Double512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((Double512Mask)m).getBits())); } @@ -773,7 +780,7 @@ final class Double512Vector extends DoubleVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, Double512Mask.class, long.class, VLENGTH, + return VectorSupport.test(BT_overflow, Double512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((Double512Mask)m).getBits())); } @@ -781,7 +788,7 @@ final class Double512Vector extends DoubleVector { @ForceInline /*package-private*/ static Double512Mask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(Double512Mask.class, long.class, VLENGTH, + return VectorSupport.fromBitsCoerced(Double512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double64Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double64Vector.java index df6b627cc18..9535f112ada 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double64Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double64Vector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class Double64Vector extends DoubleVector { return (double[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -515,7 +522,7 @@ final class Double64Vector extends DoubleVector { @ForceInline public long laneHelper(int i) { return (long) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { double[] vecarr = vec.vec(); @@ -535,7 +542,7 @@ final class Double64Vector extends DoubleVector { @ForceInline public Double64Vector withLaneHelper(int i, double e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)Double.doubleToRawLongBits(e), (v, ix, bits) -> { double[] res = v.vec().clone(); @@ -639,8 +646,8 @@ final class Double64Vector extends DoubleVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -650,7 +657,7 @@ final class Double64Vector extends DoubleVector { /*package-private*/ Double64Mask indexPartiallyInUpperRange(long offset, long limit) { return (Double64Mask) VectorSupport.indexPartiallyInUpperRange( - Double64Mask.class, double.class, VLENGTH, offset, limit, + Double64Mask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (Double64Mask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -666,7 +673,7 @@ final class Double64Vector extends DoubleVector { @ForceInline public Double64Mask compress() { return (Double64Mask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - Double64Vector.class, Double64Mask.class, ETYPE, VLENGTH, null, this, + Double64Vector.class, Double64Mask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -678,7 +685,7 @@ final class Double64Vector extends DoubleVector { public Double64Mask and(VectorMask mask) { Objects.requireNonNull(mask); Double64Mask m = (Double64Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, Double64Mask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, Double64Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -688,7 +695,7 @@ final class Double64Vector extends DoubleVector { public Double64Mask or(VectorMask mask) { Objects.requireNonNull(mask); Double64Mask m = (Double64Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, Double64Mask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, Double64Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -698,7 +705,7 @@ final class Double64Vector extends DoubleVector { public Double64Mask xor(VectorMask mask) { Objects.requireNonNull(mask); Double64Mask m = (Double64Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, Double64Mask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, Double64Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -708,21 +715,21 @@ final class Double64Vector extends DoubleVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Double64Mask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Double64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Double64Mask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Double64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Double64Mask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Double64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -732,7 +739,7 @@ final class Double64Vector extends DoubleVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Double64Mask.class, long.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Double64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -742,7 +749,7 @@ final class Double64Vector extends DoubleVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(Double64Mask.class, double.class, VLENGTH, + return VectorSupport.extract(Double64Mask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -751,7 +758,7 @@ final class Double64Vector extends DoubleVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, Double64Mask.class, long.class, VLENGTH, + return VectorSupport.test(BT_ne, Double64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((Double64Mask)m).getBits())); } @@ -759,7 +766,7 @@ final class Double64Vector extends DoubleVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, Double64Mask.class, long.class, VLENGTH, + return VectorSupport.test(BT_overflow, Double64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((Double64Mask)m).getBits())); } @@ -767,7 +774,7 @@ final class Double64Vector extends DoubleVector { @ForceInline /*package-private*/ static Double64Mask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(Double64Mask.class, long.class, VLENGTH, + return VectorSupport.fromBitsCoerced(Double64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleMaxVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleMaxVector.java index 47be1f609d8..8daa77dfc49 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleMaxVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleMaxVector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class DoubleMaxVector extends DoubleVector { return (double[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -514,7 +521,7 @@ final class DoubleMaxVector extends DoubleVector { @ForceInline public long laneHelper(int i) { return (long) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { double[] vecarr = vec.vec(); @@ -534,7 +541,7 @@ final class DoubleMaxVector extends DoubleVector { @ForceInline public DoubleMaxVector withLaneHelper(int i, double e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)Double.doubleToRawLongBits(e), (v, ix, bits) -> { double[] res = v.vec().clone(); @@ -638,8 +645,8 @@ final class DoubleMaxVector extends DoubleVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -649,7 +656,7 @@ final class DoubleMaxVector extends DoubleVector { /*package-private*/ DoubleMaxMask indexPartiallyInUpperRange(long offset, long limit) { return (DoubleMaxMask) VectorSupport.indexPartiallyInUpperRange( - DoubleMaxMask.class, double.class, VLENGTH, offset, limit, + DoubleMaxMask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (DoubleMaxMask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -665,7 +672,7 @@ final class DoubleMaxVector extends DoubleVector { @ForceInline public DoubleMaxMask compress() { return (DoubleMaxMask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - DoubleMaxVector.class, DoubleMaxMask.class, ETYPE, VLENGTH, null, this, + DoubleMaxVector.class, DoubleMaxMask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -677,7 +684,7 @@ final class DoubleMaxVector extends DoubleVector { public DoubleMaxMask and(VectorMask mask) { Objects.requireNonNull(mask); DoubleMaxMask m = (DoubleMaxMask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, DoubleMaxMask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, DoubleMaxMask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -687,7 +694,7 @@ final class DoubleMaxVector extends DoubleVector { public DoubleMaxMask or(VectorMask mask) { Objects.requireNonNull(mask); DoubleMaxMask m = (DoubleMaxMask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, DoubleMaxMask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, DoubleMaxMask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -697,7 +704,7 @@ final class DoubleMaxVector extends DoubleVector { public DoubleMaxMask xor(VectorMask mask) { Objects.requireNonNull(mask); DoubleMaxMask m = (DoubleMaxMask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, DoubleMaxMask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, DoubleMaxMask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -707,21 +714,21 @@ final class DoubleMaxVector extends DoubleVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, DoubleMaxMask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, DoubleMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, DoubleMaxMask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, DoubleMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, DoubleMaxMask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, DoubleMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -731,7 +738,7 @@ final class DoubleMaxVector extends DoubleVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, DoubleMaxMask.class, long.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, DoubleMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -741,7 +748,7 @@ final class DoubleMaxVector extends DoubleVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(DoubleMaxMask.class, double.class, VLENGTH, + return VectorSupport.extract(DoubleMaxMask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -750,7 +757,7 @@ final class DoubleMaxVector extends DoubleVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, DoubleMaxMask.class, long.class, VLENGTH, + return VectorSupport.test(BT_ne, DoubleMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((DoubleMaxMask)m).getBits())); } @@ -758,7 +765,7 @@ final class DoubleMaxVector extends DoubleVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, DoubleMaxMask.class, long.class, VLENGTH, + return VectorSupport.test(BT_overflow, DoubleMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((DoubleMaxMask)m).getBits())); } @@ -766,7 +773,7 @@ final class DoubleMaxVector extends DoubleVector { @ForceInline /*package-private*/ static DoubleMaxMask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(DoubleMaxMask.class, long.class, VLENGTH, + return VectorSupport.fromBitsCoerced(DoubleMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleVector.java index 08fda9c96e6..70be5f829f0 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleVector.java @@ -59,6 +59,10 @@ public abstract class DoubleVector extends AbstractVector { static final ValueLayout.OfDouble ELEMENT_LAYOUT = ValueLayout.JAVA_DOUBLE.withByteAlignment(1); + static final int LANE_TYPE_ORDINAL = LT_DOUBLE; + + static final int LANEBITS_TYPE_ORDINAL = LT_LONG; + @ForceInline static int opCode(Operator op) { return VectorOperators.opCode(op, VO_OPCODE_VALID, FORBID_OPCODE_KIND); @@ -562,7 +566,7 @@ public abstract class DoubleVector extends AbstractVector { @ForceInline public static DoubleVector zero(VectorSpecies species) { DoubleSpecies vsp = (DoubleSpecies) species; - return VectorSupport.fromBitsCoerced(vsp.vectorType(), double.class, species.length(), + return VectorSupport.fromBitsCoerced(vsp.vectorType(), LANE_TYPE_ORDINAL, species.length(), toBits(0.0f), MODE_BROADCAST, vsp, ((bits_, s_) -> s_.rvOp(i -> bits_))); } @@ -684,7 +688,7 @@ public abstract class DoubleVector extends AbstractVector { } int opc = opCode(op); return VectorSupport.unaryOp( - opc, getClass(), null, double.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, null, UN_IMPL.find(op, opc, DoubleVector::unaryOperations)); } @@ -712,7 +716,7 @@ public abstract class DoubleVector extends AbstractVector { } int opc = opCode(op); return VectorSupport.unaryOp( - opc, getClass(), maskClass, double.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, m, UN_IMPL.find(op, opc, DoubleVector::unaryOperations)); } @@ -801,7 +805,7 @@ public abstract class DoubleVector extends AbstractVector { int opc = opCode(op); return VectorSupport.binaryOp( - opc, getClass(), null, double.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, that, null, BIN_IMPL.find(op, opc, DoubleVector::binaryOperations)); } @@ -839,7 +843,7 @@ public abstract class DoubleVector extends AbstractVector { int opc = opCode(op); return VectorSupport.binaryOp( - opc, getClass(), maskClass, double.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, that, m, BIN_IMPL.find(op, opc, DoubleVector::binaryOperations)); } @@ -1021,7 +1025,7 @@ public abstract class DoubleVector extends AbstractVector { tother.check(this); int opc = opCode(op); return VectorSupport.ternaryOp( - opc, getClass(), null, double.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, that, tother, null, TERN_IMPL.find(op, opc, DoubleVector::ternaryOperations)); } @@ -1056,7 +1060,7 @@ public abstract class DoubleVector extends AbstractVector { int opc = opCode(op); return VectorSupport.ternaryOp( - opc, getClass(), maskClass, double.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, that, tother, m, TERN_IMPL.find(op, opc, DoubleVector::ternaryOperations)); } @@ -1928,7 +1932,7 @@ public abstract class DoubleVector extends AbstractVector { that.check(this); int opc = opCode(op); return VectorSupport.compare( - opc, getClass(), maskType, double.class, length(), + opc, getClass(), maskType, laneTypeOrdinal(), length(), this, that, null, (cond, v0, v1, m1) -> { AbstractMask m @@ -1950,7 +1954,7 @@ public abstract class DoubleVector extends AbstractVector { m.check(maskType, this); int opc = opCode(op); return VectorSupport.compare( - opc, getClass(), maskType, double.class, length(), + opc, getClass(), maskType, laneTypeOrdinal(), length(), this, that, m, (cond, v0, v1, m1) -> { AbstractMask cmpM @@ -2077,7 +2081,7 @@ public abstract class DoubleVector extends AbstractVector { blendTemplate(Class maskType, DoubleVector v, M m) { v.check(this); return VectorSupport.blend( - getClass(), maskType, double.class, length(), + getClass(), maskType, laneTypeOrdinal(), length(), this, v, m, (v0, v1, m_) -> v0.bOp(v1, m_, (i, a, b) -> b)); } @@ -2094,7 +2098,7 @@ public abstract class DoubleVector extends AbstractVector { // make sure VLENGTH*scale doesn't overflow: vsp.checkScale(scale); return VectorSupport.indexVector( - getClass(), double.class, length(), + getClass(), laneTypeOrdinal(), length(), this, scale, vsp, (v, scale_, s) -> { @@ -2286,7 +2290,7 @@ public abstract class DoubleVector extends AbstractVector { DoubleVector rearrangeTemplate(Class shuffletype, S shuffle) { Objects.requireNonNull(shuffle); return VectorSupport.rearrangeOp( - getClass(), shuffletype, null, double.class, length(), + getClass(), shuffletype, null, laneTypeOrdinal(), length(), this, shuffle, null, (v1, s_, m_) -> v1.uOp((i, a) -> { int ei = Integer.remainderUnsigned(s_.laneSource(i), v1.length()); @@ -2313,7 +2317,7 @@ public abstract class DoubleVector extends AbstractVector { Objects.requireNonNull(shuffle); m.check(masktype, this); return VectorSupport.rearrangeOp( - getClass(), shuffletype, masktype, double.class, length(), + getClass(), shuffletype, masktype, laneTypeOrdinal(), length(), this, shuffle, m, (v1, s_, m_) -> v1.uOp((i, a) -> { int ei = Integer.remainderUnsigned(s_.laneSource(i), v1.length()); @@ -2339,7 +2343,7 @@ public abstract class DoubleVector extends AbstractVector { VectorMask valid = shuffle.laneIsValid(); DoubleVector r0 = VectorSupport.rearrangeOp( - getClass(), shuffletype, null, double.class, length(), + getClass(), shuffletype, null, laneTypeOrdinal(), length(), this, shuffle, null, (v0, s_, m_) -> v0.uOp((i, a) -> { int ei = Integer.remainderUnsigned(s_.laneSource(i), v0.length()); @@ -2347,7 +2351,7 @@ public abstract class DoubleVector extends AbstractVector { })); DoubleVector r1 = VectorSupport.rearrangeOp( - getClass(), shuffletype, null, double.class, length(), + getClass(), shuffletype, null, laneTypeOrdinal(), length(), v, shuffle, null, (v1, s_, m_) -> v1.uOp((i, a) -> { int ei = Integer.remainderUnsigned(s_.laneSource(i), v1.length()); @@ -2391,7 +2395,7 @@ public abstract class DoubleVector extends AbstractVector { DoubleVector compressTemplate(Class masktype, M m) { m.check(masktype, this); return (DoubleVector) VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_COMPRESS, getClass(), masktype, - double.class, length(), this, m, + laneTypeOrdinal(), length(), this, m, (v1, m1) -> compressHelper(v1, m1)); } @@ -2410,7 +2414,7 @@ public abstract class DoubleVector extends AbstractVector { DoubleVector expandTemplate(Class masktype, M m) { m.check(masktype, this); return (DoubleVector) VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_EXPAND, getClass(), masktype, - double.class, length(), this, m, + laneTypeOrdinal(), length(), this, m, (v1, m1) -> expandHelper(v1, m1)); } @@ -2425,7 +2429,7 @@ public abstract class DoubleVector extends AbstractVector { /*package-private*/ @ForceInline final DoubleVector selectFromTemplate(DoubleVector v) { - return (DoubleVector)VectorSupport.selectFromOp(getClass(), null, double.class, + return (DoubleVector)VectorSupport.selectFromOp(getClass(), null, laneTypeOrdinal(), length(), this, v, null, (v1, v2, _m) -> v2.rearrange(v1.toShuffle())); @@ -2445,7 +2449,7 @@ public abstract class DoubleVector extends AbstractVector { DoubleVector selectFromTemplate(DoubleVector v, Class masktype, M m) { m.check(masktype, this); - return (DoubleVector)VectorSupport.selectFromOp(getClass(), masktype, double.class, + return (DoubleVector)VectorSupport.selectFromOp(getClass(), masktype, laneTypeOrdinal(), length(), this, v, m, (v1, v2, _m) -> v2.rearrange(v1.toShuffle(), _m)); @@ -2463,7 +2467,7 @@ public abstract class DoubleVector extends AbstractVector { /*package-private*/ @ForceInline final DoubleVector selectFromTemplate(DoubleVector v1, DoubleVector v2) { - return VectorSupport.selectFromTwoVectorOp(getClass(), double.class, length(), this, v1, v2, + return VectorSupport.selectFromTwoVectorOp(getClass(), laneTypeOrdinal(), length(), this, v1, v2, (vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)); } @@ -2661,7 +2665,7 @@ public abstract class DoubleVector extends AbstractVector { } int opc = opCode(op); return fromBits(VectorSupport.reductionCoerced( - opc, getClass(), maskClass, double.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, m, REDUCE_IMPL.find(op, opc, DoubleVector::reductionOperations))); } @@ -2679,7 +2683,7 @@ public abstract class DoubleVector extends AbstractVector { } int opc = opCode(op); return fromBits(VectorSupport.reductionCoerced( - opc, getClass(), null, double.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, null, REDUCE_IMPL.find(op, opc, DoubleVector::reductionOperations))); } @@ -2936,7 +2940,7 @@ public abstract class DoubleVector extends AbstractVector { vix = VectorIntrinsics.checkIndex(vix, a.length); return VectorSupport.loadWithMap( - vectorType, null, double.class, vsp.laneCount(), + vectorType, null, LANE_TYPE_ORDINAL, vsp.laneCount(), isp.vectorType(), isp.length(), a, ARRAY_BASE, vix, null, null, null, null, a, offset, indexMap, mapOffset, vsp, @@ -3119,7 +3123,7 @@ public abstract class DoubleVector extends AbstractVector { offset = checkFromIndexSize(offset, length(), a.length); DoubleSpecies vsp = vspecies(); VectorSupport.store( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, this, a, offset, @@ -3227,7 +3231,7 @@ public abstract class DoubleVector extends AbstractVector { vix = VectorIntrinsics.checkIndex(vix, a.length); VectorSupport.storeWithMap( - vsp.vectorType(), null, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), null, LANE_TYPE_ORDINAL, vsp.laneCount(), isp.vectorType(), isp.length(), a, arrayAddress(a, 0), vix, this, null, @@ -3354,7 +3358,7 @@ public abstract class DoubleVector extends AbstractVector { DoubleVector fromArray0Template(double[] a, int offset) { DoubleSpecies vsp = vspecies(); return VectorSupport.load( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, a, offset, vsp, (arr, off, s) -> s.ldOp(arr, (int) off, @@ -3371,7 +3375,7 @@ public abstract class DoubleVector extends AbstractVector { m.check(species()); DoubleSpecies vsp = vspecies(); return VectorSupport.loadMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, m, offsetInRange, a, offset, vsp, (arr, off, s, vm) -> s.ldOp(arr, (int) off, vm, @@ -3422,7 +3426,7 @@ public abstract class DoubleVector extends AbstractVector { vix = VectorIntrinsics.checkIndex(vix, a.length); return VectorSupport.loadWithMap( - vectorType, maskClass, double.class, vsp.laneCount(), + vectorType, maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), isp.vectorType(), isp.length(), a, ARRAY_BASE, vix, null, null, null, m, a, offset, indexMap, mapOffset, vsp, @@ -3439,7 +3443,7 @@ public abstract class DoubleVector extends AbstractVector { DoubleVector fromMemorySegment0Template(MemorySegment ms, long offset) { DoubleSpecies vsp = vspecies(); return ScopedMemoryAccess.loadFromMemorySegment( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), (AbstractMemorySegmentImpl) ms, offset, vsp, (msp, off, s) -> { return s.ldLongOp((MemorySegment) msp, off, DoubleVector::memorySegmentGet); @@ -3455,7 +3459,7 @@ public abstract class DoubleVector extends AbstractVector { DoubleSpecies vsp = vspecies(); m.check(vsp); return ScopedMemoryAccess.loadFromMemorySegmentMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), (AbstractMemorySegmentImpl) ms, offset, m, vsp, offsetInRange, (msp, off, s, vm) -> { return s.ldLongOp((MemorySegment) msp, off, vm, DoubleVector::memorySegmentGet); @@ -3473,7 +3477,7 @@ public abstract class DoubleVector extends AbstractVector { void intoArray0Template(double[] a, int offset) { DoubleSpecies vsp = vspecies(); VectorSupport.store( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, this, a, offset, (arr, off, v) @@ -3490,7 +3494,7 @@ public abstract class DoubleVector extends AbstractVector { m.check(species()); DoubleSpecies vsp = vspecies(); VectorSupport.storeMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, this, m, a, offset, (arr, off, v, vm) @@ -3538,7 +3542,7 @@ public abstract class DoubleVector extends AbstractVector { vix = VectorIntrinsics.checkIndex(vix, a.length); VectorSupport.storeWithMap( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), isp.vectorType(), isp.length(), a, arrayAddress(a, 0), vix, this, m, @@ -3557,7 +3561,7 @@ public abstract class DoubleVector extends AbstractVector { void intoMemorySegment0(MemorySegment ms, long offset) { DoubleSpecies vsp = vspecies(); ScopedMemoryAccess.storeIntoMemorySegment( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), this, (AbstractMemorySegmentImpl) ms, offset, (msp, off, v) -> { @@ -3574,7 +3578,7 @@ public abstract class DoubleVector extends AbstractVector { DoubleSpecies vsp = vspecies(); m.check(vsp); ScopedMemoryAccess.storeIntoMemorySegmentMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), this, m, (AbstractMemorySegmentImpl) ms, offset, (msp, off, v, vm) -> { @@ -3612,6 +3616,18 @@ public abstract class DoubleVector extends AbstractVector { return this; } + @Override + @ForceInline + final + DoubleVector swapIfNeeded(AbstractSpecies srcSpecies) { + int subLanesPerSrc = subLanesToSwap(srcSpecies); + if (subLanesPerSrc < 0) { + return this; + } + VectorShuffle shuffle = normalizeSubLanesForSpecies(this.vspecies(), subLanesPerSrc); + return (DoubleVector) this.rearrange(shuffle); + } + static final int ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_DOUBLE_INDEX_SCALE); static final long ARRAY_BASE = @@ -3778,7 +3794,7 @@ public abstract class DoubleVector extends AbstractVector { final DoubleVector broadcastBits(long bits) { return (DoubleVector) VectorSupport.fromBitsCoerced( - vectorType, double.class, laneCount, + vectorType, laneTypeOrdinal(), laneCount, bits, MODE_BROADCAST, this, (bits_, s_) -> s_.rvOp(i -> bits_)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float128Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float128Vector.java index fdfd234cb47..62c7d535fc7 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float128Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float128Vector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class Float128Vector extends FloatVector { return (float[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -518,7 +525,7 @@ final class Float128Vector extends FloatVector { @ForceInline public int laneHelper(int i) { return (int) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { float[] vecarr = vec.vec(); @@ -541,7 +548,7 @@ final class Float128Vector extends FloatVector { @ForceInline public Float128Vector withLaneHelper(int i, float e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)Float.floatToRawIntBits(e), (v, ix, bits) -> { float[] res = v.vec().clone(); @@ -645,8 +652,8 @@ final class Float128Vector extends FloatVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -656,7 +663,7 @@ final class Float128Vector extends FloatVector { /*package-private*/ Float128Mask indexPartiallyInUpperRange(long offset, long limit) { return (Float128Mask) VectorSupport.indexPartiallyInUpperRange( - Float128Mask.class, float.class, VLENGTH, offset, limit, + Float128Mask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (Float128Mask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -672,7 +679,7 @@ final class Float128Vector extends FloatVector { @ForceInline public Float128Mask compress() { return (Float128Mask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - Float128Vector.class, Float128Mask.class, ETYPE, VLENGTH, null, this, + Float128Vector.class, Float128Mask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -684,7 +691,7 @@ final class Float128Vector extends FloatVector { public Float128Mask and(VectorMask mask) { Objects.requireNonNull(mask); Float128Mask m = (Float128Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, Float128Mask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, Float128Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -694,7 +701,7 @@ final class Float128Vector extends FloatVector { public Float128Mask or(VectorMask mask) { Objects.requireNonNull(mask); Float128Mask m = (Float128Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, Float128Mask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, Float128Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -704,7 +711,7 @@ final class Float128Vector extends FloatVector { public Float128Mask xor(VectorMask mask) { Objects.requireNonNull(mask); Float128Mask m = (Float128Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, Float128Mask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, Float128Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -714,21 +721,21 @@ final class Float128Vector extends FloatVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Float128Mask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Float128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Float128Mask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Float128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Float128Mask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Float128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -738,7 +745,7 @@ final class Float128Vector extends FloatVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Float128Mask.class, int.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Float128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -748,7 +755,7 @@ final class Float128Vector extends FloatVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(Float128Mask.class, float.class, VLENGTH, + return VectorSupport.extract(Float128Mask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -757,7 +764,7 @@ final class Float128Vector extends FloatVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, Float128Mask.class, int.class, VLENGTH, + return VectorSupport.test(BT_ne, Float128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((Float128Mask)m).getBits())); } @@ -765,7 +772,7 @@ final class Float128Vector extends FloatVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, Float128Mask.class, int.class, VLENGTH, + return VectorSupport.test(BT_overflow, Float128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((Float128Mask)m).getBits())); } @@ -773,7 +780,7 @@ final class Float128Vector extends FloatVector { @ForceInline /*package-private*/ static Float128Mask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(Float128Mask.class, int.class, VLENGTH, + return VectorSupport.fromBitsCoerced(Float128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float256Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float256Vector.java index 2543382ca14..f41194500f9 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float256Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float256Vector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class Float256Vector extends FloatVector { return (float[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -522,7 +529,7 @@ final class Float256Vector extends FloatVector { @ForceInline public int laneHelper(int i) { return (int) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { float[] vecarr = vec.vec(); @@ -549,7 +556,7 @@ final class Float256Vector extends FloatVector { @ForceInline public Float256Vector withLaneHelper(int i, float e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)Float.floatToRawIntBits(e), (v, ix, bits) -> { float[] res = v.vec().clone(); @@ -653,8 +660,8 @@ final class Float256Vector extends FloatVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -664,7 +671,7 @@ final class Float256Vector extends FloatVector { /*package-private*/ Float256Mask indexPartiallyInUpperRange(long offset, long limit) { return (Float256Mask) VectorSupport.indexPartiallyInUpperRange( - Float256Mask.class, float.class, VLENGTH, offset, limit, + Float256Mask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (Float256Mask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -680,7 +687,7 @@ final class Float256Vector extends FloatVector { @ForceInline public Float256Mask compress() { return (Float256Mask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - Float256Vector.class, Float256Mask.class, ETYPE, VLENGTH, null, this, + Float256Vector.class, Float256Mask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -692,7 +699,7 @@ final class Float256Vector extends FloatVector { public Float256Mask and(VectorMask mask) { Objects.requireNonNull(mask); Float256Mask m = (Float256Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, Float256Mask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, Float256Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -702,7 +709,7 @@ final class Float256Vector extends FloatVector { public Float256Mask or(VectorMask mask) { Objects.requireNonNull(mask); Float256Mask m = (Float256Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, Float256Mask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, Float256Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -712,7 +719,7 @@ final class Float256Vector extends FloatVector { public Float256Mask xor(VectorMask mask) { Objects.requireNonNull(mask); Float256Mask m = (Float256Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, Float256Mask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, Float256Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -722,21 +729,21 @@ final class Float256Vector extends FloatVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Float256Mask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Float256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Float256Mask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Float256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Float256Mask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Float256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -746,7 +753,7 @@ final class Float256Vector extends FloatVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Float256Mask.class, int.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Float256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -756,7 +763,7 @@ final class Float256Vector extends FloatVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(Float256Mask.class, float.class, VLENGTH, + return VectorSupport.extract(Float256Mask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -765,7 +772,7 @@ final class Float256Vector extends FloatVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, Float256Mask.class, int.class, VLENGTH, + return VectorSupport.test(BT_ne, Float256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((Float256Mask)m).getBits())); } @@ -773,7 +780,7 @@ final class Float256Vector extends FloatVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, Float256Mask.class, int.class, VLENGTH, + return VectorSupport.test(BT_overflow, Float256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((Float256Mask)m).getBits())); } @@ -781,7 +788,7 @@ final class Float256Vector extends FloatVector { @ForceInline /*package-private*/ static Float256Mask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(Float256Mask.class, int.class, VLENGTH, + return VectorSupport.fromBitsCoerced(Float256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float512Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float512Vector.java index 627b1e0a237..c2fced0fdae 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float512Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float512Vector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class Float512Vector extends FloatVector { return (float[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -530,7 +537,7 @@ final class Float512Vector extends FloatVector { @ForceInline public int laneHelper(int i) { return (int) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { float[] vecarr = vec.vec(); @@ -565,7 +572,7 @@ final class Float512Vector extends FloatVector { @ForceInline public Float512Vector withLaneHelper(int i, float e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)Float.floatToRawIntBits(e), (v, ix, bits) -> { float[] res = v.vec().clone(); @@ -669,8 +676,8 @@ final class Float512Vector extends FloatVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -680,7 +687,7 @@ final class Float512Vector extends FloatVector { /*package-private*/ Float512Mask indexPartiallyInUpperRange(long offset, long limit) { return (Float512Mask) VectorSupport.indexPartiallyInUpperRange( - Float512Mask.class, float.class, VLENGTH, offset, limit, + Float512Mask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (Float512Mask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -696,7 +703,7 @@ final class Float512Vector extends FloatVector { @ForceInline public Float512Mask compress() { return (Float512Mask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - Float512Vector.class, Float512Mask.class, ETYPE, VLENGTH, null, this, + Float512Vector.class, Float512Mask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -708,7 +715,7 @@ final class Float512Vector extends FloatVector { public Float512Mask and(VectorMask mask) { Objects.requireNonNull(mask); Float512Mask m = (Float512Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, Float512Mask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, Float512Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -718,7 +725,7 @@ final class Float512Vector extends FloatVector { public Float512Mask or(VectorMask mask) { Objects.requireNonNull(mask); Float512Mask m = (Float512Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, Float512Mask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, Float512Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -728,7 +735,7 @@ final class Float512Vector extends FloatVector { public Float512Mask xor(VectorMask mask) { Objects.requireNonNull(mask); Float512Mask m = (Float512Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, Float512Mask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, Float512Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -738,21 +745,21 @@ final class Float512Vector extends FloatVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Float512Mask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Float512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Float512Mask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Float512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Float512Mask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Float512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -762,7 +769,7 @@ final class Float512Vector extends FloatVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Float512Mask.class, int.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Float512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -772,7 +779,7 @@ final class Float512Vector extends FloatVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(Float512Mask.class, float.class, VLENGTH, + return VectorSupport.extract(Float512Mask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -781,7 +788,7 @@ final class Float512Vector extends FloatVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, Float512Mask.class, int.class, VLENGTH, + return VectorSupport.test(BT_ne, Float512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((Float512Mask)m).getBits())); } @@ -789,7 +796,7 @@ final class Float512Vector extends FloatVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, Float512Mask.class, int.class, VLENGTH, + return VectorSupport.test(BT_overflow, Float512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((Float512Mask)m).getBits())); } @@ -797,7 +804,7 @@ final class Float512Vector extends FloatVector { @ForceInline /*package-private*/ static Float512Mask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(Float512Mask.class, int.class, VLENGTH, + return VectorSupport.fromBitsCoerced(Float512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float64Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float64Vector.java index 3360fdb537a..67676c828d6 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float64Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float64Vector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class Float64Vector extends FloatVector { return (float[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -516,7 +523,7 @@ final class Float64Vector extends FloatVector { @ForceInline public int laneHelper(int i) { return (int) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { float[] vecarr = vec.vec(); @@ -537,7 +544,7 @@ final class Float64Vector extends FloatVector { @ForceInline public Float64Vector withLaneHelper(int i, float e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)Float.floatToRawIntBits(e), (v, ix, bits) -> { float[] res = v.vec().clone(); @@ -641,8 +648,8 @@ final class Float64Vector extends FloatVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -652,7 +659,7 @@ final class Float64Vector extends FloatVector { /*package-private*/ Float64Mask indexPartiallyInUpperRange(long offset, long limit) { return (Float64Mask) VectorSupport.indexPartiallyInUpperRange( - Float64Mask.class, float.class, VLENGTH, offset, limit, + Float64Mask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (Float64Mask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -668,7 +675,7 @@ final class Float64Vector extends FloatVector { @ForceInline public Float64Mask compress() { return (Float64Mask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - Float64Vector.class, Float64Mask.class, ETYPE, VLENGTH, null, this, + Float64Vector.class, Float64Mask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -680,7 +687,7 @@ final class Float64Vector extends FloatVector { public Float64Mask and(VectorMask mask) { Objects.requireNonNull(mask); Float64Mask m = (Float64Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, Float64Mask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, Float64Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -690,7 +697,7 @@ final class Float64Vector extends FloatVector { public Float64Mask or(VectorMask mask) { Objects.requireNonNull(mask); Float64Mask m = (Float64Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, Float64Mask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, Float64Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -700,7 +707,7 @@ final class Float64Vector extends FloatVector { public Float64Mask xor(VectorMask mask) { Objects.requireNonNull(mask); Float64Mask m = (Float64Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, Float64Mask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, Float64Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -710,21 +717,21 @@ final class Float64Vector extends FloatVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Float64Mask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Float64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Float64Mask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Float64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Float64Mask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Float64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -734,7 +741,7 @@ final class Float64Vector extends FloatVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Float64Mask.class, int.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Float64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -744,7 +751,7 @@ final class Float64Vector extends FloatVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(Float64Mask.class, float.class, VLENGTH, + return VectorSupport.extract(Float64Mask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -753,7 +760,7 @@ final class Float64Vector extends FloatVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, Float64Mask.class, int.class, VLENGTH, + return VectorSupport.test(BT_ne, Float64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((Float64Mask)m).getBits())); } @@ -761,7 +768,7 @@ final class Float64Vector extends FloatVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, Float64Mask.class, int.class, VLENGTH, + return VectorSupport.test(BT_overflow, Float64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((Float64Mask)m).getBits())); } @@ -769,7 +776,7 @@ final class Float64Vector extends FloatVector { @ForceInline /*package-private*/ static Float64Mask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(Float64Mask.class, int.class, VLENGTH, + return VectorSupport.fromBitsCoerced(Float64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatMaxVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatMaxVector.java index 4a72661ce8b..35e4c83ebde 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatMaxVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatMaxVector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class FloatMaxVector extends FloatVector { return (float[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -514,7 +521,7 @@ final class FloatMaxVector extends FloatVector { @ForceInline public int laneHelper(int i) { return (int) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { float[] vecarr = vec.vec(); @@ -534,7 +541,7 @@ final class FloatMaxVector extends FloatVector { @ForceInline public FloatMaxVector withLaneHelper(int i, float e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)Float.floatToRawIntBits(e), (v, ix, bits) -> { float[] res = v.vec().clone(); @@ -638,8 +645,8 @@ final class FloatMaxVector extends FloatVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -649,7 +656,7 @@ final class FloatMaxVector extends FloatVector { /*package-private*/ FloatMaxMask indexPartiallyInUpperRange(long offset, long limit) { return (FloatMaxMask) VectorSupport.indexPartiallyInUpperRange( - FloatMaxMask.class, float.class, VLENGTH, offset, limit, + FloatMaxMask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (FloatMaxMask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -665,7 +672,7 @@ final class FloatMaxVector extends FloatVector { @ForceInline public FloatMaxMask compress() { return (FloatMaxMask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - FloatMaxVector.class, FloatMaxMask.class, ETYPE, VLENGTH, null, this, + FloatMaxVector.class, FloatMaxMask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -677,7 +684,7 @@ final class FloatMaxVector extends FloatVector { public FloatMaxMask and(VectorMask mask) { Objects.requireNonNull(mask); FloatMaxMask m = (FloatMaxMask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, FloatMaxMask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, FloatMaxMask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -687,7 +694,7 @@ final class FloatMaxVector extends FloatVector { public FloatMaxMask or(VectorMask mask) { Objects.requireNonNull(mask); FloatMaxMask m = (FloatMaxMask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, FloatMaxMask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, FloatMaxMask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -697,7 +704,7 @@ final class FloatMaxVector extends FloatVector { public FloatMaxMask xor(VectorMask mask) { Objects.requireNonNull(mask); FloatMaxMask m = (FloatMaxMask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, FloatMaxMask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, FloatMaxMask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -707,21 +714,21 @@ final class FloatMaxVector extends FloatVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, FloatMaxMask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, FloatMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, FloatMaxMask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, FloatMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, FloatMaxMask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, FloatMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -731,7 +738,7 @@ final class FloatMaxVector extends FloatVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, FloatMaxMask.class, int.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, FloatMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -741,7 +748,7 @@ final class FloatMaxVector extends FloatVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(FloatMaxMask.class, float.class, VLENGTH, + return VectorSupport.extract(FloatMaxMask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -750,7 +757,7 @@ final class FloatMaxVector extends FloatVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, FloatMaxMask.class, int.class, VLENGTH, + return VectorSupport.test(BT_ne, FloatMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((FloatMaxMask)m).getBits())); } @@ -758,7 +765,7 @@ final class FloatMaxVector extends FloatVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, FloatMaxMask.class, int.class, VLENGTH, + return VectorSupport.test(BT_overflow, FloatMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((FloatMaxMask)m).getBits())); } @@ -766,7 +773,7 @@ final class FloatMaxVector extends FloatVector { @ForceInline /*package-private*/ static FloatMaxMask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(FloatMaxMask.class, int.class, VLENGTH, + return VectorSupport.fromBitsCoerced(FloatMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatVector.java index 0f70a2b81c8..ee9cb9119fd 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatVector.java @@ -59,6 +59,10 @@ public abstract class FloatVector extends AbstractVector { static final ValueLayout.OfFloat ELEMENT_LAYOUT = ValueLayout.JAVA_FLOAT.withByteAlignment(1); + static final int LANE_TYPE_ORDINAL = LT_FLOAT; + + static final int LANEBITS_TYPE_ORDINAL = LT_INT; + @ForceInline static int opCode(Operator op) { return VectorOperators.opCode(op, VO_OPCODE_VALID, FORBID_OPCODE_KIND); @@ -562,7 +566,7 @@ public abstract class FloatVector extends AbstractVector { @ForceInline public static FloatVector zero(VectorSpecies species) { FloatSpecies vsp = (FloatSpecies) species; - return VectorSupport.fromBitsCoerced(vsp.vectorType(), float.class, species.length(), + return VectorSupport.fromBitsCoerced(vsp.vectorType(), LANE_TYPE_ORDINAL, species.length(), toBits(0.0f), MODE_BROADCAST, vsp, ((bits_, s_) -> s_.rvOp(i -> bits_))); } @@ -684,7 +688,7 @@ public abstract class FloatVector extends AbstractVector { } int opc = opCode(op); return VectorSupport.unaryOp( - opc, getClass(), null, float.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, null, UN_IMPL.find(op, opc, FloatVector::unaryOperations)); } @@ -712,7 +716,7 @@ public abstract class FloatVector extends AbstractVector { } int opc = opCode(op); return VectorSupport.unaryOp( - opc, getClass(), maskClass, float.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, m, UN_IMPL.find(op, opc, FloatVector::unaryOperations)); } @@ -801,7 +805,7 @@ public abstract class FloatVector extends AbstractVector { int opc = opCode(op); return VectorSupport.binaryOp( - opc, getClass(), null, float.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, that, null, BIN_IMPL.find(op, opc, FloatVector::binaryOperations)); } @@ -839,7 +843,7 @@ public abstract class FloatVector extends AbstractVector { int opc = opCode(op); return VectorSupport.binaryOp( - opc, getClass(), maskClass, float.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, that, m, BIN_IMPL.find(op, opc, FloatVector::binaryOperations)); } @@ -1021,7 +1025,7 @@ public abstract class FloatVector extends AbstractVector { tother.check(this); int opc = opCode(op); return VectorSupport.ternaryOp( - opc, getClass(), null, float.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, that, tother, null, TERN_IMPL.find(op, opc, FloatVector::ternaryOperations)); } @@ -1056,7 +1060,7 @@ public abstract class FloatVector extends AbstractVector { int opc = opCode(op); return VectorSupport.ternaryOp( - opc, getClass(), maskClass, float.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, that, tother, m, TERN_IMPL.find(op, opc, FloatVector::ternaryOperations)); } @@ -1940,7 +1944,7 @@ public abstract class FloatVector extends AbstractVector { that.check(this); int opc = opCode(op); return VectorSupport.compare( - opc, getClass(), maskType, float.class, length(), + opc, getClass(), maskType, laneTypeOrdinal(), length(), this, that, null, (cond, v0, v1, m1) -> { AbstractMask m @@ -1962,7 +1966,7 @@ public abstract class FloatVector extends AbstractVector { m.check(maskType, this); int opc = opCode(op); return VectorSupport.compare( - opc, getClass(), maskType, float.class, length(), + opc, getClass(), maskType, laneTypeOrdinal(), length(), this, that, m, (cond, v0, v1, m1) -> { AbstractMask cmpM @@ -2089,7 +2093,7 @@ public abstract class FloatVector extends AbstractVector { blendTemplate(Class maskType, FloatVector v, M m) { v.check(this); return VectorSupport.blend( - getClass(), maskType, float.class, length(), + getClass(), maskType, laneTypeOrdinal(), length(), this, v, m, (v0, v1, m_) -> v0.bOp(v1, m_, (i, a, b) -> b)); } @@ -2106,7 +2110,7 @@ public abstract class FloatVector extends AbstractVector { // make sure VLENGTH*scale doesn't overflow: vsp.checkScale(scale); return VectorSupport.indexVector( - getClass(), float.class, length(), + getClass(), laneTypeOrdinal(), length(), this, scale, vsp, (v, scale_, s) -> { @@ -2298,7 +2302,7 @@ public abstract class FloatVector extends AbstractVector { FloatVector rearrangeTemplate(Class shuffletype, S shuffle) { Objects.requireNonNull(shuffle); return VectorSupport.rearrangeOp( - getClass(), shuffletype, null, float.class, length(), + getClass(), shuffletype, null, laneTypeOrdinal(), length(), this, shuffle, null, (v1, s_, m_) -> v1.uOp((i, a) -> { int ei = Integer.remainderUnsigned(s_.laneSource(i), v1.length()); @@ -2325,7 +2329,7 @@ public abstract class FloatVector extends AbstractVector { Objects.requireNonNull(shuffle); m.check(masktype, this); return VectorSupport.rearrangeOp( - getClass(), shuffletype, masktype, float.class, length(), + getClass(), shuffletype, masktype, laneTypeOrdinal(), length(), this, shuffle, m, (v1, s_, m_) -> v1.uOp((i, a) -> { int ei = Integer.remainderUnsigned(s_.laneSource(i), v1.length()); @@ -2351,7 +2355,7 @@ public abstract class FloatVector extends AbstractVector { VectorMask valid = shuffle.laneIsValid(); FloatVector r0 = VectorSupport.rearrangeOp( - getClass(), shuffletype, null, float.class, length(), + getClass(), shuffletype, null, laneTypeOrdinal(), length(), this, shuffle, null, (v0, s_, m_) -> v0.uOp((i, a) -> { int ei = Integer.remainderUnsigned(s_.laneSource(i), v0.length()); @@ -2359,7 +2363,7 @@ public abstract class FloatVector extends AbstractVector { })); FloatVector r1 = VectorSupport.rearrangeOp( - getClass(), shuffletype, null, float.class, length(), + getClass(), shuffletype, null, laneTypeOrdinal(), length(), v, shuffle, null, (v1, s_, m_) -> v1.uOp((i, a) -> { int ei = Integer.remainderUnsigned(s_.laneSource(i), v1.length()); @@ -2403,7 +2407,7 @@ public abstract class FloatVector extends AbstractVector { FloatVector compressTemplate(Class masktype, M m) { m.check(masktype, this); return (FloatVector) VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_COMPRESS, getClass(), masktype, - float.class, length(), this, m, + laneTypeOrdinal(), length(), this, m, (v1, m1) -> compressHelper(v1, m1)); } @@ -2422,7 +2426,7 @@ public abstract class FloatVector extends AbstractVector { FloatVector expandTemplate(Class masktype, M m) { m.check(masktype, this); return (FloatVector) VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_EXPAND, getClass(), masktype, - float.class, length(), this, m, + laneTypeOrdinal(), length(), this, m, (v1, m1) -> expandHelper(v1, m1)); } @@ -2437,7 +2441,7 @@ public abstract class FloatVector extends AbstractVector { /*package-private*/ @ForceInline final FloatVector selectFromTemplate(FloatVector v) { - return (FloatVector)VectorSupport.selectFromOp(getClass(), null, float.class, + return (FloatVector)VectorSupport.selectFromOp(getClass(), null, laneTypeOrdinal(), length(), this, v, null, (v1, v2, _m) -> v2.rearrange(v1.toShuffle())); @@ -2457,7 +2461,7 @@ public abstract class FloatVector extends AbstractVector { FloatVector selectFromTemplate(FloatVector v, Class masktype, M m) { m.check(masktype, this); - return (FloatVector)VectorSupport.selectFromOp(getClass(), masktype, float.class, + return (FloatVector)VectorSupport.selectFromOp(getClass(), masktype, laneTypeOrdinal(), length(), this, v, m, (v1, v2, _m) -> v2.rearrange(v1.toShuffle(), _m)); @@ -2475,7 +2479,7 @@ public abstract class FloatVector extends AbstractVector { /*package-private*/ @ForceInline final FloatVector selectFromTemplate(FloatVector v1, FloatVector v2) { - return VectorSupport.selectFromTwoVectorOp(getClass(), float.class, length(), this, v1, v2, + return VectorSupport.selectFromTwoVectorOp(getClass(), laneTypeOrdinal(), length(), this, v1, v2, (vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)); } @@ -2681,7 +2685,7 @@ public abstract class FloatVector extends AbstractVector { } int opc = opCode(op); return fromBits(VectorSupport.reductionCoerced( - opc, getClass(), maskClass, float.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, m, REDUCE_IMPL.find(op, opc, FloatVector::reductionOperations))); } @@ -2699,7 +2703,7 @@ public abstract class FloatVector extends AbstractVector { } int opc = opCode(op); return fromBits(VectorSupport.reductionCoerced( - opc, getClass(), null, float.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, null, REDUCE_IMPL.find(op, opc, FloatVector::reductionOperations))); } @@ -2942,7 +2946,7 @@ public abstract class FloatVector extends AbstractVector { vix = VectorIntrinsics.checkIndex(vix, a.length); return VectorSupport.loadWithMap( - vectorType, null, float.class, vsp.laneCount(), + vectorType, null, LANE_TYPE_ORDINAL, vsp.laneCount(), isp.vectorType(), isp.length(), a, ARRAY_BASE, vix, null, null, null, null, a, offset, indexMap, mapOffset, vsp, @@ -3125,7 +3129,7 @@ public abstract class FloatVector extends AbstractVector { offset = checkFromIndexSize(offset, length(), a.length); FloatSpecies vsp = vspecies(); VectorSupport.store( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, this, a, offset, @@ -3214,7 +3218,7 @@ public abstract class FloatVector extends AbstractVector { vix = VectorIntrinsics.checkIndex(vix, a.length); VectorSupport.storeWithMap( - vsp.vectorType(), null, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), null, LANE_TYPE_ORDINAL, vsp.laneCount(), isp.vectorType(), isp.length(), a, arrayAddress(a, 0), vix, this, null, @@ -3341,7 +3345,7 @@ public abstract class FloatVector extends AbstractVector { FloatVector fromArray0Template(float[] a, int offset) { FloatSpecies vsp = vspecies(); return VectorSupport.load( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, a, offset, vsp, (arr, off, s) -> s.ldOp(arr, (int) off, @@ -3358,7 +3362,7 @@ public abstract class FloatVector extends AbstractVector { m.check(species()); FloatSpecies vsp = vspecies(); return VectorSupport.loadMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, m, offsetInRange, a, offset, vsp, (arr, off, s, vm) -> s.ldOp(arr, (int) off, vm, @@ -3391,7 +3395,7 @@ public abstract class FloatVector extends AbstractVector { vix = VectorIntrinsics.checkIndex(vix, a.length); return VectorSupport.loadWithMap( - vectorType, maskClass, float.class, vsp.laneCount(), + vectorType, maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), isp.vectorType(), isp.length(), a, ARRAY_BASE, vix, null, null, null, m, a, offset, indexMap, mapOffset, vsp, @@ -3408,7 +3412,7 @@ public abstract class FloatVector extends AbstractVector { FloatVector fromMemorySegment0Template(MemorySegment ms, long offset) { FloatSpecies vsp = vspecies(); return ScopedMemoryAccess.loadFromMemorySegment( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), (AbstractMemorySegmentImpl) ms, offset, vsp, (msp, off, s) -> { return s.ldLongOp((MemorySegment) msp, off, FloatVector::memorySegmentGet); @@ -3424,7 +3428,7 @@ public abstract class FloatVector extends AbstractVector { FloatSpecies vsp = vspecies(); m.check(vsp); return ScopedMemoryAccess.loadFromMemorySegmentMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), (AbstractMemorySegmentImpl) ms, offset, m, vsp, offsetInRange, (msp, off, s, vm) -> { return s.ldLongOp((MemorySegment) msp, off, vm, FloatVector::memorySegmentGet); @@ -3442,7 +3446,7 @@ public abstract class FloatVector extends AbstractVector { void intoArray0Template(float[] a, int offset) { FloatSpecies vsp = vspecies(); VectorSupport.store( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, this, a, offset, (arr, off, v) @@ -3459,7 +3463,7 @@ public abstract class FloatVector extends AbstractVector { m.check(species()); FloatSpecies vsp = vspecies(); VectorSupport.storeMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, this, m, a, offset, (arr, off, v, vm) @@ -3488,7 +3492,7 @@ public abstract class FloatVector extends AbstractVector { vix = VectorIntrinsics.checkIndex(vix, a.length); VectorSupport.storeWithMap( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), isp.vectorType(), isp.length(), a, arrayAddress(a, 0), vix, this, m, @@ -3507,7 +3511,7 @@ public abstract class FloatVector extends AbstractVector { void intoMemorySegment0(MemorySegment ms, long offset) { FloatSpecies vsp = vspecies(); ScopedMemoryAccess.storeIntoMemorySegment( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), this, (AbstractMemorySegmentImpl) ms, offset, (msp, off, v) -> { @@ -3524,7 +3528,7 @@ public abstract class FloatVector extends AbstractVector { FloatSpecies vsp = vspecies(); m.check(vsp); ScopedMemoryAccess.storeIntoMemorySegmentMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), this, m, (AbstractMemorySegmentImpl) ms, offset, (msp, off, v, vm) -> { @@ -3562,6 +3566,18 @@ public abstract class FloatVector extends AbstractVector { return this; } + @Override + @ForceInline + final + FloatVector swapIfNeeded(AbstractSpecies srcSpecies) { + int subLanesPerSrc = subLanesToSwap(srcSpecies); + if (subLanesPerSrc < 0) { + return this; + } + VectorShuffle shuffle = normalizeSubLanesForSpecies(this.vspecies(), subLanesPerSrc); + return (FloatVector) this.rearrange(shuffle); + } + static final int ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_FLOAT_INDEX_SCALE); static final long ARRAY_BASE = @@ -3728,7 +3744,7 @@ public abstract class FloatVector extends AbstractVector { final FloatVector broadcastBits(long bits) { return (FloatVector) VectorSupport.fromBitsCoerced( - vectorType, float.class, laneCount, + vectorType, laneTypeOrdinal(), laneCount, bits, MODE_BROADCAST, this, (bits_, s_) -> s_.rvOp(i -> bits_)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int128Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int128Vector.java index edf45b8772a..17e93dbd06a 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int128Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int128Vector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class Int128Vector extends IntVector { return (int[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -529,7 +536,7 @@ final class Int128Vector extends IntVector { @ForceInline public int laneHelper(int i) { return (int) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { int[] vecarr = vec.vec(); @@ -552,7 +559,7 @@ final class Int128Vector extends IntVector { @ForceInline public Int128Vector withLaneHelper(int i, int e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)e, (v, ix, bits) -> { int[] res = v.vec().clone(); @@ -656,8 +663,8 @@ final class Int128Vector extends IntVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -667,7 +674,7 @@ final class Int128Vector extends IntVector { /*package-private*/ Int128Mask indexPartiallyInUpperRange(long offset, long limit) { return (Int128Mask) VectorSupport.indexPartiallyInUpperRange( - Int128Mask.class, int.class, VLENGTH, offset, limit, + Int128Mask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (Int128Mask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -683,7 +690,7 @@ final class Int128Vector extends IntVector { @ForceInline public Int128Mask compress() { return (Int128Mask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - Int128Vector.class, Int128Mask.class, ETYPE, VLENGTH, null, this, + Int128Vector.class, Int128Mask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -695,7 +702,7 @@ final class Int128Vector extends IntVector { public Int128Mask and(VectorMask mask) { Objects.requireNonNull(mask); Int128Mask m = (Int128Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, Int128Mask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, Int128Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -705,7 +712,7 @@ final class Int128Vector extends IntVector { public Int128Mask or(VectorMask mask) { Objects.requireNonNull(mask); Int128Mask m = (Int128Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, Int128Mask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, Int128Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -715,7 +722,7 @@ final class Int128Vector extends IntVector { public Int128Mask xor(VectorMask mask) { Objects.requireNonNull(mask); Int128Mask m = (Int128Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, Int128Mask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, Int128Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -725,21 +732,21 @@ final class Int128Vector extends IntVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Int128Mask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Int128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Int128Mask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Int128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Int128Mask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Int128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -749,7 +756,7 @@ final class Int128Vector extends IntVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Int128Mask.class, int.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Int128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -759,7 +766,7 @@ final class Int128Vector extends IntVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(Int128Mask.class, int.class, VLENGTH, + return VectorSupport.extract(Int128Mask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -768,7 +775,7 @@ final class Int128Vector extends IntVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, Int128Mask.class, int.class, VLENGTH, + return VectorSupport.test(BT_ne, Int128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((Int128Mask)m).getBits())); } @@ -776,7 +783,7 @@ final class Int128Vector extends IntVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, Int128Mask.class, int.class, VLENGTH, + return VectorSupport.test(BT_overflow, Int128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((Int128Mask)m).getBits())); } @@ -784,7 +791,7 @@ final class Int128Vector extends IntVector { @ForceInline /*package-private*/ static Int128Mask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(Int128Mask.class, int.class, VLENGTH, + return VectorSupport.fromBitsCoerced(Int128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int256Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int256Vector.java index bb86ede05e1..f9700fbfd71 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int256Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int256Vector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class Int256Vector extends IntVector { return (int[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -533,7 +540,7 @@ final class Int256Vector extends IntVector { @ForceInline public int laneHelper(int i) { return (int) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { int[] vecarr = vec.vec(); @@ -560,7 +567,7 @@ final class Int256Vector extends IntVector { @ForceInline public Int256Vector withLaneHelper(int i, int e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)e, (v, ix, bits) -> { int[] res = v.vec().clone(); @@ -664,8 +671,8 @@ final class Int256Vector extends IntVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -675,7 +682,7 @@ final class Int256Vector extends IntVector { /*package-private*/ Int256Mask indexPartiallyInUpperRange(long offset, long limit) { return (Int256Mask) VectorSupport.indexPartiallyInUpperRange( - Int256Mask.class, int.class, VLENGTH, offset, limit, + Int256Mask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (Int256Mask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -691,7 +698,7 @@ final class Int256Vector extends IntVector { @ForceInline public Int256Mask compress() { return (Int256Mask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - Int256Vector.class, Int256Mask.class, ETYPE, VLENGTH, null, this, + Int256Vector.class, Int256Mask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -703,7 +710,7 @@ final class Int256Vector extends IntVector { public Int256Mask and(VectorMask mask) { Objects.requireNonNull(mask); Int256Mask m = (Int256Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, Int256Mask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, Int256Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -713,7 +720,7 @@ final class Int256Vector extends IntVector { public Int256Mask or(VectorMask mask) { Objects.requireNonNull(mask); Int256Mask m = (Int256Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, Int256Mask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, Int256Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -723,7 +730,7 @@ final class Int256Vector extends IntVector { public Int256Mask xor(VectorMask mask) { Objects.requireNonNull(mask); Int256Mask m = (Int256Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, Int256Mask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, Int256Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -733,21 +740,21 @@ final class Int256Vector extends IntVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Int256Mask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Int256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Int256Mask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Int256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Int256Mask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Int256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -757,7 +764,7 @@ final class Int256Vector extends IntVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Int256Mask.class, int.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Int256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -767,7 +774,7 @@ final class Int256Vector extends IntVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(Int256Mask.class, int.class, VLENGTH, + return VectorSupport.extract(Int256Mask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -776,7 +783,7 @@ final class Int256Vector extends IntVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, Int256Mask.class, int.class, VLENGTH, + return VectorSupport.test(BT_ne, Int256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((Int256Mask)m).getBits())); } @@ -784,7 +791,7 @@ final class Int256Vector extends IntVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, Int256Mask.class, int.class, VLENGTH, + return VectorSupport.test(BT_overflow, Int256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((Int256Mask)m).getBits())); } @@ -792,7 +799,7 @@ final class Int256Vector extends IntVector { @ForceInline /*package-private*/ static Int256Mask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(Int256Mask.class, int.class, VLENGTH, + return VectorSupport.fromBitsCoerced(Int256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int512Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int512Vector.java index 16d3b673da0..2e2ee7eac05 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int512Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int512Vector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class Int512Vector extends IntVector { return (int[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -541,7 +548,7 @@ final class Int512Vector extends IntVector { @ForceInline public int laneHelper(int i) { return (int) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { int[] vecarr = vec.vec(); @@ -576,7 +583,7 @@ final class Int512Vector extends IntVector { @ForceInline public Int512Vector withLaneHelper(int i, int e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)e, (v, ix, bits) -> { int[] res = v.vec().clone(); @@ -680,8 +687,8 @@ final class Int512Vector extends IntVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -691,7 +698,7 @@ final class Int512Vector extends IntVector { /*package-private*/ Int512Mask indexPartiallyInUpperRange(long offset, long limit) { return (Int512Mask) VectorSupport.indexPartiallyInUpperRange( - Int512Mask.class, int.class, VLENGTH, offset, limit, + Int512Mask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (Int512Mask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -707,7 +714,7 @@ final class Int512Vector extends IntVector { @ForceInline public Int512Mask compress() { return (Int512Mask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - Int512Vector.class, Int512Mask.class, ETYPE, VLENGTH, null, this, + Int512Vector.class, Int512Mask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -719,7 +726,7 @@ final class Int512Vector extends IntVector { public Int512Mask and(VectorMask mask) { Objects.requireNonNull(mask); Int512Mask m = (Int512Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, Int512Mask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, Int512Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -729,7 +736,7 @@ final class Int512Vector extends IntVector { public Int512Mask or(VectorMask mask) { Objects.requireNonNull(mask); Int512Mask m = (Int512Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, Int512Mask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, Int512Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -739,7 +746,7 @@ final class Int512Vector extends IntVector { public Int512Mask xor(VectorMask mask) { Objects.requireNonNull(mask); Int512Mask m = (Int512Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, Int512Mask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, Int512Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -749,21 +756,21 @@ final class Int512Vector extends IntVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Int512Mask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Int512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Int512Mask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Int512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Int512Mask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Int512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -773,7 +780,7 @@ final class Int512Vector extends IntVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Int512Mask.class, int.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Int512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -783,7 +790,7 @@ final class Int512Vector extends IntVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(Int512Mask.class, int.class, VLENGTH, + return VectorSupport.extract(Int512Mask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -792,7 +799,7 @@ final class Int512Vector extends IntVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, Int512Mask.class, int.class, VLENGTH, + return VectorSupport.test(BT_ne, Int512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((Int512Mask)m).getBits())); } @@ -800,7 +807,7 @@ final class Int512Vector extends IntVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, Int512Mask.class, int.class, VLENGTH, + return VectorSupport.test(BT_overflow, Int512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((Int512Mask)m).getBits())); } @@ -808,7 +815,7 @@ final class Int512Vector extends IntVector { @ForceInline /*package-private*/ static Int512Mask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(Int512Mask.class, int.class, VLENGTH, + return VectorSupport.fromBitsCoerced(Int512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int64Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int64Vector.java index d55364a8d67..8338799c61a 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int64Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int64Vector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class Int64Vector extends IntVector { return (int[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -527,7 +534,7 @@ final class Int64Vector extends IntVector { @ForceInline public int laneHelper(int i) { return (int) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { int[] vecarr = vec.vec(); @@ -548,7 +555,7 @@ final class Int64Vector extends IntVector { @ForceInline public Int64Vector withLaneHelper(int i, int e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)e, (v, ix, bits) -> { int[] res = v.vec().clone(); @@ -652,8 +659,8 @@ final class Int64Vector extends IntVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -663,7 +670,7 @@ final class Int64Vector extends IntVector { /*package-private*/ Int64Mask indexPartiallyInUpperRange(long offset, long limit) { return (Int64Mask) VectorSupport.indexPartiallyInUpperRange( - Int64Mask.class, int.class, VLENGTH, offset, limit, + Int64Mask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (Int64Mask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -679,7 +686,7 @@ final class Int64Vector extends IntVector { @ForceInline public Int64Mask compress() { return (Int64Mask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - Int64Vector.class, Int64Mask.class, ETYPE, VLENGTH, null, this, + Int64Vector.class, Int64Mask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -691,7 +698,7 @@ final class Int64Vector extends IntVector { public Int64Mask and(VectorMask mask) { Objects.requireNonNull(mask); Int64Mask m = (Int64Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, Int64Mask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, Int64Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -701,7 +708,7 @@ final class Int64Vector extends IntVector { public Int64Mask or(VectorMask mask) { Objects.requireNonNull(mask); Int64Mask m = (Int64Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, Int64Mask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, Int64Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -711,7 +718,7 @@ final class Int64Vector extends IntVector { public Int64Mask xor(VectorMask mask) { Objects.requireNonNull(mask); Int64Mask m = (Int64Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, Int64Mask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, Int64Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -721,21 +728,21 @@ final class Int64Vector extends IntVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Int64Mask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Int64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Int64Mask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Int64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Int64Mask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Int64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -745,7 +752,7 @@ final class Int64Vector extends IntVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Int64Mask.class, int.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Int64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -755,7 +762,7 @@ final class Int64Vector extends IntVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(Int64Mask.class, int.class, VLENGTH, + return VectorSupport.extract(Int64Mask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -764,7 +771,7 @@ final class Int64Vector extends IntVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, Int64Mask.class, int.class, VLENGTH, + return VectorSupport.test(BT_ne, Int64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((Int64Mask)m).getBits())); } @@ -772,7 +779,7 @@ final class Int64Vector extends IntVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, Int64Mask.class, int.class, VLENGTH, + return VectorSupport.test(BT_overflow, Int64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((Int64Mask)m).getBits())); } @@ -780,7 +787,7 @@ final class Int64Vector extends IntVector { @ForceInline /*package-private*/ static Int64Mask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(Int64Mask.class, int.class, VLENGTH, + return VectorSupport.fromBitsCoerced(Int64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntMaxVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntMaxVector.java index 0a1cd45eb93..177890e765c 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntMaxVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntMaxVector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class IntMaxVector extends IntVector { return (int[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -526,7 +533,7 @@ final class IntMaxVector extends IntVector { @ForceInline public int laneHelper(int i) { return (int) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { int[] vecarr = vec.vec(); @@ -546,7 +553,7 @@ final class IntMaxVector extends IntVector { @ForceInline public IntMaxVector withLaneHelper(int i, int e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)e, (v, ix, bits) -> { int[] res = v.vec().clone(); @@ -650,8 +657,8 @@ final class IntMaxVector extends IntVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -661,7 +668,7 @@ final class IntMaxVector extends IntVector { /*package-private*/ IntMaxMask indexPartiallyInUpperRange(long offset, long limit) { return (IntMaxMask) VectorSupport.indexPartiallyInUpperRange( - IntMaxMask.class, int.class, VLENGTH, offset, limit, + IntMaxMask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (IntMaxMask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -677,7 +684,7 @@ final class IntMaxVector extends IntVector { @ForceInline public IntMaxMask compress() { return (IntMaxMask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - IntMaxVector.class, IntMaxMask.class, ETYPE, VLENGTH, null, this, + IntMaxVector.class, IntMaxMask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -689,7 +696,7 @@ final class IntMaxVector extends IntVector { public IntMaxMask and(VectorMask mask) { Objects.requireNonNull(mask); IntMaxMask m = (IntMaxMask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, IntMaxMask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, IntMaxMask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -699,7 +706,7 @@ final class IntMaxVector extends IntVector { public IntMaxMask or(VectorMask mask) { Objects.requireNonNull(mask); IntMaxMask m = (IntMaxMask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, IntMaxMask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, IntMaxMask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -709,7 +716,7 @@ final class IntMaxVector extends IntVector { public IntMaxMask xor(VectorMask mask) { Objects.requireNonNull(mask); IntMaxMask m = (IntMaxMask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, IntMaxMask.class, null, int.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, IntMaxMask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -719,21 +726,21 @@ final class IntMaxVector extends IntVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, IntMaxMask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, IntMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, IntMaxMask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, IntMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, IntMaxMask.class, int.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, IntMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -743,7 +750,7 @@ final class IntMaxVector extends IntVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, IntMaxMask.class, int.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, IntMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -753,7 +760,7 @@ final class IntMaxVector extends IntVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(IntMaxMask.class, int.class, VLENGTH, + return VectorSupport.extract(IntMaxMask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -762,7 +769,7 @@ final class IntMaxVector extends IntVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, IntMaxMask.class, int.class, VLENGTH, + return VectorSupport.test(BT_ne, IntMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((IntMaxMask)m).getBits())); } @@ -770,7 +777,7 @@ final class IntMaxVector extends IntVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, IntMaxMask.class, int.class, VLENGTH, + return VectorSupport.test(BT_overflow, IntMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((IntMaxMask)m).getBits())); } @@ -778,7 +785,7 @@ final class IntMaxVector extends IntVector { @ForceInline /*package-private*/ static IntMaxMask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(IntMaxMask.class, int.class, VLENGTH, + return VectorSupport.fromBitsCoerced(IntMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntVector.java index 23e703dcada..412ac8e59b2 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntVector.java @@ -59,6 +59,10 @@ public abstract class IntVector extends AbstractVector { static final ValueLayout.OfInt ELEMENT_LAYOUT = ValueLayout.JAVA_INT.withByteAlignment(1); + static final int LANE_TYPE_ORDINAL = LT_INT; + + static final int LANEBITS_TYPE_ORDINAL = LT_INT; + @ForceInline static int opCode(Operator op) { return VectorOperators.opCode(op, VO_OPCODE_VALID, FORBID_OPCODE_KIND); @@ -573,7 +577,7 @@ public abstract class IntVector extends AbstractVector { @ForceInline public static IntVector zero(VectorSpecies species) { IntSpecies vsp = (IntSpecies) species; - return VectorSupport.fromBitsCoerced(vsp.vectorType(), int.class, species.length(), + return VectorSupport.fromBitsCoerced(vsp.vectorType(), LANE_TYPE_ORDINAL, species.length(), 0, MODE_BROADCAST, vsp, ((bits_, s_) -> s_.rvOp(i -> bits_))); } @@ -695,7 +699,7 @@ public abstract class IntVector extends AbstractVector { } int opc = opCode(op); return VectorSupport.unaryOp( - opc, getClass(), null, int.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, null, UN_IMPL.find(op, opc, IntVector::unaryOperations)); } @@ -723,7 +727,7 @@ public abstract class IntVector extends AbstractVector { } int opc = opCode(op); return VectorSupport.unaryOp( - opc, getClass(), maskClass, int.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, m, UN_IMPL.find(op, opc, IntVector::unaryOperations)); } @@ -796,7 +800,7 @@ public abstract class IntVector extends AbstractVector { int opc = opCode(op); return VectorSupport.binaryOp( - opc, getClass(), null, int.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, that, null, BIN_IMPL.find(op, opc, IntVector::binaryOperations)); } @@ -847,7 +851,7 @@ public abstract class IntVector extends AbstractVector { int opc = opCode(op); return VectorSupport.binaryOp( - opc, getClass(), maskClass, int.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, that, m, BIN_IMPL.find(op, opc, IntVector::binaryOperations)); } @@ -1038,7 +1042,7 @@ public abstract class IntVector extends AbstractVector { e &= SHIFT_MASK; int opc = opCode(op); return VectorSupport.broadcastInt( - opc, getClass(), null, int.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, e, null, BIN_INT_IMPL.find(op, opc, IntVector::broadcastIntOperations)); } @@ -1059,7 +1063,7 @@ public abstract class IntVector extends AbstractVector { e &= SHIFT_MASK; int opc = opCode(op); return VectorSupport.broadcastInt( - opc, getClass(), maskClass, int.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, e, m, BIN_INT_IMPL.find(op, opc, IntVector::broadcastIntOperations)); } @@ -1135,7 +1139,7 @@ public abstract class IntVector extends AbstractVector { } int opc = opCode(op); return VectorSupport.ternaryOp( - opc, getClass(), null, int.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, that, tother, null, TERN_IMPL.find(op, opc, IntVector::ternaryOperations)); } @@ -1175,7 +1179,7 @@ public abstract class IntVector extends AbstractVector { } int opc = opCode(op); return VectorSupport.ternaryOp( - opc, getClass(), maskClass, int.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, that, tother, m, TERN_IMPL.find(op, opc, IntVector::ternaryOperations)); } @@ -2055,7 +2059,7 @@ public abstract class IntVector extends AbstractVector { that.check(this); int opc = opCode(op); return VectorSupport.compare( - opc, getClass(), maskType, int.class, length(), + opc, getClass(), maskType, laneTypeOrdinal(), length(), this, that, null, (cond, v0, v1, m1) -> { AbstractMask m @@ -2077,7 +2081,7 @@ public abstract class IntVector extends AbstractVector { m.check(maskType, this); int opc = opCode(op); return VectorSupport.compare( - opc, getClass(), maskType, int.class, length(), + opc, getClass(), maskType, laneTypeOrdinal(), length(), this, that, m, (cond, v0, v1, m1) -> { AbstractMask cmpM @@ -2208,7 +2212,7 @@ public abstract class IntVector extends AbstractVector { blendTemplate(Class maskType, IntVector v, M m) { v.check(this); return VectorSupport.blend( - getClass(), maskType, int.class, length(), + getClass(), maskType, laneTypeOrdinal(), length(), this, v, m, (v0, v1, m_) -> v0.bOp(v1, m_, (i, a, b) -> b)); } @@ -2225,7 +2229,7 @@ public abstract class IntVector extends AbstractVector { // make sure VLENGTH*scale doesn't overflow: vsp.checkScale(scale); return VectorSupport.indexVector( - getClass(), int.class, length(), + getClass(), laneTypeOrdinal(), length(), this, scale, vsp, (v, scale_, s) -> { @@ -2417,7 +2421,7 @@ public abstract class IntVector extends AbstractVector { IntVector rearrangeTemplate(Class shuffletype, S shuffle) { Objects.requireNonNull(shuffle); return VectorSupport.rearrangeOp( - getClass(), shuffletype, null, int.class, length(), + getClass(), shuffletype, null, laneTypeOrdinal(), length(), this, shuffle, null, (v1, s_, m_) -> v1.uOp((i, a) -> { int ei = Integer.remainderUnsigned(s_.laneSource(i), v1.length()); @@ -2444,7 +2448,7 @@ public abstract class IntVector extends AbstractVector { Objects.requireNonNull(shuffle); m.check(masktype, this); return VectorSupport.rearrangeOp( - getClass(), shuffletype, masktype, int.class, length(), + getClass(), shuffletype, masktype, laneTypeOrdinal(), length(), this, shuffle, m, (v1, s_, m_) -> v1.uOp((i, a) -> { int ei = Integer.remainderUnsigned(s_.laneSource(i), v1.length()); @@ -2470,7 +2474,7 @@ public abstract class IntVector extends AbstractVector { VectorMask valid = shuffle.laneIsValid(); IntVector r0 = VectorSupport.rearrangeOp( - getClass(), shuffletype, null, int.class, length(), + getClass(), shuffletype, null, laneTypeOrdinal(), length(), this, shuffle, null, (v0, s_, m_) -> v0.uOp((i, a) -> { int ei = Integer.remainderUnsigned(s_.laneSource(i), v0.length()); @@ -2478,7 +2482,7 @@ public abstract class IntVector extends AbstractVector { })); IntVector r1 = VectorSupport.rearrangeOp( - getClass(), shuffletype, null, int.class, length(), + getClass(), shuffletype, null, laneTypeOrdinal(), length(), v, shuffle, null, (v1, s_, m_) -> v1.uOp((i, a) -> { int ei = Integer.remainderUnsigned(s_.laneSource(i), v1.length()); @@ -2528,7 +2532,7 @@ public abstract class IntVector extends AbstractVector { IntVector compressTemplate(Class masktype, M m) { m.check(masktype, this); return (IntVector) VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_COMPRESS, getClass(), masktype, - int.class, length(), this, m, + laneTypeOrdinal(), length(), this, m, (v1, m1) -> compressHelper(v1, m1)); } @@ -2547,7 +2551,7 @@ public abstract class IntVector extends AbstractVector { IntVector expandTemplate(Class masktype, M m) { m.check(masktype, this); return (IntVector) VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_EXPAND, getClass(), masktype, - int.class, length(), this, m, + laneTypeOrdinal(), length(), this, m, (v1, m1) -> expandHelper(v1, m1)); } @@ -2562,7 +2566,7 @@ public abstract class IntVector extends AbstractVector { /*package-private*/ @ForceInline final IntVector selectFromTemplate(IntVector v) { - return (IntVector)VectorSupport.selectFromOp(getClass(), null, int.class, + return (IntVector)VectorSupport.selectFromOp(getClass(), null, laneTypeOrdinal(), length(), this, v, null, (v1, v2, _m) -> v2.rearrange(v1.toShuffle())); @@ -2582,7 +2586,7 @@ public abstract class IntVector extends AbstractVector { IntVector selectFromTemplate(IntVector v, Class masktype, M m) { m.check(masktype, this); - return (IntVector)VectorSupport.selectFromOp(getClass(), masktype, int.class, + return (IntVector)VectorSupport.selectFromOp(getClass(), masktype, laneTypeOrdinal(), length(), this, v, m, (v1, v2, _m) -> v2.rearrange(v1.toShuffle(), _m)); @@ -2600,7 +2604,7 @@ public abstract class IntVector extends AbstractVector { /*package-private*/ @ForceInline final IntVector selectFromTemplate(IntVector v1, IntVector v2) { - return VectorSupport.selectFromTwoVectorOp(getClass(), int.class, length(), this, v1, v2, + return VectorSupport.selectFromTwoVectorOp(getClass(), laneTypeOrdinal(), length(), this, v1, v2, (vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)); } @@ -2820,7 +2824,7 @@ public abstract class IntVector extends AbstractVector { } int opc = opCode(op); return fromBits(VectorSupport.reductionCoerced( - opc, getClass(), maskClass, int.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, m, REDUCE_IMPL.find(op, opc, IntVector::reductionOperations))); } @@ -2838,7 +2842,7 @@ public abstract class IntVector extends AbstractVector { } int opc = opCode(op); return fromBits(VectorSupport.reductionCoerced( - opc, getClass(), null, int.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, null, REDUCE_IMPL.find(op, opc, IntVector::reductionOperations))); } @@ -3100,7 +3104,7 @@ public abstract class IntVector extends AbstractVector { vix = VectorIntrinsics.checkIndex(vix, a.length); return VectorSupport.loadWithMap( - vectorType, null, int.class, vsp.laneCount(), + vectorType, null, LANE_TYPE_ORDINAL, vsp.laneCount(), isp.vectorType(), isp.length(), a, ARRAY_BASE, vix, null, null, null, null, a, offset, indexMap, mapOffset, vsp, @@ -3283,7 +3287,7 @@ public abstract class IntVector extends AbstractVector { offset = checkFromIndexSize(offset, length(), a.length); IntSpecies vsp = vspecies(); VectorSupport.store( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, this, a, offset, @@ -3372,7 +3376,7 @@ public abstract class IntVector extends AbstractVector { vix = VectorIntrinsics.checkIndex(vix, a.length); VectorSupport.storeWithMap( - vsp.vectorType(), null, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), null, LANE_TYPE_ORDINAL, vsp.laneCount(), isp.vectorType(), isp.length(), a, arrayAddress(a, 0), vix, this, null, @@ -3499,7 +3503,7 @@ public abstract class IntVector extends AbstractVector { IntVector fromArray0Template(int[] a, int offset) { IntSpecies vsp = vspecies(); return VectorSupport.load( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, a, offset, vsp, (arr, off, s) -> s.ldOp(arr, (int) off, @@ -3516,7 +3520,7 @@ public abstract class IntVector extends AbstractVector { m.check(species()); IntSpecies vsp = vspecies(); return VectorSupport.loadMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, m, offsetInRange, a, offset, vsp, (arr, off, s, vm) -> s.ldOp(arr, (int) off, vm, @@ -3549,7 +3553,7 @@ public abstract class IntVector extends AbstractVector { vix = VectorIntrinsics.checkIndex(vix, a.length); return VectorSupport.loadWithMap( - vectorType, maskClass, int.class, vsp.laneCount(), + vectorType, maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), isp.vectorType(), isp.length(), a, ARRAY_BASE, vix, null, null, null, m, a, offset, indexMap, mapOffset, vsp, @@ -3566,7 +3570,7 @@ public abstract class IntVector extends AbstractVector { IntVector fromMemorySegment0Template(MemorySegment ms, long offset) { IntSpecies vsp = vspecies(); return ScopedMemoryAccess.loadFromMemorySegment( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), (AbstractMemorySegmentImpl) ms, offset, vsp, (msp, off, s) -> { return s.ldLongOp((MemorySegment) msp, off, IntVector::memorySegmentGet); @@ -3582,7 +3586,7 @@ public abstract class IntVector extends AbstractVector { IntSpecies vsp = vspecies(); m.check(vsp); return ScopedMemoryAccess.loadFromMemorySegmentMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), (AbstractMemorySegmentImpl) ms, offset, m, vsp, offsetInRange, (msp, off, s, vm) -> { return s.ldLongOp((MemorySegment) msp, off, vm, IntVector::memorySegmentGet); @@ -3600,7 +3604,7 @@ public abstract class IntVector extends AbstractVector { void intoArray0Template(int[] a, int offset) { IntSpecies vsp = vspecies(); VectorSupport.store( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, this, a, offset, (arr, off, v) @@ -3617,7 +3621,7 @@ public abstract class IntVector extends AbstractVector { m.check(species()); IntSpecies vsp = vspecies(); VectorSupport.storeMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, this, m, a, offset, (arr, off, v, vm) @@ -3646,7 +3650,7 @@ public abstract class IntVector extends AbstractVector { vix = VectorIntrinsics.checkIndex(vix, a.length); VectorSupport.storeWithMap( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), isp.vectorType(), isp.length(), a, arrayAddress(a, 0), vix, this, m, @@ -3665,7 +3669,7 @@ public abstract class IntVector extends AbstractVector { void intoMemorySegment0(MemorySegment ms, long offset) { IntSpecies vsp = vspecies(); ScopedMemoryAccess.storeIntoMemorySegment( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), this, (AbstractMemorySegmentImpl) ms, offset, (msp, off, v) -> { @@ -3682,7 +3686,7 @@ public abstract class IntVector extends AbstractVector { IntSpecies vsp = vspecies(); m.check(vsp); ScopedMemoryAccess.storeIntoMemorySegmentMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), this, m, (AbstractMemorySegmentImpl) ms, offset, (msp, off, v, vm) -> { @@ -3720,6 +3724,18 @@ public abstract class IntVector extends AbstractVector { return this; } + @Override + @ForceInline + final + IntVector swapIfNeeded(AbstractSpecies srcSpecies) { + int subLanesPerSrc = subLanesToSwap(srcSpecies); + if (subLanesPerSrc < 0) { + return this; + } + VectorShuffle shuffle = normalizeSubLanesForSpecies(this.vspecies(), subLanesPerSrc); + return (IntVector) this.rearrange(shuffle); + } + static final int ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_INT_INDEX_SCALE); static final long ARRAY_BASE = @@ -3886,7 +3902,7 @@ public abstract class IntVector extends AbstractVector { final IntVector broadcastBits(long bits) { return (IntVector) VectorSupport.fromBitsCoerced( - vectorType, int.class, laneCount, + vectorType, laneTypeOrdinal(), laneCount, bits, MODE_BROADCAST, this, (bits_, s_) -> s_.rvOp(i -> bits_)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LaneType.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LaneType.java index 53fa773555f..59844eabb57 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LaneType.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LaneType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2026, Oracle and/or its affiliates. All rights reserved. * 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,20 +35,19 @@ import static jdk.incubator.vector.VectorIntrinsics.*; * It caches all sorts of goodies that we can't put on java.lang.Class. */ enum LaneType { - FLOAT(float.class, Float.class, float[].class, 'F', 24, Float.SIZE, T_FLOAT), - DOUBLE(double.class, Double.class, double[].class, 'F', 53, Double.SIZE, T_DOUBLE), - BYTE(byte.class, Byte.class, byte[].class, 'I', -1, Byte.SIZE, T_BYTE), - SHORT(short.class, Short.class, short[].class, 'I', -1, Short.SIZE, T_SHORT), - INT(int.class, Integer.class, int[].class, 'I', -1, Integer.SIZE, T_INT), - LONG(long.class, Long.class, long[].class, 'I', -1, Long.SIZE, T_LONG); + FLOAT(float.class, Float.class, float[].class, 'F', 24, Float.SIZE), + DOUBLE(double.class, Double.class, double[].class, 'F', 53, Double.SIZE), + BYTE(byte.class, Byte.class, byte[].class, 'I', -1, Byte.SIZE), + SHORT(short.class, Short.class, short[].class, 'I', -1, Short.SIZE), + INT(int.class, Integer.class, int[].class, 'I', -1, Integer.SIZE), + LONG(long.class, Long.class, long[].class, 'I', -1, Long.SIZE); LaneType(Class elementType, Class genericElementType, Class arrayType, char elementKind, int elementPrecision, - int elementSize, - int basicType) { + int elementSize) { if (elementPrecision <= 0) elementPrecision += elementSize; this.elementType = elementType; @@ -67,12 +66,6 @@ enum LaneType { // report that condition also. this.typeChar = genericElementType.getSimpleName().charAt(0); assert("FDBSIL".indexOf(typeChar) == ordinal()) : this; - // Same as in JVMS, org.objectweb.asm.Opcodes, etc.: - this.basicType = basicType; - assert(basicType == - ( (elementSizeLog2 - /*lg(Byte.SIZE)*/ 3) - | (elementKind == 'F' ? 4 : 8))) : this; - assert("....zcFDBSILoav..".charAt(basicType) == typeChar); } final Class elementType; @@ -85,7 +78,6 @@ enum LaneType { final int switchKey; // 1+ordinal(), which is non-zero final String printName; final char typeChar; // one of "BSILFD" - final int basicType; // lg(size/8) | (kind=='F'?4:kind=='I'?8) private @Stable LaneType asIntegral; private @Stable LaneType asFloating; @@ -194,8 +186,8 @@ enum LaneType { /*package-private*/ @ForceInline - static LaneType ofBasicType(int bt) { - return ENUM_FROM_BT[bt].check(); + static LaneType ofLaneTypeOrdinal(int lo) { + return ENUM_VALUES[lo].check(); } /*package-private*/ @@ -207,13 +199,11 @@ enum LaneType { @Stable private static final LaneType[] ENUM_VALUES; @Stable private static final LaneType[] ENUM_FROM_SK; @Stable private static final LaneType[] ENUM_FROM_C0; - @Stable private static final LaneType[] ENUM_FROM_BT; - private static final int C0_MASK = 0x0F, BT_MASK = 0x0F; + private static final int C0_MASK = 0x0F; static { LaneType[] values = values().clone(); LaneType[] valuesByKey = new LaneType[1+values.length]; LaneType[] valuesByC0 = new LaneType[C0_MASK+1]; - LaneType[] valuesByBT = new LaneType[BT_MASK+1]; for (int ord = 0; ord < values.length; ord++) { int key = 1+ord; LaneType value = values[ord]; @@ -229,8 +219,6 @@ enum LaneType { c0 &= C0_MASK; assert(valuesByC0[c0] == null); valuesByC0[c0] = value; - assert(valuesByBT[value.basicType] == null); - valuesByBT[value.basicType] = value; // set up asIntegral if (value.elementKind == 'I') { value.asIntegral = value; @@ -276,15 +264,14 @@ enum LaneType { ENUM_VALUES = values; ENUM_FROM_SK = valuesByKey; ENUM_FROM_C0 = valuesByC0; - ENUM_FROM_BT = valuesByBT; } static { - assert(ofBasicType(T_FLOAT) == FLOAT); - assert(ofBasicType(T_DOUBLE) == DOUBLE); - assert(ofBasicType(T_BYTE) == BYTE); - assert(ofBasicType(T_SHORT) == SHORT); - assert(ofBasicType(T_INT) == INT); - assert(ofBasicType(T_LONG) == LONG); + assert(ofLaneTypeOrdinal(LT_FLOAT) == FLOAT); + assert(ofLaneTypeOrdinal(LT_DOUBLE) == DOUBLE); + assert(ofLaneTypeOrdinal(LT_BYTE) == BYTE); + assert(ofLaneTypeOrdinal(LT_SHORT) == SHORT); + assert(ofLaneTypeOrdinal(LT_INT) == INT); + assert(ofLaneTypeOrdinal(LT_LONG) == LONG); } } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long128Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long128Vector.java index 5a47153837a..01d721f64fc 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long128Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long128Vector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class Long128Vector extends LongVector { return (long[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -517,7 +524,7 @@ final class Long128Vector extends LongVector { @ForceInline public long laneHelper(int i) { return (long) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { long[] vecarr = vec.vec(); @@ -538,7 +545,7 @@ final class Long128Vector extends LongVector { @ForceInline public Long128Vector withLaneHelper(int i, long e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)e, (v, ix, bits) -> { long[] res = v.vec().clone(); @@ -642,8 +649,8 @@ final class Long128Vector extends LongVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -653,7 +660,7 @@ final class Long128Vector extends LongVector { /*package-private*/ Long128Mask indexPartiallyInUpperRange(long offset, long limit) { return (Long128Mask) VectorSupport.indexPartiallyInUpperRange( - Long128Mask.class, long.class, VLENGTH, offset, limit, + Long128Mask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (Long128Mask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -669,7 +676,7 @@ final class Long128Vector extends LongVector { @ForceInline public Long128Mask compress() { return (Long128Mask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - Long128Vector.class, Long128Mask.class, ETYPE, VLENGTH, null, this, + Long128Vector.class, Long128Mask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -681,7 +688,7 @@ final class Long128Vector extends LongVector { public Long128Mask and(VectorMask mask) { Objects.requireNonNull(mask); Long128Mask m = (Long128Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, Long128Mask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, Long128Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -691,7 +698,7 @@ final class Long128Vector extends LongVector { public Long128Mask or(VectorMask mask) { Objects.requireNonNull(mask); Long128Mask m = (Long128Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, Long128Mask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, Long128Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -701,7 +708,7 @@ final class Long128Vector extends LongVector { public Long128Mask xor(VectorMask mask) { Objects.requireNonNull(mask); Long128Mask m = (Long128Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, Long128Mask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, Long128Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -711,21 +718,21 @@ final class Long128Vector extends LongVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Long128Mask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Long128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Long128Mask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Long128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Long128Mask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Long128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -735,7 +742,7 @@ final class Long128Vector extends LongVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Long128Mask.class, long.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Long128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -745,7 +752,7 @@ final class Long128Vector extends LongVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(Long128Mask.class, long.class, VLENGTH, + return VectorSupport.extract(Long128Mask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -754,7 +761,7 @@ final class Long128Vector extends LongVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, Long128Mask.class, long.class, VLENGTH, + return VectorSupport.test(BT_ne, Long128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((Long128Mask)m).getBits())); } @@ -762,7 +769,7 @@ final class Long128Vector extends LongVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, Long128Mask.class, long.class, VLENGTH, + return VectorSupport.test(BT_overflow, Long128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((Long128Mask)m).getBits())); } @@ -770,7 +777,7 @@ final class Long128Vector extends LongVector { @ForceInline /*package-private*/ static Long128Mask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(Long128Mask.class, long.class, VLENGTH, + return VectorSupport.fromBitsCoerced(Long128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long256Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long256Vector.java index 9c3ff7627cc..b3e7022771c 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long256Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long256Vector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class Long256Vector extends LongVector { return (long[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -519,7 +526,7 @@ final class Long256Vector extends LongVector { @ForceInline public long laneHelper(int i) { return (long) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { long[] vecarr = vec.vec(); @@ -542,7 +549,7 @@ final class Long256Vector extends LongVector { @ForceInline public Long256Vector withLaneHelper(int i, long e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)e, (v, ix, bits) -> { long[] res = v.vec().clone(); @@ -646,8 +653,8 @@ final class Long256Vector extends LongVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -657,7 +664,7 @@ final class Long256Vector extends LongVector { /*package-private*/ Long256Mask indexPartiallyInUpperRange(long offset, long limit) { return (Long256Mask) VectorSupport.indexPartiallyInUpperRange( - Long256Mask.class, long.class, VLENGTH, offset, limit, + Long256Mask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (Long256Mask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -673,7 +680,7 @@ final class Long256Vector extends LongVector { @ForceInline public Long256Mask compress() { return (Long256Mask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - Long256Vector.class, Long256Mask.class, ETYPE, VLENGTH, null, this, + Long256Vector.class, Long256Mask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -685,7 +692,7 @@ final class Long256Vector extends LongVector { public Long256Mask and(VectorMask mask) { Objects.requireNonNull(mask); Long256Mask m = (Long256Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, Long256Mask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, Long256Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -695,7 +702,7 @@ final class Long256Vector extends LongVector { public Long256Mask or(VectorMask mask) { Objects.requireNonNull(mask); Long256Mask m = (Long256Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, Long256Mask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, Long256Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -705,7 +712,7 @@ final class Long256Vector extends LongVector { public Long256Mask xor(VectorMask mask) { Objects.requireNonNull(mask); Long256Mask m = (Long256Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, Long256Mask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, Long256Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -715,21 +722,21 @@ final class Long256Vector extends LongVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Long256Mask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Long256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Long256Mask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Long256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Long256Mask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Long256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -739,7 +746,7 @@ final class Long256Vector extends LongVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Long256Mask.class, long.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Long256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -749,7 +756,7 @@ final class Long256Vector extends LongVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(Long256Mask.class, long.class, VLENGTH, + return VectorSupport.extract(Long256Mask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -758,7 +765,7 @@ final class Long256Vector extends LongVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, Long256Mask.class, long.class, VLENGTH, + return VectorSupport.test(BT_ne, Long256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((Long256Mask)m).getBits())); } @@ -766,7 +773,7 @@ final class Long256Vector extends LongVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, Long256Mask.class, long.class, VLENGTH, + return VectorSupport.test(BT_overflow, Long256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((Long256Mask)m).getBits())); } @@ -774,7 +781,7 @@ final class Long256Vector extends LongVector { @ForceInline /*package-private*/ static Long256Mask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(Long256Mask.class, long.class, VLENGTH, + return VectorSupport.fromBitsCoerced(Long256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long512Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long512Vector.java index 30d29c3cd03..169664bc242 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long512Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long512Vector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class Long512Vector extends LongVector { return (long[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -523,7 +530,7 @@ final class Long512Vector extends LongVector { @ForceInline public long laneHelper(int i) { return (long) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { long[] vecarr = vec.vec(); @@ -550,7 +557,7 @@ final class Long512Vector extends LongVector { @ForceInline public Long512Vector withLaneHelper(int i, long e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)e, (v, ix, bits) -> { long[] res = v.vec().clone(); @@ -654,8 +661,8 @@ final class Long512Vector extends LongVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -665,7 +672,7 @@ final class Long512Vector extends LongVector { /*package-private*/ Long512Mask indexPartiallyInUpperRange(long offset, long limit) { return (Long512Mask) VectorSupport.indexPartiallyInUpperRange( - Long512Mask.class, long.class, VLENGTH, offset, limit, + Long512Mask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (Long512Mask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -681,7 +688,7 @@ final class Long512Vector extends LongVector { @ForceInline public Long512Mask compress() { return (Long512Mask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - Long512Vector.class, Long512Mask.class, ETYPE, VLENGTH, null, this, + Long512Vector.class, Long512Mask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -693,7 +700,7 @@ final class Long512Vector extends LongVector { public Long512Mask and(VectorMask mask) { Objects.requireNonNull(mask); Long512Mask m = (Long512Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, Long512Mask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, Long512Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -703,7 +710,7 @@ final class Long512Vector extends LongVector { public Long512Mask or(VectorMask mask) { Objects.requireNonNull(mask); Long512Mask m = (Long512Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, Long512Mask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, Long512Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -713,7 +720,7 @@ final class Long512Vector extends LongVector { public Long512Mask xor(VectorMask mask) { Objects.requireNonNull(mask); Long512Mask m = (Long512Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, Long512Mask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, Long512Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -723,21 +730,21 @@ final class Long512Vector extends LongVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Long512Mask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Long512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Long512Mask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Long512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Long512Mask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Long512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -747,7 +754,7 @@ final class Long512Vector extends LongVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Long512Mask.class, long.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Long512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -757,7 +764,7 @@ final class Long512Vector extends LongVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(Long512Mask.class, long.class, VLENGTH, + return VectorSupport.extract(Long512Mask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -766,7 +773,7 @@ final class Long512Vector extends LongVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, Long512Mask.class, long.class, VLENGTH, + return VectorSupport.test(BT_ne, Long512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((Long512Mask)m).getBits())); } @@ -774,7 +781,7 @@ final class Long512Vector extends LongVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, Long512Mask.class, long.class, VLENGTH, + return VectorSupport.test(BT_overflow, Long512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((Long512Mask)m).getBits())); } @@ -782,7 +789,7 @@ final class Long512Vector extends LongVector { @ForceInline /*package-private*/ static Long512Mask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(Long512Mask.class, long.class, VLENGTH, + return VectorSupport.fromBitsCoerced(Long512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long64Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long64Vector.java index 518baa168ec..66c84fde56f 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long64Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long64Vector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class Long64Vector extends LongVector { return (long[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -516,7 +523,7 @@ final class Long64Vector extends LongVector { @ForceInline public long laneHelper(int i) { return (long) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { long[] vecarr = vec.vec(); @@ -536,7 +543,7 @@ final class Long64Vector extends LongVector { @ForceInline public Long64Vector withLaneHelper(int i, long e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)e, (v, ix, bits) -> { long[] res = v.vec().clone(); @@ -640,8 +647,8 @@ final class Long64Vector extends LongVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -651,7 +658,7 @@ final class Long64Vector extends LongVector { /*package-private*/ Long64Mask indexPartiallyInUpperRange(long offset, long limit) { return (Long64Mask) VectorSupport.indexPartiallyInUpperRange( - Long64Mask.class, long.class, VLENGTH, offset, limit, + Long64Mask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (Long64Mask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -667,7 +674,7 @@ final class Long64Vector extends LongVector { @ForceInline public Long64Mask compress() { return (Long64Mask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - Long64Vector.class, Long64Mask.class, ETYPE, VLENGTH, null, this, + Long64Vector.class, Long64Mask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -679,7 +686,7 @@ final class Long64Vector extends LongVector { public Long64Mask and(VectorMask mask) { Objects.requireNonNull(mask); Long64Mask m = (Long64Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, Long64Mask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, Long64Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -689,7 +696,7 @@ final class Long64Vector extends LongVector { public Long64Mask or(VectorMask mask) { Objects.requireNonNull(mask); Long64Mask m = (Long64Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, Long64Mask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, Long64Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -699,7 +706,7 @@ final class Long64Vector extends LongVector { public Long64Mask xor(VectorMask mask) { Objects.requireNonNull(mask); Long64Mask m = (Long64Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, Long64Mask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, Long64Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -709,21 +716,21 @@ final class Long64Vector extends LongVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Long64Mask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Long64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Long64Mask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Long64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Long64Mask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Long64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -733,7 +740,7 @@ final class Long64Vector extends LongVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Long64Mask.class, long.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Long64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -743,7 +750,7 @@ final class Long64Vector extends LongVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(Long64Mask.class, long.class, VLENGTH, + return VectorSupport.extract(Long64Mask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -752,7 +759,7 @@ final class Long64Vector extends LongVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, Long64Mask.class, long.class, VLENGTH, + return VectorSupport.test(BT_ne, Long64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((Long64Mask)m).getBits())); } @@ -760,7 +767,7 @@ final class Long64Vector extends LongVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, Long64Mask.class, long.class, VLENGTH, + return VectorSupport.test(BT_overflow, Long64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((Long64Mask)m).getBits())); } @@ -768,7 +775,7 @@ final class Long64Vector extends LongVector { @ForceInline /*package-private*/ static Long64Mask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(Long64Mask.class, long.class, VLENGTH, + return VectorSupport.fromBitsCoerced(Long64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongMaxVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongMaxVector.java index 3d981c37ae2..c95db0c4482 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongMaxVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongMaxVector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class LongMaxVector extends LongVector { return (long[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -516,7 +523,7 @@ final class LongMaxVector extends LongVector { @ForceInline public long laneHelper(int i) { return (long) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { long[] vecarr = vec.vec(); @@ -536,7 +543,7 @@ final class LongMaxVector extends LongVector { @ForceInline public LongMaxVector withLaneHelper(int i, long e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)e, (v, ix, bits) -> { long[] res = v.vec().clone(); @@ -640,8 +647,8 @@ final class LongMaxVector extends LongVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -651,7 +658,7 @@ final class LongMaxVector extends LongVector { /*package-private*/ LongMaxMask indexPartiallyInUpperRange(long offset, long limit) { return (LongMaxMask) VectorSupport.indexPartiallyInUpperRange( - LongMaxMask.class, long.class, VLENGTH, offset, limit, + LongMaxMask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (LongMaxMask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -667,7 +674,7 @@ final class LongMaxVector extends LongVector { @ForceInline public LongMaxMask compress() { return (LongMaxMask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - LongMaxVector.class, LongMaxMask.class, ETYPE, VLENGTH, null, this, + LongMaxVector.class, LongMaxMask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -679,7 +686,7 @@ final class LongMaxVector extends LongVector { public LongMaxMask and(VectorMask mask) { Objects.requireNonNull(mask); LongMaxMask m = (LongMaxMask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, LongMaxMask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, LongMaxMask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -689,7 +696,7 @@ final class LongMaxVector extends LongVector { public LongMaxMask or(VectorMask mask) { Objects.requireNonNull(mask); LongMaxMask m = (LongMaxMask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, LongMaxMask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, LongMaxMask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -699,7 +706,7 @@ final class LongMaxVector extends LongVector { public LongMaxMask xor(VectorMask mask) { Objects.requireNonNull(mask); LongMaxMask m = (LongMaxMask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, LongMaxMask.class, null, long.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, LongMaxMask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -709,21 +716,21 @@ final class LongMaxVector extends LongVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, LongMaxMask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, LongMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, LongMaxMask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, LongMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, LongMaxMask.class, long.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, LongMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -733,7 +740,7 @@ final class LongMaxVector extends LongVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, LongMaxMask.class, long.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, LongMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -743,7 +750,7 @@ final class LongMaxVector extends LongVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(LongMaxMask.class, long.class, VLENGTH, + return VectorSupport.extract(LongMaxMask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -752,7 +759,7 @@ final class LongMaxVector extends LongVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, LongMaxMask.class, long.class, VLENGTH, + return VectorSupport.test(BT_ne, LongMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((LongMaxMask)m).getBits())); } @@ -760,7 +767,7 @@ final class LongMaxVector extends LongVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, LongMaxMask.class, long.class, VLENGTH, + return VectorSupport.test(BT_overflow, LongMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((LongMaxMask)m).getBits())); } @@ -768,7 +775,7 @@ final class LongMaxVector extends LongVector { @ForceInline /*package-private*/ static LongMaxMask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(LongMaxMask.class, long.class, VLENGTH, + return VectorSupport.fromBitsCoerced(LongMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongVector.java index 58bfd4d7772..5657bbec0a6 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongVector.java @@ -59,6 +59,10 @@ public abstract class LongVector extends AbstractVector { static final ValueLayout.OfLong ELEMENT_LAYOUT = ValueLayout.JAVA_LONG.withByteAlignment(1); + static final int LANE_TYPE_ORDINAL = LT_LONG; + + static final int LANEBITS_TYPE_ORDINAL = LT_LONG; + @ForceInline static int opCode(Operator op) { return VectorOperators.opCode(op, VO_OPCODE_VALID, FORBID_OPCODE_KIND); @@ -573,7 +577,7 @@ public abstract class LongVector extends AbstractVector { @ForceInline public static LongVector zero(VectorSpecies species) { LongSpecies vsp = (LongSpecies) species; - return VectorSupport.fromBitsCoerced(vsp.vectorType(), long.class, species.length(), + return VectorSupport.fromBitsCoerced(vsp.vectorType(), LANE_TYPE_ORDINAL, species.length(), 0, MODE_BROADCAST, vsp, ((bits_, s_) -> s_.rvOp(i -> bits_))); } @@ -653,7 +657,7 @@ public abstract class LongVector extends AbstractVector { } int opc = opCode(op); return VectorSupport.unaryOp( - opc, getClass(), null, long.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, null, UN_IMPL.find(op, opc, LongVector::unaryOperations)); } @@ -681,7 +685,7 @@ public abstract class LongVector extends AbstractVector { } int opc = opCode(op); return VectorSupport.unaryOp( - opc, getClass(), maskClass, long.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, m, UN_IMPL.find(op, opc, LongVector::unaryOperations)); } @@ -754,7 +758,7 @@ public abstract class LongVector extends AbstractVector { int opc = opCode(op); return VectorSupport.binaryOp( - opc, getClass(), null, long.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, that, null, BIN_IMPL.find(op, opc, LongVector::binaryOperations)); } @@ -805,7 +809,7 @@ public abstract class LongVector extends AbstractVector { int opc = opCode(op); return VectorSupport.binaryOp( - opc, getClass(), maskClass, long.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, that, m, BIN_IMPL.find(op, opc, LongVector::binaryOperations)); } @@ -951,7 +955,7 @@ public abstract class LongVector extends AbstractVector { e &= SHIFT_MASK; int opc = opCode(op); return VectorSupport.broadcastInt( - opc, getClass(), null, long.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, e, null, BIN_INT_IMPL.find(op, opc, LongVector::broadcastIntOperations)); } @@ -972,7 +976,7 @@ public abstract class LongVector extends AbstractVector { e &= SHIFT_MASK; int opc = opCode(op); return VectorSupport.broadcastInt( - opc, getClass(), maskClass, long.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, e, m, BIN_INT_IMPL.find(op, opc, LongVector::broadcastIntOperations)); } @@ -1048,7 +1052,7 @@ public abstract class LongVector extends AbstractVector { } int opc = opCode(op); return VectorSupport.ternaryOp( - opc, getClass(), null, long.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, that, tother, null, TERN_IMPL.find(op, opc, LongVector::ternaryOperations)); } @@ -1088,7 +1092,7 @@ public abstract class LongVector extends AbstractVector { } int opc = opCode(op); return VectorSupport.ternaryOp( - opc, getClass(), maskClass, long.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, that, tother, m, TERN_IMPL.find(op, opc, LongVector::ternaryOperations)); } @@ -1968,7 +1972,7 @@ public abstract class LongVector extends AbstractVector { that.check(this); int opc = opCode(op); return VectorSupport.compare( - opc, getClass(), maskType, long.class, length(), + opc, getClass(), maskType, laneTypeOrdinal(), length(), this, that, null, (cond, v0, v1, m1) -> { AbstractMask m @@ -1990,7 +1994,7 @@ public abstract class LongVector extends AbstractVector { m.check(maskType, this); int opc = opCode(op); return VectorSupport.compare( - opc, getClass(), maskType, long.class, length(), + opc, getClass(), maskType, laneTypeOrdinal(), length(), this, that, m, (cond, v0, v1, m1) -> { AbstractMask cmpM @@ -2095,7 +2099,7 @@ public abstract class LongVector extends AbstractVector { blendTemplate(Class maskType, LongVector v, M m) { v.check(this); return VectorSupport.blend( - getClass(), maskType, long.class, length(), + getClass(), maskType, laneTypeOrdinal(), length(), this, v, m, (v0, v1, m_) -> v0.bOp(v1, m_, (i, a, b) -> b)); } @@ -2112,7 +2116,7 @@ public abstract class LongVector extends AbstractVector { // make sure VLENGTH*scale doesn't overflow: vsp.checkScale(scale); return VectorSupport.indexVector( - getClass(), long.class, length(), + getClass(), laneTypeOrdinal(), length(), this, scale, vsp, (v, scale_, s) -> { @@ -2283,7 +2287,7 @@ public abstract class LongVector extends AbstractVector { LongVector rearrangeTemplate(Class shuffletype, S shuffle) { Objects.requireNonNull(shuffle); return VectorSupport.rearrangeOp( - getClass(), shuffletype, null, long.class, length(), + getClass(), shuffletype, null, laneTypeOrdinal(), length(), this, shuffle, null, (v1, s_, m_) -> v1.uOp((i, a) -> { int ei = Integer.remainderUnsigned(s_.laneSource(i), v1.length()); @@ -2310,7 +2314,7 @@ public abstract class LongVector extends AbstractVector { Objects.requireNonNull(shuffle); m.check(masktype, this); return VectorSupport.rearrangeOp( - getClass(), shuffletype, masktype, long.class, length(), + getClass(), shuffletype, masktype, laneTypeOrdinal(), length(), this, shuffle, m, (v1, s_, m_) -> v1.uOp((i, a) -> { int ei = Integer.remainderUnsigned(s_.laneSource(i), v1.length()); @@ -2336,7 +2340,7 @@ public abstract class LongVector extends AbstractVector { VectorMask valid = shuffle.laneIsValid(); LongVector r0 = VectorSupport.rearrangeOp( - getClass(), shuffletype, null, long.class, length(), + getClass(), shuffletype, null, laneTypeOrdinal(), length(), this, shuffle, null, (v0, s_, m_) -> v0.uOp((i, a) -> { int ei = Integer.remainderUnsigned(s_.laneSource(i), v0.length()); @@ -2344,7 +2348,7 @@ public abstract class LongVector extends AbstractVector { })); LongVector r1 = VectorSupport.rearrangeOp( - getClass(), shuffletype, null, long.class, length(), + getClass(), shuffletype, null, laneTypeOrdinal(), length(), v, shuffle, null, (v1, s_, m_) -> v1.uOp((i, a) -> { int ei = Integer.remainderUnsigned(s_.laneSource(i), v1.length()); @@ -2394,7 +2398,7 @@ public abstract class LongVector extends AbstractVector { LongVector compressTemplate(Class masktype, M m) { m.check(masktype, this); return (LongVector) VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_COMPRESS, getClass(), masktype, - long.class, length(), this, m, + laneTypeOrdinal(), length(), this, m, (v1, m1) -> compressHelper(v1, m1)); } @@ -2413,7 +2417,7 @@ public abstract class LongVector extends AbstractVector { LongVector expandTemplate(Class masktype, M m) { m.check(masktype, this); return (LongVector) VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_EXPAND, getClass(), masktype, - long.class, length(), this, m, + laneTypeOrdinal(), length(), this, m, (v1, m1) -> expandHelper(v1, m1)); } @@ -2428,7 +2432,7 @@ public abstract class LongVector extends AbstractVector { /*package-private*/ @ForceInline final LongVector selectFromTemplate(LongVector v) { - return (LongVector)VectorSupport.selectFromOp(getClass(), null, long.class, + return (LongVector)VectorSupport.selectFromOp(getClass(), null, laneTypeOrdinal(), length(), this, v, null, (v1, v2, _m) -> v2.rearrange(v1.toShuffle())); @@ -2448,7 +2452,7 @@ public abstract class LongVector extends AbstractVector { LongVector selectFromTemplate(LongVector v, Class masktype, M m) { m.check(masktype, this); - return (LongVector)VectorSupport.selectFromOp(getClass(), masktype, long.class, + return (LongVector)VectorSupport.selectFromOp(getClass(), masktype, laneTypeOrdinal(), length(), this, v, m, (v1, v2, _m) -> v2.rearrange(v1.toShuffle(), _m)); @@ -2466,7 +2470,7 @@ public abstract class LongVector extends AbstractVector { /*package-private*/ @ForceInline final LongVector selectFromTemplate(LongVector v1, LongVector v2) { - return VectorSupport.selectFromTwoVectorOp(getClass(), long.class, length(), this, v1, v2, + return VectorSupport.selectFromTwoVectorOp(getClass(), laneTypeOrdinal(), length(), this, v1, v2, (vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)); } @@ -2686,7 +2690,7 @@ public abstract class LongVector extends AbstractVector { } int opc = opCode(op); return fromBits(VectorSupport.reductionCoerced( - opc, getClass(), maskClass, long.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, m, REDUCE_IMPL.find(op, opc, LongVector::reductionOperations))); } @@ -2704,7 +2708,7 @@ public abstract class LongVector extends AbstractVector { } int opc = opCode(op); return fromBits(VectorSupport.reductionCoerced( - opc, getClass(), null, long.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, null, REDUCE_IMPL.find(op, opc, LongVector::reductionOperations))); } @@ -2979,7 +2983,7 @@ public abstract class LongVector extends AbstractVector { vix = VectorIntrinsics.checkIndex(vix, a.length); return VectorSupport.loadWithMap( - vectorType, null, long.class, vsp.laneCount(), + vectorType, null, LANE_TYPE_ORDINAL, vsp.laneCount(), isp.vectorType(), isp.length(), a, ARRAY_BASE, vix, null, null, null, null, a, offset, indexMap, mapOffset, vsp, @@ -3162,7 +3166,7 @@ public abstract class LongVector extends AbstractVector { offset = checkFromIndexSize(offset, length(), a.length); LongSpecies vsp = vspecies(); VectorSupport.store( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, this, a, offset, @@ -3270,7 +3274,7 @@ public abstract class LongVector extends AbstractVector { vix = VectorIntrinsics.checkIndex(vix, a.length); VectorSupport.storeWithMap( - vsp.vectorType(), null, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), null, LANE_TYPE_ORDINAL, vsp.laneCount(), isp.vectorType(), isp.length(), a, arrayAddress(a, 0), vix, this, null, @@ -3397,7 +3401,7 @@ public abstract class LongVector extends AbstractVector { LongVector fromArray0Template(long[] a, int offset) { LongSpecies vsp = vspecies(); return VectorSupport.load( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, a, offset, vsp, (arr, off, s) -> s.ldOp(arr, (int) off, @@ -3414,7 +3418,7 @@ public abstract class LongVector extends AbstractVector { m.check(species()); LongSpecies vsp = vspecies(); return VectorSupport.loadMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, m, offsetInRange, a, offset, vsp, (arr, off, s, vm) -> s.ldOp(arr, (int) off, vm, @@ -3465,7 +3469,7 @@ public abstract class LongVector extends AbstractVector { vix = VectorIntrinsics.checkIndex(vix, a.length); return VectorSupport.loadWithMap( - vectorType, maskClass, long.class, vsp.laneCount(), + vectorType, maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), isp.vectorType(), isp.length(), a, ARRAY_BASE, vix, null, null, null, m, a, offset, indexMap, mapOffset, vsp, @@ -3482,7 +3486,7 @@ public abstract class LongVector extends AbstractVector { LongVector fromMemorySegment0Template(MemorySegment ms, long offset) { LongSpecies vsp = vspecies(); return ScopedMemoryAccess.loadFromMemorySegment( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), (AbstractMemorySegmentImpl) ms, offset, vsp, (msp, off, s) -> { return s.ldLongOp((MemorySegment) msp, off, LongVector::memorySegmentGet); @@ -3498,7 +3502,7 @@ public abstract class LongVector extends AbstractVector { LongSpecies vsp = vspecies(); m.check(vsp); return ScopedMemoryAccess.loadFromMemorySegmentMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), (AbstractMemorySegmentImpl) ms, offset, m, vsp, offsetInRange, (msp, off, s, vm) -> { return s.ldLongOp((MemorySegment) msp, off, vm, LongVector::memorySegmentGet); @@ -3516,7 +3520,7 @@ public abstract class LongVector extends AbstractVector { void intoArray0Template(long[] a, int offset) { LongSpecies vsp = vspecies(); VectorSupport.store( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, this, a, offset, (arr, off, v) @@ -3533,7 +3537,7 @@ public abstract class LongVector extends AbstractVector { m.check(species()); LongSpecies vsp = vspecies(); VectorSupport.storeMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, this, m, a, offset, (arr, off, v, vm) @@ -3581,7 +3585,7 @@ public abstract class LongVector extends AbstractVector { vix = VectorIntrinsics.checkIndex(vix, a.length); VectorSupport.storeWithMap( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), isp.vectorType(), isp.length(), a, arrayAddress(a, 0), vix, this, m, @@ -3600,7 +3604,7 @@ public abstract class LongVector extends AbstractVector { void intoMemorySegment0(MemorySegment ms, long offset) { LongSpecies vsp = vspecies(); ScopedMemoryAccess.storeIntoMemorySegment( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), this, (AbstractMemorySegmentImpl) ms, offset, (msp, off, v) -> { @@ -3617,7 +3621,7 @@ public abstract class LongVector extends AbstractVector { LongSpecies vsp = vspecies(); m.check(vsp); ScopedMemoryAccess.storeIntoMemorySegmentMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), this, m, (AbstractMemorySegmentImpl) ms, offset, (msp, off, v, vm) -> { @@ -3655,6 +3659,18 @@ public abstract class LongVector extends AbstractVector { return this; } + @Override + @ForceInline + final + LongVector swapIfNeeded(AbstractSpecies srcSpecies) { + int subLanesPerSrc = subLanesToSwap(srcSpecies); + if (subLanesPerSrc < 0) { + return this; + } + VectorShuffle shuffle = normalizeSubLanesForSpecies(this.vspecies(), subLanesPerSrc); + return (LongVector) this.rearrange(shuffle); + } + static final int ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_LONG_INDEX_SCALE); static final long ARRAY_BASE = @@ -3821,7 +3837,7 @@ public abstract class LongVector extends AbstractVector { final LongVector broadcastBits(long bits) { return (LongVector) VectorSupport.fromBitsCoerced( - vectorType, long.class, laneCount, + vectorType, laneTypeOrdinal(), laneCount, bits, MODE_BROADCAST, this, (bits_, s_) -> s_.rvOp(i -> bits_)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short128Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short128Vector.java index 60f22eb5fb9..cc35a1ea069 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short128Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short128Vector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class Short128Vector extends ShortVector { return (short[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -533,7 +540,7 @@ final class Short128Vector extends ShortVector { @ForceInline public short laneHelper(int i) { return (short) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { short[] vecarr = vec.vec(); @@ -560,7 +567,7 @@ final class Short128Vector extends ShortVector { @ForceInline public Short128Vector withLaneHelper(int i, short e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)e, (v, ix, bits) -> { short[] res = v.vec().clone(); @@ -664,8 +671,8 @@ final class Short128Vector extends ShortVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -675,7 +682,7 @@ final class Short128Vector extends ShortVector { /*package-private*/ Short128Mask indexPartiallyInUpperRange(long offset, long limit) { return (Short128Mask) VectorSupport.indexPartiallyInUpperRange( - Short128Mask.class, short.class, VLENGTH, offset, limit, + Short128Mask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (Short128Mask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -691,7 +698,7 @@ final class Short128Vector extends ShortVector { @ForceInline public Short128Mask compress() { return (Short128Mask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - Short128Vector.class, Short128Mask.class, ETYPE, VLENGTH, null, this, + Short128Vector.class, Short128Mask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -703,7 +710,7 @@ final class Short128Vector extends ShortVector { public Short128Mask and(VectorMask mask) { Objects.requireNonNull(mask); Short128Mask m = (Short128Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, Short128Mask.class, null, short.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, Short128Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -713,7 +720,7 @@ final class Short128Vector extends ShortVector { public Short128Mask or(VectorMask mask) { Objects.requireNonNull(mask); Short128Mask m = (Short128Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, Short128Mask.class, null, short.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, Short128Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -723,7 +730,7 @@ final class Short128Vector extends ShortVector { public Short128Mask xor(VectorMask mask) { Objects.requireNonNull(mask); Short128Mask m = (Short128Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, Short128Mask.class, null, short.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, Short128Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -733,21 +740,21 @@ final class Short128Vector extends ShortVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Short128Mask.class, short.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Short128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Short128Mask.class, short.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Short128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Short128Mask.class, short.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Short128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -757,7 +764,7 @@ final class Short128Vector extends ShortVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Short128Mask.class, short.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Short128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -767,7 +774,7 @@ final class Short128Vector extends ShortVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(Short128Mask.class, short.class, VLENGTH, + return VectorSupport.extract(Short128Mask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -776,7 +783,7 @@ final class Short128Vector extends ShortVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, Short128Mask.class, short.class, VLENGTH, + return VectorSupport.test(BT_ne, Short128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((Short128Mask)m).getBits())); } @@ -784,7 +791,7 @@ final class Short128Vector extends ShortVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, Short128Mask.class, short.class, VLENGTH, + return VectorSupport.test(BT_overflow, Short128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((Short128Mask)m).getBits())); } @@ -792,7 +799,7 @@ final class Short128Vector extends ShortVector { @ForceInline /*package-private*/ static Short128Mask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(Short128Mask.class, short.class, VLENGTH, + return VectorSupport.fromBitsCoerced(Short128Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short256Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short256Vector.java index 14c415afac2..a3841eb63dc 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short256Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short256Vector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class Short256Vector extends ShortVector { return (short[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -541,7 +548,7 @@ final class Short256Vector extends ShortVector { @ForceInline public short laneHelper(int i) { return (short) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { short[] vecarr = vec.vec(); @@ -576,7 +583,7 @@ final class Short256Vector extends ShortVector { @ForceInline public Short256Vector withLaneHelper(int i, short e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)e, (v, ix, bits) -> { short[] res = v.vec().clone(); @@ -680,8 +687,8 @@ final class Short256Vector extends ShortVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -691,7 +698,7 @@ final class Short256Vector extends ShortVector { /*package-private*/ Short256Mask indexPartiallyInUpperRange(long offset, long limit) { return (Short256Mask) VectorSupport.indexPartiallyInUpperRange( - Short256Mask.class, short.class, VLENGTH, offset, limit, + Short256Mask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (Short256Mask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -707,7 +714,7 @@ final class Short256Vector extends ShortVector { @ForceInline public Short256Mask compress() { return (Short256Mask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - Short256Vector.class, Short256Mask.class, ETYPE, VLENGTH, null, this, + Short256Vector.class, Short256Mask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -719,7 +726,7 @@ final class Short256Vector extends ShortVector { public Short256Mask and(VectorMask mask) { Objects.requireNonNull(mask); Short256Mask m = (Short256Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, Short256Mask.class, null, short.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, Short256Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -729,7 +736,7 @@ final class Short256Vector extends ShortVector { public Short256Mask or(VectorMask mask) { Objects.requireNonNull(mask); Short256Mask m = (Short256Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, Short256Mask.class, null, short.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, Short256Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -739,7 +746,7 @@ final class Short256Vector extends ShortVector { public Short256Mask xor(VectorMask mask) { Objects.requireNonNull(mask); Short256Mask m = (Short256Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, Short256Mask.class, null, short.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, Short256Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -749,21 +756,21 @@ final class Short256Vector extends ShortVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Short256Mask.class, short.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Short256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Short256Mask.class, short.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Short256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Short256Mask.class, short.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Short256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -773,7 +780,7 @@ final class Short256Vector extends ShortVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Short256Mask.class, short.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Short256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -783,7 +790,7 @@ final class Short256Vector extends ShortVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(Short256Mask.class, short.class, VLENGTH, + return VectorSupport.extract(Short256Mask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -792,7 +799,7 @@ final class Short256Vector extends ShortVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, Short256Mask.class, short.class, VLENGTH, + return VectorSupport.test(BT_ne, Short256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((Short256Mask)m).getBits())); } @@ -800,7 +807,7 @@ final class Short256Vector extends ShortVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, Short256Mask.class, short.class, VLENGTH, + return VectorSupport.test(BT_overflow, Short256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((Short256Mask)m).getBits())); } @@ -808,7 +815,7 @@ final class Short256Vector extends ShortVector { @ForceInline /*package-private*/ static Short256Mask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(Short256Mask.class, short.class, VLENGTH, + return VectorSupport.fromBitsCoerced(Short256Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short512Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short512Vector.java index c92979302a6..3da20257a8d 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short512Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short512Vector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class Short512Vector extends ShortVector { return (short[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -557,7 +564,7 @@ final class Short512Vector extends ShortVector { @ForceInline public short laneHelper(int i) { return (short) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { short[] vecarr = vec.vec(); @@ -608,7 +615,7 @@ final class Short512Vector extends ShortVector { @ForceInline public Short512Vector withLaneHelper(int i, short e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)e, (v, ix, bits) -> { short[] res = v.vec().clone(); @@ -712,8 +719,8 @@ final class Short512Vector extends ShortVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -723,7 +730,7 @@ final class Short512Vector extends ShortVector { /*package-private*/ Short512Mask indexPartiallyInUpperRange(long offset, long limit) { return (Short512Mask) VectorSupport.indexPartiallyInUpperRange( - Short512Mask.class, short.class, VLENGTH, offset, limit, + Short512Mask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (Short512Mask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -739,7 +746,7 @@ final class Short512Vector extends ShortVector { @ForceInline public Short512Mask compress() { return (Short512Mask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - Short512Vector.class, Short512Mask.class, ETYPE, VLENGTH, null, this, + Short512Vector.class, Short512Mask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -751,7 +758,7 @@ final class Short512Vector extends ShortVector { public Short512Mask and(VectorMask mask) { Objects.requireNonNull(mask); Short512Mask m = (Short512Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, Short512Mask.class, null, short.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, Short512Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -761,7 +768,7 @@ final class Short512Vector extends ShortVector { public Short512Mask or(VectorMask mask) { Objects.requireNonNull(mask); Short512Mask m = (Short512Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, Short512Mask.class, null, short.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, Short512Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -771,7 +778,7 @@ final class Short512Vector extends ShortVector { public Short512Mask xor(VectorMask mask) { Objects.requireNonNull(mask); Short512Mask m = (Short512Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, Short512Mask.class, null, short.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, Short512Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -781,21 +788,21 @@ final class Short512Vector extends ShortVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Short512Mask.class, short.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Short512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Short512Mask.class, short.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Short512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Short512Mask.class, short.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Short512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -805,7 +812,7 @@ final class Short512Vector extends ShortVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Short512Mask.class, short.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Short512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -815,7 +822,7 @@ final class Short512Vector extends ShortVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(Short512Mask.class, short.class, VLENGTH, + return VectorSupport.extract(Short512Mask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -824,7 +831,7 @@ final class Short512Vector extends ShortVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, Short512Mask.class, short.class, VLENGTH, + return VectorSupport.test(BT_ne, Short512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((Short512Mask)m).getBits())); } @@ -832,7 +839,7 @@ final class Short512Vector extends ShortVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, Short512Mask.class, short.class, VLENGTH, + return VectorSupport.test(BT_overflow, Short512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((Short512Mask)m).getBits())); } @@ -840,7 +847,7 @@ final class Short512Vector extends ShortVector { @ForceInline /*package-private*/ static Short512Mask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(Short512Mask.class, short.class, VLENGTH, + return VectorSupport.fromBitsCoerced(Short512Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short64Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short64Vector.java index b454989b45f..8b3246996f3 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short64Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short64Vector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class Short64Vector extends ShortVector { return (short[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -529,7 +536,7 @@ final class Short64Vector extends ShortVector { @ForceInline public short laneHelper(int i) { return (short) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { short[] vecarr = vec.vec(); @@ -552,7 +559,7 @@ final class Short64Vector extends ShortVector { @ForceInline public Short64Vector withLaneHelper(int i, short e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)e, (v, ix, bits) -> { short[] res = v.vec().clone(); @@ -656,8 +663,8 @@ final class Short64Vector extends ShortVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -667,7 +674,7 @@ final class Short64Vector extends ShortVector { /*package-private*/ Short64Mask indexPartiallyInUpperRange(long offset, long limit) { return (Short64Mask) VectorSupport.indexPartiallyInUpperRange( - Short64Mask.class, short.class, VLENGTH, offset, limit, + Short64Mask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (Short64Mask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -683,7 +690,7 @@ final class Short64Vector extends ShortVector { @ForceInline public Short64Mask compress() { return (Short64Mask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - Short64Vector.class, Short64Mask.class, ETYPE, VLENGTH, null, this, + Short64Vector.class, Short64Mask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -695,7 +702,7 @@ final class Short64Vector extends ShortVector { public Short64Mask and(VectorMask mask) { Objects.requireNonNull(mask); Short64Mask m = (Short64Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, Short64Mask.class, null, short.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, Short64Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -705,7 +712,7 @@ final class Short64Vector extends ShortVector { public Short64Mask or(VectorMask mask) { Objects.requireNonNull(mask); Short64Mask m = (Short64Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, Short64Mask.class, null, short.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, Short64Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -715,7 +722,7 @@ final class Short64Vector extends ShortVector { public Short64Mask xor(VectorMask mask) { Objects.requireNonNull(mask); Short64Mask m = (Short64Mask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, Short64Mask.class, null, short.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, Short64Mask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -725,21 +732,21 @@ final class Short64Vector extends ShortVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Short64Mask.class, short.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, Short64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Short64Mask.class, short.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, Short64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Short64Mask.class, short.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, Short64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -749,7 +756,7 @@ final class Short64Vector extends ShortVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Short64Mask.class, short.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, Short64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -759,7 +766,7 @@ final class Short64Vector extends ShortVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(Short64Mask.class, short.class, VLENGTH, + return VectorSupport.extract(Short64Mask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -768,7 +775,7 @@ final class Short64Vector extends ShortVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, Short64Mask.class, short.class, VLENGTH, + return VectorSupport.test(BT_ne, Short64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((Short64Mask)m).getBits())); } @@ -776,7 +783,7 @@ final class Short64Vector extends ShortVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, Short64Mask.class, short.class, VLENGTH, + return VectorSupport.test(BT_overflow, Short64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((Short64Mask)m).getBits())); } @@ -784,7 +791,7 @@ final class Short64Vector extends ShortVector { @ForceInline /*package-private*/ static Short64Mask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(Short64Mask.class, short.class, VLENGTH, + return VectorSupport.fromBitsCoerced(Short64Mask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortMaxVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortMaxVector.java index bea14b7d5fd..bf9b13c6606 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortMaxVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortMaxVector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class ShortMaxVector extends ShortVector { return (short[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -526,7 +533,7 @@ final class ShortMaxVector extends ShortVector { @ForceInline public short laneHelper(int i) { return (short) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { short[] vecarr = vec.vec(); @@ -546,7 +553,7 @@ final class ShortMaxVector extends ShortVector { @ForceInline public ShortMaxVector withLaneHelper(int i, short e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)e, (v, ix, bits) -> { short[] res = v.vec().clone(); @@ -650,8 +657,8 @@ final class ShortMaxVector extends ShortVector { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -661,7 +668,7 @@ final class ShortMaxVector extends ShortVector { /*package-private*/ ShortMaxMask indexPartiallyInUpperRange(long offset, long limit) { return (ShortMaxMask) VectorSupport.indexPartiallyInUpperRange( - ShortMaxMask.class, short.class, VLENGTH, offset, limit, + ShortMaxMask.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> (ShortMaxMask) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -677,7 +684,7 @@ final class ShortMaxVector extends ShortVector { @ForceInline public ShortMaxMask compress() { return (ShortMaxMask)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - ShortMaxVector.class, ShortMaxMask.class, ETYPE, VLENGTH, null, this, + ShortMaxVector.class, ShortMaxMask.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -689,7 +696,7 @@ final class ShortMaxVector extends ShortVector { public ShortMaxMask and(VectorMask mask) { Objects.requireNonNull(mask); ShortMaxMask m = (ShortMaxMask)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, ShortMaxMask.class, null, short.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, ShortMaxMask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -699,7 +706,7 @@ final class ShortMaxVector extends ShortVector { public ShortMaxMask or(VectorMask mask) { Objects.requireNonNull(mask); ShortMaxMask m = (ShortMaxMask)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, ShortMaxMask.class, null, short.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, ShortMaxMask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -709,7 +716,7 @@ final class ShortMaxVector extends ShortVector { public ShortMaxMask xor(VectorMask mask) { Objects.requireNonNull(mask); ShortMaxMask m = (ShortMaxMask)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, ShortMaxMask.class, null, short.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, ShortMaxMask.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -719,21 +726,21 @@ final class ShortMaxVector extends ShortVector { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, ShortMaxMask.class, short.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, ShortMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, ShortMaxMask.class, short.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, ShortMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, ShortMaxMask.class, short.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, ShortMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -743,7 +750,7 @@ final class ShortMaxVector extends ShortVector { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, ShortMaxMask.class, short.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, ShortMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -753,7 +760,7 @@ final class ShortMaxVector extends ShortVector { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract(ShortMaxMask.class, short.class, VLENGTH, + return VectorSupport.extract(ShortMaxMask.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -762,7 +769,7 @@ final class ShortMaxVector extends ShortVector { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, ShortMaxMask.class, short.class, VLENGTH, + return VectorSupport.test(BT_ne, ShortMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper(((ShortMaxMask)m).getBits())); } @@ -770,7 +777,7 @@ final class ShortMaxVector extends ShortVector { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, ShortMaxMask.class, short.class, VLENGTH, + return VectorSupport.test(BT_overflow, ShortMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper(((ShortMaxMask)m).getBits())); } @@ -778,7 +785,7 @@ final class ShortMaxVector extends ShortVector { @ForceInline /*package-private*/ static ShortMaxMask maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced(ShortMaxMask.class, short.class, VLENGTH, + return VectorSupport.fromBitsCoerced(ShortMaxMask.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortVector.java index 7ab7e7c4417..03b7bb030b9 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortVector.java @@ -59,6 +59,10 @@ public abstract class ShortVector extends AbstractVector { static final ValueLayout.OfShort ELEMENT_LAYOUT = ValueLayout.JAVA_SHORT.withByteAlignment(1); + static final int LANE_TYPE_ORDINAL = LT_SHORT; + + static final int LANEBITS_TYPE_ORDINAL = LT_SHORT; + @ForceInline static int opCode(Operator op) { return VectorOperators.opCode(op, VO_OPCODE_VALID, FORBID_OPCODE_KIND); @@ -573,7 +577,7 @@ public abstract class ShortVector extends AbstractVector { @ForceInline public static ShortVector zero(VectorSpecies species) { ShortSpecies vsp = (ShortSpecies) species; - return VectorSupport.fromBitsCoerced(vsp.vectorType(), short.class, species.length(), + return VectorSupport.fromBitsCoerced(vsp.vectorType(), LANE_TYPE_ORDINAL, species.length(), 0, MODE_BROADCAST, vsp, ((bits_, s_) -> s_.rvOp(i -> bits_))); } @@ -695,7 +699,7 @@ public abstract class ShortVector extends AbstractVector { } int opc = opCode(op); return VectorSupport.unaryOp( - opc, getClass(), null, short.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, null, UN_IMPL.find(op, opc, ShortVector::unaryOperations)); } @@ -723,7 +727,7 @@ public abstract class ShortVector extends AbstractVector { } int opc = opCode(op); return VectorSupport.unaryOp( - opc, getClass(), maskClass, short.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, m, UN_IMPL.find(op, opc, ShortVector::unaryOperations)); } @@ -796,7 +800,7 @@ public abstract class ShortVector extends AbstractVector { int opc = opCode(op); return VectorSupport.binaryOp( - opc, getClass(), null, short.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, that, null, BIN_IMPL.find(op, opc, ShortVector::binaryOperations)); } @@ -847,7 +851,7 @@ public abstract class ShortVector extends AbstractVector { int opc = opCode(op); return VectorSupport.binaryOp( - opc, getClass(), maskClass, short.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, that, m, BIN_IMPL.find(op, opc, ShortVector::binaryOperations)); } @@ -1034,7 +1038,7 @@ public abstract class ShortVector extends AbstractVector { e &= SHIFT_MASK; int opc = opCode(op); return VectorSupport.broadcastInt( - opc, getClass(), null, short.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, e, null, BIN_INT_IMPL.find(op, opc, ShortVector::broadcastIntOperations)); } @@ -1055,7 +1059,7 @@ public abstract class ShortVector extends AbstractVector { e &= SHIFT_MASK; int opc = opCode(op); return VectorSupport.broadcastInt( - opc, getClass(), maskClass, short.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, e, m, BIN_INT_IMPL.find(op, opc, ShortVector::broadcastIntOperations)); } @@ -1132,7 +1136,7 @@ public abstract class ShortVector extends AbstractVector { } int opc = opCode(op); return VectorSupport.ternaryOp( - opc, getClass(), null, short.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, that, tother, null, TERN_IMPL.find(op, opc, ShortVector::ternaryOperations)); } @@ -1172,7 +1176,7 @@ public abstract class ShortVector extends AbstractVector { } int opc = opCode(op); return VectorSupport.ternaryOp( - opc, getClass(), maskClass, short.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, that, tother, m, TERN_IMPL.find(op, opc, ShortVector::ternaryOperations)); } @@ -2071,7 +2075,7 @@ public abstract class ShortVector extends AbstractVector { that.check(this); int opc = opCode(op); return VectorSupport.compare( - opc, getClass(), maskType, short.class, length(), + opc, getClass(), maskType, laneTypeOrdinal(), length(), this, that, null, (cond, v0, v1, m1) -> { AbstractMask m @@ -2093,7 +2097,7 @@ public abstract class ShortVector extends AbstractVector { m.check(maskType, this); int opc = opCode(op); return VectorSupport.compare( - opc, getClass(), maskType, short.class, length(), + opc, getClass(), maskType, laneTypeOrdinal(), length(), this, that, m, (cond, v0, v1, m1) -> { AbstractMask cmpM @@ -2224,7 +2228,7 @@ public abstract class ShortVector extends AbstractVector { blendTemplate(Class maskType, ShortVector v, M m) { v.check(this); return VectorSupport.blend( - getClass(), maskType, short.class, length(), + getClass(), maskType, laneTypeOrdinal(), length(), this, v, m, (v0, v1, m_) -> v0.bOp(v1, m_, (i, a, b) -> b)); } @@ -2241,7 +2245,7 @@ public abstract class ShortVector extends AbstractVector { // make sure VLENGTH*scale doesn't overflow: vsp.checkScale(scale); return VectorSupport.indexVector( - getClass(), short.class, length(), + getClass(), laneTypeOrdinal(), length(), this, scale, vsp, (v, scale_, s) -> { @@ -2433,7 +2437,7 @@ public abstract class ShortVector extends AbstractVector { ShortVector rearrangeTemplate(Class shuffletype, S shuffle) { Objects.requireNonNull(shuffle); return VectorSupport.rearrangeOp( - getClass(), shuffletype, null, short.class, length(), + getClass(), shuffletype, null, laneTypeOrdinal(), length(), this, shuffle, null, (v1, s_, m_) -> v1.uOp((i, a) -> { int ei = Integer.remainderUnsigned(s_.laneSource(i), v1.length()); @@ -2460,7 +2464,7 @@ public abstract class ShortVector extends AbstractVector { Objects.requireNonNull(shuffle); m.check(masktype, this); return VectorSupport.rearrangeOp( - getClass(), shuffletype, masktype, short.class, length(), + getClass(), shuffletype, masktype, laneTypeOrdinal(), length(), this, shuffle, m, (v1, s_, m_) -> v1.uOp((i, a) -> { int ei = Integer.remainderUnsigned(s_.laneSource(i), v1.length()); @@ -2486,7 +2490,7 @@ public abstract class ShortVector extends AbstractVector { VectorMask valid = shuffle.laneIsValid(); ShortVector r0 = VectorSupport.rearrangeOp( - getClass(), shuffletype, null, short.class, length(), + getClass(), shuffletype, null, laneTypeOrdinal(), length(), this, shuffle, null, (v0, s_, m_) -> v0.uOp((i, a) -> { int ei = Integer.remainderUnsigned(s_.laneSource(i), v0.length()); @@ -2494,7 +2498,7 @@ public abstract class ShortVector extends AbstractVector { })); ShortVector r1 = VectorSupport.rearrangeOp( - getClass(), shuffletype, null, short.class, length(), + getClass(), shuffletype, null, laneTypeOrdinal(), length(), v, shuffle, null, (v1, s_, m_) -> v1.uOp((i, a) -> { int ei = Integer.remainderUnsigned(s_.laneSource(i), v1.length()); @@ -2544,7 +2548,7 @@ public abstract class ShortVector extends AbstractVector { ShortVector compressTemplate(Class masktype, M m) { m.check(masktype, this); return (ShortVector) VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_COMPRESS, getClass(), masktype, - short.class, length(), this, m, + laneTypeOrdinal(), length(), this, m, (v1, m1) -> compressHelper(v1, m1)); } @@ -2563,7 +2567,7 @@ public abstract class ShortVector extends AbstractVector { ShortVector expandTemplate(Class masktype, M m) { m.check(masktype, this); return (ShortVector) VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_EXPAND, getClass(), masktype, - short.class, length(), this, m, + laneTypeOrdinal(), length(), this, m, (v1, m1) -> expandHelper(v1, m1)); } @@ -2578,7 +2582,7 @@ public abstract class ShortVector extends AbstractVector { /*package-private*/ @ForceInline final ShortVector selectFromTemplate(ShortVector v) { - return (ShortVector)VectorSupport.selectFromOp(getClass(), null, short.class, + return (ShortVector)VectorSupport.selectFromOp(getClass(), null, laneTypeOrdinal(), length(), this, v, null, (v1, v2, _m) -> v2.rearrange(v1.toShuffle())); @@ -2598,7 +2602,7 @@ public abstract class ShortVector extends AbstractVector { ShortVector selectFromTemplate(ShortVector v, Class masktype, M m) { m.check(masktype, this); - return (ShortVector)VectorSupport.selectFromOp(getClass(), masktype, short.class, + return (ShortVector)VectorSupport.selectFromOp(getClass(), masktype, laneTypeOrdinal(), length(), this, v, m, (v1, v2, _m) -> v2.rearrange(v1.toShuffle(), _m)); @@ -2616,7 +2620,7 @@ public abstract class ShortVector extends AbstractVector { /*package-private*/ @ForceInline final ShortVector selectFromTemplate(ShortVector v1, ShortVector v2) { - return VectorSupport.selectFromTwoVectorOp(getClass(), short.class, length(), this, v1, v2, + return VectorSupport.selectFromTwoVectorOp(getClass(), laneTypeOrdinal(), length(), this, v1, v2, (vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)); } @@ -2836,7 +2840,7 @@ public abstract class ShortVector extends AbstractVector { } int opc = opCode(op); return fromBits(VectorSupport.reductionCoerced( - opc, getClass(), maskClass, short.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, m, REDUCE_IMPL.find(op, opc, ShortVector::reductionOperations))); } @@ -2854,7 +2858,7 @@ public abstract class ShortVector extends AbstractVector { } int opc = opCode(op); return fromBits(VectorSupport.reductionCoerced( - opc, getClass(), null, short.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, null, REDUCE_IMPL.find(op, opc, ShortVector::reductionOperations))); } @@ -3137,7 +3141,7 @@ public abstract class ShortVector extends AbstractVector { } return VectorSupport.loadWithMap( - vectorType, null, short.class, vsp.laneCount(), + vectorType, null, LANE_TYPE_ORDINAL, vsp.laneCount(), lsp.vectorType(), lsp.length(), a, ARRAY_BASE, vix0, vix1, null, null, null, a, offset, indexMap, mapOffset, vsp, @@ -3470,7 +3474,7 @@ public abstract class ShortVector extends AbstractVector { offset = checkFromIndexSize(offset, length(), a.length); ShortSpecies vsp = vspecies(); VectorSupport.store( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, this, a, offset, @@ -3619,7 +3623,7 @@ public abstract class ShortVector extends AbstractVector { offset = checkFromIndexSize(offset, length(), a.length); ShortSpecies vsp = vspecies(); VectorSupport.store( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), a, charArrayAddress(a, offset), false, this, a, offset, @@ -3824,7 +3828,7 @@ public abstract class ShortVector extends AbstractVector { ShortVector fromArray0Template(short[] a, int offset) { ShortSpecies vsp = vspecies(); return VectorSupport.load( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, a, offset, vsp, (arr, off, s) -> s.ldOp(arr, (int) off, @@ -3841,7 +3845,7 @@ public abstract class ShortVector extends AbstractVector { m.check(species()); ShortSpecies vsp = vspecies(); return VectorSupport.loadMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, m, offsetInRange, a, offset, vsp, (arr, off, s, vm) -> s.ldOp(arr, (int) off, vm, @@ -3888,7 +3892,7 @@ public abstract class ShortVector extends AbstractVector { } return VectorSupport.loadWithMap( - vectorType, maskClass, short.class, vsp.laneCount(), + vectorType, maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), lsp.vectorType(), lsp.length(), a, ARRAY_BASE, vix0, vix1, null, null, m, a, offset, indexMap, mapOffset, vsp, @@ -3904,7 +3908,7 @@ public abstract class ShortVector extends AbstractVector { ShortVector fromCharArray0Template(char[] a, int offset) { ShortSpecies vsp = vspecies(); return VectorSupport.load( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), a, charArrayAddress(a, offset), false, a, offset, vsp, (arr, off, s) -> s.ldOp(arr, (int) off, @@ -3921,7 +3925,7 @@ public abstract class ShortVector extends AbstractVector { m.check(species()); ShortSpecies vsp = vspecies(); return VectorSupport.loadMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), a, charArrayAddress(a, offset), false, m, offsetInRange, a, offset, vsp, (arr, off, s, vm) -> s.ldOp(arr, (int) off, vm, @@ -3936,7 +3940,7 @@ public abstract class ShortVector extends AbstractVector { ShortVector fromMemorySegment0Template(MemorySegment ms, long offset) { ShortSpecies vsp = vspecies(); return ScopedMemoryAccess.loadFromMemorySegment( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), (AbstractMemorySegmentImpl) ms, offset, vsp, (msp, off, s) -> { return s.ldLongOp((MemorySegment) msp, off, ShortVector::memorySegmentGet); @@ -3952,7 +3956,7 @@ public abstract class ShortVector extends AbstractVector { ShortSpecies vsp = vspecies(); m.check(vsp); return ScopedMemoryAccess.loadFromMemorySegmentMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), (AbstractMemorySegmentImpl) ms, offset, m, vsp, offsetInRange, (msp, off, s, vm) -> { return s.ldLongOp((MemorySegment) msp, off, vm, ShortVector::memorySegmentGet); @@ -3970,7 +3974,7 @@ public abstract class ShortVector extends AbstractVector { void intoArray0Template(short[] a, int offset) { ShortSpecies vsp = vspecies(); VectorSupport.store( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, this, a, offset, (arr, off, v) @@ -3987,7 +3991,7 @@ public abstract class ShortVector extends AbstractVector { m.check(species()); ShortSpecies vsp = vspecies(); VectorSupport.storeMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, this, m, a, offset, (arr, off, v, vm) @@ -4002,7 +4006,7 @@ public abstract class ShortVector extends AbstractVector { void intoMemorySegment0(MemorySegment ms, long offset) { ShortSpecies vsp = vspecies(); ScopedMemoryAccess.storeIntoMemorySegment( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), this, (AbstractMemorySegmentImpl) ms, offset, (msp, off, v) -> { @@ -4019,7 +4023,7 @@ public abstract class ShortVector extends AbstractVector { ShortSpecies vsp = vspecies(); m.check(vsp); ScopedMemoryAccess.storeIntoMemorySegmentMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), this, m, (AbstractMemorySegmentImpl) ms, offset, (msp, off, v, vm) -> { @@ -4037,7 +4041,7 @@ public abstract class ShortVector extends AbstractVector { m.check(species()); ShortSpecies vsp = vspecies(); VectorSupport.storeMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), a, charArrayAddress(a, offset), false, this, m, a, offset, (arr, off, v, vm) @@ -4074,6 +4078,18 @@ public abstract class ShortVector extends AbstractVector { return this; } + @Override + @ForceInline + final + ShortVector swapIfNeeded(AbstractSpecies srcSpecies) { + int subLanesPerSrc = subLanesToSwap(srcSpecies); + if (subLanesPerSrc < 0) { + return this; + } + VectorShuffle shuffle = normalizeSubLanesForSpecies(this.vspecies(), subLanesPerSrc); + return (ShortVector) this.rearrange(shuffle); + } + static final int ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_SHORT_INDEX_SCALE); static final long ARRAY_BASE = @@ -4257,7 +4273,7 @@ public abstract class ShortVector extends AbstractVector { final ShortVector broadcastBits(long bits) { return (ShortVector) VectorSupport.fromBitsCoerced( - vectorType, short.class, laneCount, + vectorType, laneTypeOrdinal(), laneCount, bits, MODE_BROADCAST, this, (bits_, s_) -> s_.rvOp(i -> bits_)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorMask.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorMask.java index eb231597e85..13ee9e27e0d 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorMask.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorMask.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -207,7 +207,7 @@ public abstract class VectorMask extends jdk.internal.vm.vector.VectorSupport int laneCount = vsp.laneCount(); offset = VectorIntrinsics.checkFromIndexSize(offset, laneCount, bits.length); return VectorSupport.load( - vsp.maskType(), vsp.elementType(), laneCount, + vsp.maskType(), vsp.laneTypeOrdinal(), laneCount, bits, (long) offset + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET, false, bits, offset, vsp, (c, idx, s) @@ -240,7 +240,7 @@ public abstract class VectorMask extends jdk.internal.vm.vector.VectorSupport public static VectorMask fromLong(VectorSpecies species, long bits) { AbstractSpecies vsp = (AbstractSpecies) species; bits = bits & (0xFFFFFFFFFFFFFFFFL >>> (64 - vsp.laneCount())); - return VectorSupport.fromBitsCoerced(vsp.maskType(), vsp.elementType(), vsp.laneCount(), bits, + return VectorSupport.fromBitsCoerced(vsp.maskType(), vsp.laneTypeOrdinal(), vsp.laneCount(), bits, VectorSupport.MODE_BITS_COERCED_LONG_TO_MASK, vsp, (m, s) -> { if (m == (m >> 1)) { diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorOperators.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorOperators.java index 34ab05046e0..84009c55ac9 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorOperators.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorOperators.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -817,8 +817,8 @@ public abstract class VectorOperators { private static ConversionImpl convert(String name, char kind, Class dom, Class ran, int opCode, int flags) { - int domran = ((LaneType.of(dom).basicType << VO_DOM_SHIFT) + - (LaneType.of(ran).basicType << VO_RAN_SHIFT)); + int domran = ((LaneType.of(dom).ordinal() << VO_DOM_SHIFT) + + (LaneType.of(ran).ordinal() << VO_RAN_SHIFT)); if (opCode >= 0) { if ((opCode & VO_DOM_RAN_MASK) == 0) { opCode += domran; @@ -945,10 +945,10 @@ public abstract class VectorOperators { @ForceInline /*package-private*/ - boolean compatibleWith(LaneType laneType) { - if (laneType.elementKind == 'F') { + boolean compatibleWith(LaneType type) { + if (type.elementKind == 'F') { return !opKind(VO_NOFP); - } else if (laneType.elementKind == 'I') { + } else if (type.elementKind == 'I') { return !opKind(VO_ONLYFP); } else { throw new AssertionError(); @@ -1077,8 +1077,8 @@ public abstract class VectorOperators { String name; Class domType = dom.elementType; Class ranType = ran.elementType; - int domCode = (dom.basicType << VO_DOM_SHIFT); - int ranCode = (ran.basicType << VO_RAN_SHIFT); + int domCode = (dom.ordinal() << VO_DOM_SHIFT); + int ranCode = (ran.ordinal() << VO_RAN_SHIFT); int opCode = domCode + ranCode; switch (kind) { case 'I': @@ -1156,16 +1156,16 @@ public abstract class VectorOperators { switch (conv.kind) { case 'W': int domCode = (opc >> VO_DOM_SHIFT) & 0xF; - dom = LaneType.ofBasicType(domCode); + dom = LaneType.ofLaneTypeOrdinal(domCode); break; case 'N': int ranCode = (opc >> VO_RAN_SHIFT) & 0xF; - ran = LaneType.ofBasicType(ranCode); + ran = LaneType.ofLaneTypeOrdinal(ranCode); break; } assert((opc & VO_DOM_RAN_MASK) == - ((dom.basicType << VO_DOM_SHIFT) + - (ran.basicType << VO_RAN_SHIFT))); + ((dom.ordinal() << VO_DOM_SHIFT) + + (ran.ordinal() << VO_RAN_SHIFT))); ConversionImpl[] cache = cacheOf(conv.kind, dom); int ranKey = ran.switchKey; if (cache[ranKey] != conv) { @@ -1233,12 +1233,12 @@ public abstract class VectorOperators { break; case 'W': doc = "In-place widen {@code _domVal} inside _ran to {@code (_ran)_domVal}"; - LaneType logdom = LaneType.ofBasicType(domran >> VO_DOM_SHIFT & 0xF); + LaneType logdom = LaneType.ofLaneTypeOrdinal(domran >> VO_DOM_SHIFT & 0xF); doc = doc.replace("_dom", logdom.elementType.getSimpleName()); break; case 'N': doc = "In-place narrow {@code _domVal} to {@code (_ran)_domVal} inside _dom"; - LaneType logran = LaneType.ofBasicType(domran >> VO_RAN_SHIFT & 0xF); + LaneType logran = LaneType.ofLaneTypeOrdinal(domran >> VO_RAN_SHIFT & 0xF); doc = doc.replace("_ran", logran.elementType.getSimpleName()); break; default: diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-Vector.java.template b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-Vector.java.template index ce3b7512c93..03883cf3e8a 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-Vector.java.template +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-Vector.java.template @@ -63,6 +63,10 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { static final ValueLayout.Of$Type$ ELEMENT_LAYOUT = ValueLayout.JAVA_$TYPE$.withByteAlignment(1); + static final int LANE_TYPE_ORDINAL = $laneType$; + + static final int LANEBITS_TYPE_ORDINAL = $lanebitsType$; + @ForceInline static int opCode(Operator op) { return VectorOperators.opCode(op, VO_OPCODE_VALID, FORBID_OPCODE_KIND); @@ -588,11 +592,11 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { public static $abstractvectortype$ zero(VectorSpecies<$Boxtype$> species) { $Type$Species vsp = ($Type$Species) species; #if[FP] - return VectorSupport.fromBitsCoerced(vsp.vectorType(), $type$.class, species.length(), + return VectorSupport.fromBitsCoerced(vsp.vectorType(), LANE_TYPE_ORDINAL, species.length(), toBits(0.0f), MODE_BROADCAST, vsp, ((bits_, s_) -> s_.rvOp(i -> bits_))); #else[FP] - return VectorSupport.fromBitsCoerced(vsp.vectorType(), $type$.class, species.length(), + return VectorSupport.fromBitsCoerced(vsp.vectorType(), LANE_TYPE_ORDINAL, species.length(), 0, MODE_BROADCAST, vsp, ((bits_, s_) -> s_.rvOp(i -> bits_))); #end[FP] @@ -724,7 +728,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { } int opc = opCode(op); return VectorSupport.unaryOp( - opc, getClass(), null, $type$.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, null, UN_IMPL.find(op, opc, $abstractvectortype$::unaryOperations)); } @@ -759,7 +763,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { } int opc = opCode(op); return VectorSupport.unaryOp( - opc, getClass(), maskClass, $type$.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, m, UN_IMPL.find(op, opc, $abstractvectortype$::unaryOperations)); } @@ -903,7 +907,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { int opc = opCode(op); return VectorSupport.binaryOp( - opc, getClass(), null, $type$.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, that, null, BIN_IMPL.find(op, opc, $abstractvectortype$::binaryOperations)); } @@ -970,7 +974,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { int opc = opCode(op); return VectorSupport.binaryOp( - opc, getClass(), maskClass, $type$.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, that, m, BIN_IMPL.find(op, opc, $abstractvectortype$::binaryOperations)); } @@ -1198,7 +1202,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { e &= SHIFT_MASK; int opc = opCode(op); return VectorSupport.broadcastInt( - opc, getClass(), null, $type$.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, e, null, BIN_INT_IMPL.find(op, opc, $abstractvectortype$::broadcastIntOperations)); } @@ -1219,7 +1223,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { e &= SHIFT_MASK; int opc = opCode(op); return VectorSupport.broadcastInt( - opc, getClass(), maskClass, $type$.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, e, m, BIN_INT_IMPL.find(op, opc, $abstractvectortype$::broadcastIntOperations)); } @@ -1303,7 +1307,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { #end[BITWISE] int opc = opCode(op); return VectorSupport.ternaryOp( - opc, getClass(), null, $type$.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, that, tother, null, TERN_IMPL.find(op, opc, $abstractvectortype$::ternaryOperations)); } @@ -1345,7 +1349,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { #end[BITWISE] int opc = opCode(op); return VectorSupport.ternaryOp( - opc, getClass(), maskClass, $type$.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, that, tother, m, TERN_IMPL.find(op, opc, $abstractvectortype$::ternaryOperations)); } @@ -2477,7 +2481,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { that.check(this); int opc = opCode(op); return VectorSupport.compare( - opc, getClass(), maskType, $type$.class, length(), + opc, getClass(), maskType, laneTypeOrdinal(), length(), this, that, null, (cond, v0, v1, m1) -> { AbstractMask<$Boxtype$> m @@ -2499,7 +2503,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { m.check(maskType, this); int opc = opCode(op); return VectorSupport.compare( - opc, getClass(), maskType, $type$.class, length(), + opc, getClass(), maskType, laneTypeOrdinal(), length(), this, that, m, (cond, v0, v1, m1) -> { AbstractMask<$Boxtype$> cmpM @@ -2634,7 +2638,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { blendTemplate(Class maskType, $abstractvectortype$ v, M m) { v.check(this); return VectorSupport.blend( - getClass(), maskType, $type$.class, length(), + getClass(), maskType, laneTypeOrdinal(), length(), this, v, m, (v0, v1, m_) -> v0.bOp(v1, m_, (i, a, b) -> b)); } @@ -2651,7 +2655,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { // make sure VLENGTH*scale doesn't overflow: vsp.checkScale(scale); return VectorSupport.indexVector( - getClass(), $type$.class, length(), + getClass(), laneTypeOrdinal(), length(), this, scale, vsp, (v, scale_, s) -> { @@ -2865,7 +2869,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { $abstractvectortype$ rearrangeTemplate(Class shuffletype, S shuffle) { Objects.requireNonNull(shuffle); return VectorSupport.rearrangeOp( - getClass(), shuffletype, null, $type$.class, length(), + getClass(), shuffletype, null, laneTypeOrdinal(), length(), this, shuffle, null, (v1, s_, m_) -> v1.uOp((i, a) -> { int ei = Integer.remainderUnsigned(s_.laneSource(i), v1.length()); @@ -2892,7 +2896,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { Objects.requireNonNull(shuffle); m.check(masktype, this); return VectorSupport.rearrangeOp( - getClass(), shuffletype, masktype, $type$.class, length(), + getClass(), shuffletype, masktype, laneTypeOrdinal(), length(), this, shuffle, m, (v1, s_, m_) -> v1.uOp((i, a) -> { int ei = Integer.remainderUnsigned(s_.laneSource(i), v1.length()); @@ -2918,7 +2922,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { VectorMask<$Boxtype$> valid = shuffle.laneIsValid(); $abstractvectortype$ r0 = VectorSupport.rearrangeOp( - getClass(), shuffletype, null, $type$.class, length(), + getClass(), shuffletype, null, laneTypeOrdinal(), length(), this, shuffle, null, (v0, s_, m_) -> v0.uOp((i, a) -> { int ei = Integer.remainderUnsigned(s_.laneSource(i), v0.length()); @@ -2926,7 +2930,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { })); $abstractvectortype$ r1 = VectorSupport.rearrangeOp( - getClass(), shuffletype, null, $type$.class, length(), + getClass(), shuffletype, null, laneTypeOrdinal(), length(), v, shuffle, null, (v1, s_, m_) -> v1.uOp((i, a) -> { int ei = Integer.remainderUnsigned(s_.laneSource(i), v1.length()); @@ -2988,7 +2992,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { $Type$Vector compressTemplate(Class masktype, M m) { m.check(masktype, this); return ($Type$Vector) VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_COMPRESS, getClass(), masktype, - $type$.class, length(), this, m, + laneTypeOrdinal(), length(), this, m, (v1, m1) -> compressHelper(v1, m1)); } @@ -3007,7 +3011,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { $Type$Vector expandTemplate(Class masktype, M m) { m.check(masktype, this); return ($Type$Vector) VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_EXPAND, getClass(), masktype, - $type$.class, length(), this, m, + laneTypeOrdinal(), length(), this, m, (v1, m1) -> expandHelper(v1, m1)); } @@ -3022,7 +3026,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { /*package-private*/ @ForceInline final $abstractvectortype$ selectFromTemplate($abstractvectortype$ v) { - return ($Type$Vector)VectorSupport.selectFromOp(getClass(), null, $type$.class, + return ($Type$Vector)VectorSupport.selectFromOp(getClass(), null, laneTypeOrdinal(), length(), this, v, null, (v1, v2, _m) -> v2.rearrange(v1.toShuffle())); @@ -3042,7 +3046,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { $abstractvectortype$ selectFromTemplate($abstractvectortype$ v, Class masktype, M m) { m.check(masktype, this); - return ($Type$Vector)VectorSupport.selectFromOp(getClass(), masktype, $type$.class, + return ($Type$Vector)VectorSupport.selectFromOp(getClass(), masktype, laneTypeOrdinal(), length(), this, v, m, (v1, v2, _m) -> v2.rearrange(v1.toShuffle(), _m)); @@ -3060,7 +3064,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { /*package-private*/ @ForceInline final $abstractvectortype$ selectFromTemplate($abstractvectortype$ v1, $abstractvectortype$ v2) { - return VectorSupport.selectFromTwoVectorOp(getClass(), $type$.class, length(), this, v1, v2, + return VectorSupport.selectFromTwoVectorOp(getClass(), laneTypeOrdinal(), length(), this, v1, v2, (vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)); } @@ -3409,7 +3413,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { } int opc = opCode(op); return fromBits(VectorSupport.reductionCoerced( - opc, getClass(), maskClass, $type$.class, length(), + opc, getClass(), maskClass, laneTypeOrdinal(), length(), this, m, REDUCE_IMPL.find(op, opc, $abstractvectortype$::reductionOperations))); } @@ -3427,7 +3431,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { } int opc = opCode(op); return fromBits(VectorSupport.reductionCoerced( - opc, getClass(), null, $type$.class, length(), + opc, getClass(), null, laneTypeOrdinal(), length(), this, null, REDUCE_IMPL.find(op, opc, $abstractvectortype$::reductionOperations))); } @@ -3789,7 +3793,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { } return VectorSupport.loadWithMap( - vectorType, null, $type$.class, vsp.laneCount(), + vectorType, null, LANE_TYPE_ORDINAL, vsp.laneCount(), lsp.vectorType(), lsp.length(), a, ARRAY_BASE, vix0, vix1, vix2, vix3, null, a, offset, indexMap, mapOffset, vsp, @@ -3797,7 +3801,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { s.vOp(n -> c[idx + iMap[idy+n]])); #else[byte] return VectorSupport.loadWithMap( - vectorType, null, $type$.class, vsp.laneCount(), + vectorType, null, LANE_TYPE_ORDINAL, vsp.laneCount(), lsp.vectorType(), lsp.length(), a, ARRAY_BASE, vix0, vix1, null, null, null, a, offset, indexMap, mapOffset, vsp, @@ -3850,7 +3854,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { vix = VectorIntrinsics.checkIndex(vix, a.length); return VectorSupport.loadWithMap( - vectorType, null, $type$.class, vsp.laneCount(), + vectorType, null, LANE_TYPE_ORDINAL, vsp.laneCount(), isp.vectorType(), isp.length(), a, ARRAY_BASE, vix, null, null, null, null, a, offset, indexMap, mapOffset, vsp, @@ -4349,7 +4353,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { offset = checkFromIndexSize(offset, length(), a.length); $Type$Species vsp = vspecies(); VectorSupport.store( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, this, a, offset, @@ -4476,7 +4480,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { vix = VectorIntrinsics.checkIndex(vix, a.length); VectorSupport.storeWithMap( - vsp.vectorType(), null, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), null, LANE_TYPE_ORDINAL, vsp.laneCount(), isp.vectorType(), isp.length(), a, arrayAddress(a, 0), vix, this, null, @@ -4569,7 +4573,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { offset = checkFromIndexSize(offset, length(), a.length); $Type$Species vsp = vspecies(); VectorSupport.store( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), a, charArrayAddress(a, offset), false, this, a, offset, @@ -4731,7 +4735,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { $Type$Species vsp = vspecies(); ByteVector normalized = this.and((byte) 1); VectorSupport.store( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), a, booleanArrayAddress(a, offset), false, normalized, a, offset, @@ -4945,7 +4949,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { $abstractvectortype$ fromArray0Template($type$[] a, int offset) { $Type$Species vsp = vspecies(); return VectorSupport.load( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, a, offset, vsp, (arr, off, s) -> s.ldOp(arr, (int) off, @@ -4962,7 +4966,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { m.check(species()); $Type$Species vsp = vspecies(); return VectorSupport.loadMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, m, offsetInRange, a, offset, vsp, (arr, off, s, vm) -> s.ldOp(arr, (int) off, vm, @@ -5020,7 +5024,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { } return VectorSupport.loadWithMap( - vectorType, maskClass, $type$.class, vsp.laneCount(), + vectorType, maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), lsp.vectorType(), lsp.length(), a, ARRAY_BASE, vix0, vix1, vix2, vix3, m, a, offset, indexMap, mapOffset, vsp, @@ -5028,7 +5032,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { s.vOp(vm, n -> c[idx + iMap[idy+n]])); #else[byte] return VectorSupport.loadWithMap( - vectorType, maskClass, $type$.class, vsp.laneCount(), + vectorType, maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), lsp.vectorType(), lsp.length(), a, ARRAY_BASE, vix0, vix1, null, null, m, a, offset, indexMap, mapOffset, vsp, @@ -5083,7 +5087,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { vix = VectorIntrinsics.checkIndex(vix, a.length); return VectorSupport.loadWithMap( - vectorType, maskClass, $type$.class, vsp.laneCount(), + vectorType, maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), isp.vectorType(), isp.length(), a, ARRAY_BASE, vix, null, null, null, m, a, offset, indexMap, mapOffset, vsp, @@ -5101,7 +5105,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { $abstractvectortype$ fromCharArray0Template(char[] a, int offset) { $Type$Species vsp = vspecies(); return VectorSupport.load( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), a, charArrayAddress(a, offset), false, a, offset, vsp, (arr, off, s) -> s.ldOp(arr, (int) off, @@ -5118,7 +5122,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { m.check(species()); $Type$Species vsp = vspecies(); return VectorSupport.loadMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), a, charArrayAddress(a, offset), false, m, offsetInRange, a, offset, vsp, (arr, off, s, vm) -> s.ldOp(arr, (int) off, vm, @@ -5135,7 +5139,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { $abstractvectortype$ fromBooleanArray0Template(boolean[] a, int offset) { $Type$Species vsp = vspecies(); return VectorSupport.load( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), a, booleanArrayAddress(a, offset), false, a, offset, vsp, (arr, off, s) -> s.ldOp(arr, (int) off, @@ -5152,7 +5156,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { m.check(species()); $Type$Species vsp = vspecies(); return VectorSupport.loadMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), a, booleanArrayAddress(a, offset), false, m, offsetInRange, a, offset, vsp, (arr, off, s, vm) -> s.ldOp(arr, (int) off, vm, @@ -5167,7 +5171,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { $abstractvectortype$ fromMemorySegment0Template(MemorySegment ms, long offset) { $Type$Species vsp = vspecies(); return ScopedMemoryAccess.loadFromMemorySegment( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), (AbstractMemorySegmentImpl) ms, offset, vsp, (msp, off, s) -> { return s.ldLongOp((MemorySegment) msp, off, $abstractvectortype$::memorySegmentGet); @@ -5183,7 +5187,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { $Type$Species vsp = vspecies(); m.check(vsp); return ScopedMemoryAccess.loadFromMemorySegmentMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), (AbstractMemorySegmentImpl) ms, offset, m, vsp, offsetInRange, (msp, off, s, vm) -> { return s.ldLongOp((MemorySegment) msp, off, vm, $abstractvectortype$::memorySegmentGet); @@ -5201,7 +5205,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { void intoArray0Template($type$[] a, int offset) { $Type$Species vsp = vspecies(); VectorSupport.store( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, this, a, offset, (arr, off, v) @@ -5218,7 +5222,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { m.check(species()); $Type$Species vsp = vspecies(); VectorSupport.storeMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), a, arrayAddress(a, offset), false, this, m, a, offset, (arr, off, v, vm) @@ -5274,7 +5278,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { vix = VectorIntrinsics.checkIndex(vix, a.length); VectorSupport.storeWithMap( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), isp.vectorType(), isp.length(), a, arrayAddress(a, 0), vix, this, m, @@ -5299,7 +5303,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { $Type$Species vsp = vspecies(); ByteVector normalized = this.and((byte) 1); VectorSupport.storeMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), a, booleanArrayAddress(a, offset), false, normalized, m, a, offset, (arr, off, v, vm) @@ -5313,7 +5317,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { void intoMemorySegment0(MemorySegment ms, long offset) { $Type$Species vsp = vspecies(); ScopedMemoryAccess.storeIntoMemorySegment( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), LANE_TYPE_ORDINAL, vsp.laneCount(), this, (AbstractMemorySegmentImpl) ms, offset, (msp, off, v) -> { @@ -5330,7 +5334,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { $Type$Species vsp = vspecies(); m.check(vsp); ScopedMemoryAccess.storeIntoMemorySegmentMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), this, m, (AbstractMemorySegmentImpl) ms, offset, (msp, off, v, vm) -> { @@ -5349,7 +5353,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { m.check(species()); $Type$Species vsp = vspecies(); VectorSupport.storeMasked( - vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), + vsp.vectorType(), maskClass, LANE_TYPE_ORDINAL, vsp.laneCount(), a, charArrayAddress(a, offset), false, this, m, a, offset, (arr, off, v, vm) @@ -5604,7 +5608,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { final $abstractvectortype$ broadcastBits(long bits) { return ($abstractvectortype$) VectorSupport.fromBitsCoerced( - vectorType, $type$.class, laneCount, + vectorType, laneTypeOrdinal(), laneCount, bits, MODE_BROADCAST, this, (bits_, s_) -> s_.rvOp(i -> bits_)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-VectorBits.java.template b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-VectorBits.java.template index fa502e3f29a..61ac02d84f6 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-VectorBits.java.template +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-VectorBits.java.template @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,13 @@ final class $vectortype$ extends $abstractvectortype$ { return ($type$[])getPayload(); } + /*package-private*/ + @ForceInline + final @Override + int laneTypeOrdinal() { + return LANE_TYPE_ORDINAL; + } + // Virtualized constructors @Override @@ -577,7 +584,7 @@ final class $vectortype$ extends $abstractvectortype$ { @ForceInline public $bitstype$ laneHelper(int i) { return ($bitstype$) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { $type$[] vecarr = vec.vec(); @@ -627,7 +634,7 @@ final class $vectortype$ extends $abstractvectortype$ { @ForceInline public $vectortype$ withLaneHelper(int i, $type$ e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)$Type$.$type$ToRaw$Bitstype$Bits(e), (v, ix, bits) -> { $type$[] res = v.vec().clone(); @@ -730,7 +737,7 @@ final class $vectortype$ extends $abstractvectortype$ { @ForceInline public $type$ laneHelper(int i) { return ($type$) VectorSupport.extract( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (vec, ix) -> { $type$[] vecarr = vec.vec(); @@ -832,7 +839,7 @@ final class $vectortype$ extends $abstractvectortype$ { @ForceInline public $vectortype$ withLaneHelper(int i, $type$ e) { return VectorSupport.insert( - VCLASS, ETYPE, VLENGTH, + VCLASS, LANE_TYPE_ORDINAL, VLENGTH, this, i, (long)e, (v, ix, bits) -> { $type$[] res = v.vec().clone(); @@ -937,8 +944,8 @@ final class $vectortype$ extends $abstractvectortype$ { throw new IllegalArgumentException("VectorMask length and species length differ"); return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, - this.getClass(), ETYPE, VLENGTH, - species.maskType(), species.elementType(), VLENGTH, + this.getClass(), LANE_TYPE_ORDINAL, VLENGTH, + species.maskType(), species.laneTypeOrdinal(), VLENGTH, this, species, (m, s) -> s.maskFactory(m.toArray()).check(s)); } @@ -948,7 +955,7 @@ final class $vectortype$ extends $abstractvectortype$ { /*package-private*/ $masktype$ indexPartiallyInUpperRange(long offset, long limit) { return ($masktype$) VectorSupport.indexPartiallyInUpperRange( - $masktype$.class, $type$.class, VLENGTH, offset, limit, + $masktype$.class, LANE_TYPE_ORDINAL, VLENGTH, offset, limit, (o, l) -> ($masktype$) TRUE_MASK.indexPartiallyInRange(o, l)); } @@ -964,7 +971,7 @@ final class $vectortype$ extends $abstractvectortype$ { @ForceInline public $masktype$ compress() { return ($masktype$)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS, - $vectortype$.class, $masktype$.class, ETYPE, VLENGTH, null, this, + $vectortype$.class, $masktype$.class, LANE_TYPE_ORDINAL, VLENGTH, null, this, (v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount())); } @@ -976,7 +983,7 @@ final class $vectortype$ extends $abstractvectortype$ { public $masktype$ and(VectorMask<$Boxtype$> mask) { Objects.requireNonNull(mask); $masktype$ m = ($masktype$)mask; - return VectorSupport.binaryOp(VECTOR_OP_AND, $masktype$.class, null, $bitstype$.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_AND, $masktype$.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a & b)); } @@ -986,7 +993,7 @@ final class $vectortype$ extends $abstractvectortype$ { public $masktype$ or(VectorMask<$Boxtype$> mask) { Objects.requireNonNull(mask); $masktype$ m = ($masktype$)mask; - return VectorSupport.binaryOp(VECTOR_OP_OR, $masktype$.class, null, $bitstype$.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_OR, $masktype$.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a | b)); } @@ -996,7 +1003,7 @@ final class $vectortype$ extends $abstractvectortype$ { public $masktype$ xor(VectorMask<$Boxtype$> mask) { Objects.requireNonNull(mask); $masktype$ m = ($masktype$)mask; - return VectorSupport.binaryOp(VECTOR_OP_XOR, $masktype$.class, null, $bitstype$.class, VLENGTH, + return VectorSupport.binaryOp(VECTOR_OP_XOR, $masktype$.class, null, LANEBITS_TYPE_ORDINAL, VLENGTH, this, m, null, (m1, m2, vm) -> m1.bOp(m2, (i, a, b) -> a ^ b)); } @@ -1006,21 +1013,21 @@ final class $vectortype$ extends $abstractvectortype$ { @Override @ForceInline public int trueCount() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, $masktype$.class, $bitstype$.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TRUECOUNT, $masktype$.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> trueCountHelper(m.getBits())); } @Override @ForceInline public int firstTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, $masktype$.class, $bitstype$.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_FIRSTTRUE, $masktype$.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> firstTrueHelper(m.getBits())); } @Override @ForceInline public int lastTrue() { - return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, $masktype$.class, $bitstype$.class, VLENGTH, this, + return (int) VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_LASTTRUE, $masktype$.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> lastTrueHelper(m.getBits())); } @@ -1030,7 +1037,7 @@ final class $vectortype$ extends $abstractvectortype$ { if (length() > Long.SIZE) { throw new UnsupportedOperationException("too many lanes for one long"); } - return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, $masktype$.class, $bitstype$.class, VLENGTH, this, + return VectorSupport.maskReductionCoerced(VECTOR_OP_MASK_TOLONG, $masktype$.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, (m) -> toLongHelper(m.getBits())); } @@ -1040,7 +1047,7 @@ final class $vectortype$ extends $abstractvectortype$ { @ForceInline public boolean laneIsSet(int i) { Objects.checkIndex(i, length()); - return VectorSupport.extract($masktype$.class, $type$.class, VLENGTH, + return VectorSupport.extract($masktype$.class, LANE_TYPE_ORDINAL, VLENGTH, this, i, (m, idx) -> (m.getBits()[idx] ? 1L : 0L)) == 1L; } @@ -1049,7 +1056,7 @@ final class $vectortype$ extends $abstractvectortype$ { @Override @ForceInline public boolean anyTrue() { - return VectorSupport.test(BT_ne, $masktype$.class, $bitstype$.class, VLENGTH, + return VectorSupport.test(BT_ne, $masktype$.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> anyTrueHelper((($masktype$)m).getBits())); } @@ -1057,7 +1064,7 @@ final class $vectortype$ extends $abstractvectortype$ { @Override @ForceInline public boolean allTrue() { - return VectorSupport.test(BT_overflow, $masktype$.class, $bitstype$.class, VLENGTH, + return VectorSupport.test(BT_overflow, $masktype$.class, LANEBITS_TYPE_ORDINAL, VLENGTH, this, vspecies().maskAll(true), (m, __) -> allTrueHelper((($masktype$)m).getBits())); } @@ -1065,7 +1072,7 @@ final class $vectortype$ extends $abstractvectortype$ { @ForceInline /*package-private*/ static $masktype$ maskAll(boolean bit) { - return VectorSupport.fromBitsCoerced($masktype$.class, $bitstype$.class, VLENGTH, + return VectorSupport.fromBitsCoerced($masktype$.class, LANEBITS_TYPE_ORDINAL, VLENGTH, (bit ? -1 : 0), MODE_BROADCAST, null, (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/gen-src.sh b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/gen-src.sh index 6841a47c757..a9f1648eaa7 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/gen-src.sh +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/gen-src.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -77,11 +77,15 @@ do byte) Wideboxtype=Integer sizeInBytes=1 + laneType=LT_BYTE + lanebitsType=LT_BYTE args="$args -KbyteOrShort" ;; short) Wideboxtype=Integer sizeInBytes=2 + laneType=LT_SHORT + lanebitsType=LT_SHORT args="$args -KbyteOrShort" ;; int) @@ -92,6 +96,8 @@ do Fptype=Float Boxfptype=Float sizeInBytes=4 + laneType=LT_INT + lanebitsType=LT_INT args="$args -KintOrLong -KintOrFP -KintOrFloat" ;; long) @@ -99,6 +105,8 @@ do Fptype=Double Boxfptype=Double sizeInBytes=8 + laneType=LT_LONG + lanebitsType=LT_LONG args="$args -KintOrLong -KlongOrDouble" ;; float) @@ -107,6 +115,8 @@ do Bitstype=Int Boxbitstype=Integer sizeInBytes=4 + laneType=LT_FLOAT + lanebitsType=LT_INT args="$args -KintOrFP -KintOrFloat" ;; double) @@ -115,11 +125,13 @@ do Bitstype=Long Boxbitstype=Long sizeInBytes=8 + laneType=LT_DOUBLE + lanebitsType=LT_LONG args="$args -KintOrFP -KlongOrDouble" ;; esac - args="$args -K$kind -DBoxtype=$Boxtype -DWideboxtype=$Wideboxtype" + args="$args -K$kind -DlaneType=$laneType -DlanebitsType=$lanebitsType -DBoxtype=$Boxtype -DWideboxtype=$Wideboxtype" args="$args -Dbitstype=$bitstype -DBitstype=$Bitstype -DBoxbitstype=$Boxbitstype" args="$args -Dfptype=$fptype -DFptype=$Fptype -DBoxfptype=$Boxfptype" args="$args -DsizeInBytes=$sizeInBytes" diff --git a/src/jdk.jartool/share/classes/sun/tools/jar/Validator.java b/src/jdk.jartool/share/classes/sun/tools/jar/Validator.java index be694eeb1bc..c6f6f012543 100644 --- a/src/jdk.jartool/share/classes/sun/tools/jar/Validator.java +++ b/src/jdk.jartool/share/classes/sun/tools/jar/Validator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,6 +47,8 @@ import java.util.function.Function; import java.util.function.IntSupplier; import java.util.regex.Pattern; import java.util.stream.Collectors; +import java.util.jar.Attributes; +import java.util.jar.Manifest; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipInputStream; @@ -100,6 +102,7 @@ final class Validator { this.zf = zf; this.zis = zis; checkModuleDescriptor(MODULE_INFO); + checkAutomaticModuleName(); } static boolean validate(Main main, File zipFile) throws IOException { @@ -453,6 +456,36 @@ final class Validator { }); } + /** + * Checks whether an Automatic-Module-Name entry is valid + * and also verifies it to the name given by a compiled + * module descriptor. + */ + private void checkAutomaticModuleName() { + var entry = zf.getEntry("META-INF/MANIFEST.MF"); + if (entry == null) { + return; + } + try (InputStream jis = zf.getInputStream(entry)) { + Attributes attributes = new Manifest(jis).getMainAttributes(); + String automaticModuleName = attributes.getValue("Automatic-Module-Name"); + if (automaticModuleName == null) { + return; + } + try { + ModuleDescriptor.newAutomaticModule(automaticModuleName); + } catch (IllegalArgumentException e) { + errorAndInvalid(formatMsg("error.validator.manifest.invalid.automatic.module.name", automaticModuleName)); + } + if (md == null || automaticModuleName.equals(md.name())) { + return; + } + errorAndInvalid(formatMsg("error.validator.manifest.inconsistent.automatic.module.name", automaticModuleName, md.name())); + } catch (IOException e) { + errorAndInvalid(e.getMessage()); + } + } + /* * Checks whether or not the given versioned module descriptor's attributes * are valid when compared against the root/base module descriptor. diff --git a/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties b/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties index c80377e20c1..95c5f80197d 100644 --- a/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties +++ b/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties @@ -138,6 +138,10 @@ error.validator.metainf.wrong.position=\ expected entry META-INF/ to be at position 0, but found: {0} error.validator.manifest.wrong.position=\ expected entry META-INF/MANIFEST.MF to be at position 0 or 1, but found it at position: {0} +error.validator.manifest.invalid.automatic.module.name=\ + invalid module name of Automatic-Module-Name entry in manifest: {0} +error.validator.manifest.inconsistent.automatic.module.name=\ + expected Automatic-Module-Name entry in manifest: {0} to match name of compiled module: {1} warn.validator.identical.entry=\ Warning: entry {0} contains a class that\n\ is identical to an entry already in the jar diff --git a/src/jdk.jartool/share/man/jarsigner.md b/src/jdk.jartool/share/man/jarsigner.md index 0ecc159a037..d128b9c11ff 100644 --- a/src/jdk.jartool/share/man/jarsigner.md +++ b/src/jdk.jartool/share/man/jarsigner.md @@ -483,7 +483,7 @@ the following standards: `-keystore` option is relevant for signing and verifying a JAR file. In addition, aliases are specified when signing and verifying a JAR file. -`-keystore` *url* +[`-keystore`]{#option-keystore} *url* : Specifies the URL that tells the keystore location. This defaults to the file `.keystore` in the user's home directory, as determined by the `user.home` system property. @@ -517,7 +517,7 @@ the following standards: > `keytool -keystore NONE -storetype PKCS11 -list` -`-storepass` \[`:env` \| `:file`\] *argument* +[`-storepass`]{#option-storepass} \[`:env` \| `:file`\] *argument* : Specifies the password that is required to access the keystore. This is only needed when signing (not verifying) a JAR file. In that case, if a `-storepass` option isn't provided at the command line, then the user is @@ -536,7 +536,7 @@ the following standards: The password shouldn't be specified on the command line or in a script unless it is for testing purposes, or you are on a secure system. -`-storetype` *storetype* +[`-storetype`]{#option-storetype} *storetype* : Specifies the type of keystore to be instantiated. The default keystore type is the one that is specified as the value of the `keystore.type` property in the security properties file, which is returned by the static @@ -548,7 +548,7 @@ the following standards: (such as a dedicated PIN-pad or a biometric reader), then the `-protected` option must be specified and no password options can be specified. -`-keypass` \[`:env` \| `:file`\] *argument* `-certchain` *file* +[`-keypass`]{#option-keypass} \[`:env` \| `:file`\] *argument* `-certchain` *file* : Specifies the password used to protect the private key of the keystore entry addressed by the alias specified on the command line. The password is required when using `jarsigner` to sign a JAR file. If no password is @@ -568,7 +568,7 @@ the following standards: The password shouldn't be specified on the command line or in a script unless it is for testing purposes, or you are on a secure system. -`-certchain` *file* +[`-certchain`]{#option-certchain} *file* : Specifies the certificate chain to be used when the certificate chain associated with the private key of the keystore entry that is addressed by the alias specified on the command line isn't complete. This can happen @@ -579,7 +579,7 @@ the following standards: (also known as Base64 encoding) as defined by [Internet RFC 1421 Certificate Encoding Standard](http://tools.ietf.org/html/rfc1421). -`-sigfile` *file* +[`-sigfile`]{#option-sigfile} *file* : Specifies the base file name to be used for the generated `.SF` and signature block files. For example, if file is `DUKESIGN`, then the generated `.SF` and signature block files are named `DUKESIGN.SF` and `DUKESIGN.RSA`, and placed in the @@ -598,10 +598,10 @@ the following standards: file name, then each such character is converted to an underscore (\_) character to form the file name. -`-signedjar` *file* +[`-signedjar`]{#option-signedjar} *file* : Specifies the name of signed JAR file. -`-digestalg` *algorithm* +[`-digestalg`]{#option-digestalg} *algorithm* : Specifies the name of the message digest algorithm to use when digesting the entries of a JAR file. @@ -613,7 +613,7 @@ the following standards: specified algorithm or the user must specify one with the `-addprovider` or `-providerClass` options; otherwise, the command will not succeed. -`-sigalg` *algorithm* +[`-sigalg`]{#option-sigalg} *algorithm* : Specifies the name of the signature algorithm to use to sign the JAR file. This algorithm must be compatible with the private key used to sign the @@ -627,10 +627,10 @@ the following standards: For a list of standard signature algorithm names, see the Java Security Standard Algorithm Names Specification. -`-verify` +[`-verify`]{#option-verify} : Verifies a signed JAR file. -`-verbose`\[`:`*suboptions*\] +[`-verbose`]{#option-verbose}\[`:`*suboptions*\] : When the `-verbose` option appears on the command line, it indicates that the `jarsigner` use the verbose mode when signing or verifying with the suboptions determining how much information is shown. This causes the , @@ -654,7 +654,7 @@ the following standards: more)*. See [Example of Verifying a Signed JAR File] and [Example of Verification with Certificate Information]. -`-certs` +[`-certs`]{#option-certs} : If the `-certs` option appears on the command line with the `-verify` and `-verbose` options, then the output includes certificate information for each signer of the JAR file. This information includes the name of the type @@ -669,14 +669,14 @@ the following standards: the alias name for the keystore entry for that signer is displayed in parentheses. -`-revCheck` +[`-revCheck`]{#option-revCheck} : This option enables revocation checking of certificates when signing or verifying a JAR file. The `jarsigner` command attempts to make network connections to fetch OCSP responses and CRLs if the `-revCheck` option is specified on the command line. Note that revocation checks are not enabled unless this option is specified. -`-tsa` *url* +[`-tsa`]{#option-tsa} *url* : If `-tsa http://example.tsa.url` appears on the command line when signing a JAR file then a time stamp is generated for the signature. The URL, `http://example.tsa.url`, identifies the location of the Time Stamping @@ -689,7 +689,7 @@ the following standards: stamp token returned by the TSA is stored with the signature in the signature block file. -`-tsacert` *alias* +[`-tsacert`]{#option-tsacert} *alias* : When `-tsacert` *alias* appears on the command line when signing a JAR file, a time stamp is generated for the signature. The alias identifies the TSA public key certificate in the keystore that is in effect. The entry's @@ -699,7 +699,7 @@ the following standards: The TSA public key certificate must be present in the keystore when using the `-tsacert` option. -`-tsapolicyid` *policyid* +[`-tsapolicyid`]{#option-tsapolicyid} *policyid* : Specifies the object identifier (OID) that identifies the policy ID to be sent to the TSA server. If this option isn't specified, no policy ID is sent and the TSA server will choose a default policy ID. @@ -708,7 +708,7 @@ the following standards: Standardization Sector (ITU-T) standard. These identifiers are typically period-separated sets of non-negative digits like `1.2.3.4`, for example. -`-tsadigestalg` *algorithm* +[`-tsadigestalg`]{#option-tsadigestalg} *algorithm* : Specifies the message digest algorithm that is used to generate the message imprint to be sent to the TSA server. If this option isn't specified, SHA-384 will be used. @@ -718,7 +718,7 @@ the following standards: For a list of standard message digest algorithm names, see the Java Security Standard Algorithm Names Specification. -`-internalsf` +[`-internalsf`]{#option-internalsf} : In the past, the signature block file generated when a JAR file was signed included a complete encoded copy of the `.SF` file (signature file) also generated. This behavior has been changed. To reduce the overall @@ -728,7 +728,7 @@ the following standards: In practice, don't use the `-internalsf` option because it incurs higher overhead. -`-sectionsonly` +[`-sectionsonly`]{#option-sectionsonly} : If the `-sectionsonly` option appears on the command line, then the `.SF` file (signature file) generated when a JAR file is signed doesn't include a header that contains a hash of the whole manifest file. It contains only @@ -747,12 +747,12 @@ the following standards: The `-sectionsonly` option is primarily used for testing. It shouldn't be used other than for testing because using it incurs higher overhead. -`-protected` +[`-protected`]{#option-protected} : Values can be either `true` or `false`. Specify `true` when a password must be specified through a protected authentication path such as a dedicated PIN reader. -`-providerName` *providerName* +[`-providerName`]{#option-providerName} *providerName* : If more than one provider was configured in the `java.security` security properties file, then you can use the `-providerName` option to target a specific provider instance. The argument to this option is the name of the @@ -768,7 +768,7 @@ the following standards: > `jarsigner -keystore NONE -storetype PKCS11 -providerName SunPKCS11-SmartCard -list` -`-addprovider` *name* \[`-providerArg` *arg*\] +[`-addprovider`]{#option-addprovider} *name* \[`-providerArg` *arg*\] : Adds a security provider by name (such as SunPKCS11) and an optional configure argument. The value of the security provider is the name of a security provider that is defined in a module. @@ -782,7 +782,7 @@ the following standards: > `jarsigner -keystore NONE -storetype PKCS11 -addprovider SunPKCS11 -providerArg /mydir1/mydir2/token.config` -`-providerClass` *provider-class-name* \[`-providerArg` *arg*\] +[`-providerClass`]{#option-providerClass} *provider-class-name* \[`-providerArg` *arg*\] : Used to specify the name of cryptographic service provider's master class file when the service provider isn't listed in the `java.security` security properties file. Adds a security provider by fully-qualified class name and @@ -792,7 +792,7 @@ the following standards: The preferred way to load PKCS11 is by using modules. See `-addprovider`. -`-providerPath` *classpath* +[`-providerPath`]{#option-providerPath} *classpath* : Used to specify the classpath for providers specified by the `-providerClass` option. Multiple paths should be separated by the system-dependent path-separator character. @@ -804,13 +804,13 @@ the following standards: execution environment or memory usage. For a list of possible interpreter options, type `java -h` or `java -X` at the command line. -`-strict` +[`-strict`]{#option-strict} : During the signing or verifying process, the command may issue warning messages. If you specify this option, the exit code of the tool reflects the severe warning messages that this command found. See [Errors and Warnings]. -`-conf` *url* +[`-conf`]{#option-conf} *url* : Specifies a pre-configured options file. Read the [keytool documentation](keytool.html#pre-configured-options-file) for details. The property keys supported are "jarsigner.all" for all actions, @@ -818,7 +818,7 @@ the following standards: `jarsigner` arguments including the JAR file name and alias name(s) cannot be set in this file. -`-version` +[`-version`]{#option-version} : Prints the program version. ## Errors and Warnings diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/stylesheet.css b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/stylesheet.css index 53b9d8ca6b2..6198df5c2f3 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/stylesheet.css +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/stylesheet.css @@ -163,6 +163,13 @@ \ '); --current-theme-svg: url("moon.svg"); + div.block a[href], div.horizontal-scroll a[href], div.inherited-list h3 a[href], header > div a[href], + .hierarchy a[href], .index a[href], div.caption a[href], .sub-title a[href], .deprecation-comment a[href], + .serialized-class-details a[href] { + text-decoration: underline; + text-decoration-thickness: 0.02em; + text-underline-offset: 0.12em; + } } /* * Styles for individual HTML elements. diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocLog.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocLog.java index 84c32a4c732..b3bf1c14cb1 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocLog.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocLog.java @@ -55,7 +55,6 @@ import com.sun.source.doctree.TextTree; import com.sun.tools.javac.tree.DCTree.DCDocComment; import com.sun.tools.javac.tree.DCTree; -import com.sun.tools.javac.tree.EndPosTable; import com.sun.tools.javac.util.Context.Factory; import com.sun.tools.javac.util.DiagnosticSource; import com.sun.source.tree.CompilationUnitTree; @@ -616,7 +615,7 @@ public class JavadocLog extends Log implements Reporter { } @Override - public int getEndPosition(EndPosTable endPosTable) { + public int getEndPosition() { return end; } }; diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java index 825672cfe6d..3baae08eed6 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -248,8 +248,8 @@ public class JlinkTask { * Read the release.txt from the module. */ private static Optional getReleaseInfo(ModuleReference mref) { - try { - Optional release = mref.open().open(JDK_RELEASE_RESOURCE); + try (var moduleReader = mref.open()) { + Optional release = moduleReader.open(JDK_RELEASE_RESOURCE); if (release.isEmpty()) { return Optional.empty(); diff --git a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/AppImageSigner.java b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/AppImageSigner.java index 19ff78f174e..c908ec7447c 100644 --- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/AppImageSigner.java +++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/AppImageSigner.java @@ -24,7 +24,6 @@ */ package jdk.jpackage.internal; -import static java.util.stream.Collectors.joining; import static jdk.jpackage.internal.MacPackagingPipeline.APPLICATION_LAYOUT; import static jdk.jpackage.internal.model.MacPackage.RUNTIME_BUNDLE_LAYOUT; import static jdk.jpackage.internal.util.function.ThrowingConsumer.toConsumer; @@ -40,7 +39,6 @@ import java.util.Optional; import java.util.Set; import java.util.function.Consumer; import java.util.function.Predicate; -import java.util.stream.Stream; import jdk.jpackage.internal.Codesign.CodesignException; import jdk.jpackage.internal.model.Application; import jdk.jpackage.internal.model.ApplicationLayout; @@ -63,9 +61,10 @@ final class AppImageSigner { throw handleCodesignException(app, ex); } catch (ExceptionBox ex) { if (ex.getCause() instanceof CodesignException codesignEx) { - handleCodesignException(app, codesignEx); + throw handleCodesignException(app, codesignEx); + } else { + throw ex; } - throw ex; } }); } @@ -165,13 +164,9 @@ final class AppImageSigner { } } - private static CodesignException handleCodesignException(MacApplication app, CodesignException ex) { - // Log output of "codesign" in case of error. It should help - // user to diagnose issues when using --mac-app-image-sign-identity. - // In addition add possible reason for failure. For example - // "--app-content" can fail "codesign". - + private static IOException handleCodesignException(MacApplication app, CodesignException ex) { if (!app.contentDirSources().isEmpty()) { + // Additional content may cause signing error. Log.info(I18N.getString("message.codesign.failed.reason.app.content")); } @@ -182,11 +177,7 @@ final class AppImageSigner { Log.info(I18N.getString("message.codesign.failed.reason.xcode.tools")); } - // Log "codesign" output - Log.info(I18N.format("error.tool.failed.with.output", "codesign")); - Log.info(Stream.of(ex.getOutput()).collect(joining("\n")).strip()); - - return ex; + return ex.getCause(); } private static boolean isXcodeDevToolsInstalled() { diff --git a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/Codesign.java b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/Codesign.java index a7cd17b06b9..984202bbfaf 100644 --- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/Codesign.java +++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/Codesign.java @@ -34,22 +34,21 @@ import java.util.Objects; import java.util.Optional; import java.util.function.Consumer; import java.util.function.Supplier; - +import jdk.jpackage.internal.util.CommandOutputControl.UnexpectedExitCodeException; public final class Codesign { public static final class CodesignException extends Exception { - CodesignException(String[] output) { - this.output = output; + CodesignException(UnexpectedExitCodeException cause) { + super(Objects.requireNonNull(cause)); } - String[] getOutput() { - return output; + @Override + public UnexpectedExitCodeException getCause() { + return (UnexpectedExitCodeException)super.getCause(); } - private final String[] output; - private static final long serialVersionUID = 1L; } @@ -96,9 +95,10 @@ public final class Codesign { var exec = Executor.of(cmdline).args(path.toString()).saveOutput(true); configureExecutor.ifPresent(configure -> configure.accept(exec)); - var result = exec.execute(); - if (result.getExitCode() != 0) { - throw new CodesignException(result.getOutput().toArray(String[]::new)); + try { + exec.execute().expectExitCode(0); + } catch (UnexpectedExitCodeException ex) { + throw new CodesignException(ex); } } diff --git a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources.properties b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources.properties index 0237d49f399..e1b154c5933 100644 --- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources.properties +++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources.properties @@ -28,7 +28,6 @@ error.certificate.expired=Certificate expired {0} error.cert.not.found=No certificate found matching [{0}] using keychain [{1}] error.multiple.certs.found=Multiple certificates matching name [{0}] found in keychain [{1}] error.app-image.mac-sign.required=--mac-sign option is required with predefined application image and with type [app-image] -error.tool.failed.with.output="{0}" failed with following output: error.invalid-runtime-image-missing-file=Runtime image "{0}" is missing "{1}" file error.invalid-runtime-image-bin-dir=Runtime image "{0}" should not contain "bin" folder error.invalid-runtime-image-bin-dir.advice=Use --strip-native-commands jlink option when generating runtime image used with {0} option diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/CfgFile.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/CfgFile.java index 9cb9fb5cba0..7958dcdef2d 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/CfgFile.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/CfgFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -124,21 +124,19 @@ final class CfgFile { Files.write(cfgFile, (Iterable) lines::iterator); } - private record Referencies(Path appModsDirectory) { + private record Referencies(Path appModsDirectory, Path appDirectory) { Referencies { - if (!appModsDirectory.startsWith(appDirectory())) { + if (!appModsDirectory.startsWith(appDirectory)) { throw new IllegalArgumentException(); } } Referencies(ApplicationLayout appLayout) { - this(Path.of("$APPDIR").resolve(appLayout.appModsDirectory().getFileName())); + this(BASEDIR.resolve(appLayout.appModsDirectory().getFileName()), BASEDIR); } - Path appDirectory() { - return Path.of("$APPDIR"); - } + private static final Path BASEDIR = Path.of("$APPDIR"); } private final LauncherStartupInfo startupInfo; diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/cli/Main.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/cli/Main.java index 562a0d2d3c1..73b4850344b 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/cli/Main.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/cli/Main.java @@ -271,11 +271,9 @@ public final class Main { } messagePrinter.accept(I18N.format("message.error-header", msg)); - if (!verbose) { - messagePrinter.accept(I18N.format("message.failed-command-output-header")); - try (var lines = new BufferedReader(new StringReader(commandOutput)).lines()) { - lines.forEach(messagePrinter); - } + messagePrinter.accept(I18N.format("message.failed-command-output-header")); + try (var lines = new BufferedReader(new StringReader(commandOutput)).lines()) { + lines.forEach(messagePrinter); } } diff --git a/src/jdk.jshell/share/classes/jdk/jshell/ReplParser.java b/src/jdk.jshell/share/classes/jdk/jshell/ReplParser.java index 0219fa0eaf8..11fe05fbb98 100644 --- a/src/jdk.jshell/share/classes/jdk/jshell/ReplParser.java +++ b/src/jdk.jshell/share/classes/jdk/jshell/ReplParser.java @@ -75,9 +75,8 @@ class ReplParser extends JavacParser { com.sun.tools.javac.parser.Lexer S, boolean keepDocComments, boolean keepLineMap, - boolean keepEndPositions, boolean forceExpression) { - super(fac, S, keepDocComments, keepLineMap, keepEndPositions); + super(fac, S, keepDocComments, keepLineMap); this.forceExpression = forceExpression; this.source = fac.source; } @@ -103,7 +102,7 @@ class ReplParser extends JavacParser { boolean firstTypeDecl = true; while (token.kind != EOF) { - if (token.pos > 0 && token.pos <= endPosTable.errorEndPos) { + if (token.pos > 0 && token.pos <= errorEndPos) { // error recovery skip(true, false, false, false); if (token.kind == EOF) { @@ -141,7 +140,6 @@ class ReplParser extends JavacParser { storeEnd(toplevel, S.prevToken().endPos); } toplevel.lineMap = S.getLineMap(); - toplevel.endPositions = this.endPosTable; return toplevel; } diff --git a/src/jdk.jshell/share/classes/jdk/jshell/ReplParserFactory.java b/src/jdk.jshell/share/classes/jdk/jshell/ReplParserFactory.java index 5c02561807b..3a3b25dade0 100644 --- a/src/jdk.jshell/share/classes/jdk/jshell/ReplParserFactory.java +++ b/src/jdk.jshell/share/classes/jdk/jshell/ReplParserFactory.java @@ -60,13 +60,8 @@ class ReplParserFactory extends ParserFactory { } @Override - public JavacParser newParser(CharSequence input, boolean keepDocComments, boolean keepEndPos, boolean keepLineMap) { + public JavacParser newParser(CharSequence input, boolean keepDocComments, boolean keepLineMap, boolean parseModuleInfo) { com.sun.tools.javac.parser.Lexer lexer = scannerFactory.newScanner(input, keepDocComments); - return new ReplParser(this, lexer, keepDocComments, keepLineMap, keepEndPos, forceExpression); - } - - @Override - public JavacParser newParser(CharSequence input, boolean keepDocComments, boolean keepEndPos, boolean keepLineMap, boolean parseModuleInfo) { - return newParser(input, keepDocComments, keepEndPos, keepLineMap); + return new ReplParser(this, lexer, keepDocComments, keepLineMap, forceExpression); } } diff --git a/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java b/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java index d5b44b569a4..1cf0c85702f 100644 --- a/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java +++ b/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,6 @@ import com.sun.source.tree.NewClassTree; import com.sun.source.tree.Scope; import com.sun.source.tree.Tree; import com.sun.source.tree.Tree.Kind; -import static com.sun.source.tree.Tree.Kind.METHOD; import com.sun.source.tree.TypeParameterTree; import com.sun.source.tree.VariableTree; import com.sun.source.tree.YieldTree; @@ -81,6 +80,7 @@ import java.util.Iterator; import java.util.List; import java.util.Objects; import java.util.function.Predicate; +import java.util.TreeSet; import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; @@ -114,7 +114,6 @@ import java.util.Map; import java.util.NoSuchElementException; import java.util.Optional; import java.util.Set; -import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.function.BiConsumer; @@ -149,14 +148,10 @@ import javax.tools.JavaFileManager.Location; import javax.tools.StandardLocation; import jdk.jshell.ExpressionToTypeInfo.ExpressionInfo; -import static jdk.jshell.Util.REPL_DOESNOTMATTER_CLASS_NAME; import static jdk.jshell.SourceCodeAnalysis.Completeness.DEFINITELY_INCOMPLETE; import static jdk.jshell.TreeDissector.printType; import static java.util.stream.Collectors.joining; -import static javax.lang.model.element.ElementKind.CONSTRUCTOR; -import static javax.lang.model.element.ElementKind.MODULE; -import static javax.lang.model.element.ElementKind.PACKAGE; import javax.lang.model.type.IntersectionType; import javax.lang.model.util.Elements; @@ -815,7 +810,7 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis { }; String wrappedCode = codeWrap.wrapped(); return this.proc.taskFactory.analyze(codeWrap, task -> { - List result = new ArrayList<>(); + TreeSet result = new TreeSet<>(Comparator.comparing(Highlight::start).thenComparing(Highlight::end)); CompilationUnitTree cut = task.cuTrees().iterator().next(); Trees trees = task.trees(); SourcePositions sp = trees.getSourcePositions(); @@ -1050,8 +1045,7 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis { } }.scan(cut, null); result.removeIf(h -> h.start() == h.end()); - Collections.sort(result, (h1, h2) -> h1.start() - h2.start()); - return result; + return new ArrayList<>(result); }); } diff --git a/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java b/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java index 13c07ea32c0..0de0e27ec07 100644 --- a/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java +++ b/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java @@ -819,9 +819,9 @@ class TaskFactory { } @Override - public JavacParser newParser(CharSequence input, boolean keepDocComments, boolean keepEndPos, boolean keepLineMap, boolean parseModuleInfo) { + public JavacParser newParser(CharSequence input, boolean keepDocComments, boolean keepLineMap, boolean parseModuleInfo) { com.sun.tools.javac.parser.Lexer lexer = scannerFactory.newScanner(input, keepDocComments); - return new JavacParser(this, lexer, keepDocComments, keepLineMap, keepEndPos, parseModuleInfo) { + return new JavacParser(this, lexer, keepDocComments, keepLineMap, parseModuleInfo) { @Override public JCExpression parseType(boolean allowVar, com.sun.tools.javac.util.List annotations) { int pos = token.pos; diff --git a/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpChannelImpl.java b/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpChannelImpl.java index 485ebf13f2c..263aa58e098 100644 --- a/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpChannelImpl.java +++ b/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpChannelImpl.java @@ -84,9 +84,9 @@ public class SctpChannelImpl extends SctpChannel private final int fdVal; - /* IDs of native threads doing send and receive, for signalling */ - private volatile long receiverThread; - private volatile long senderThread; + /* Threads doing send and receive, for signalling */ + private volatile Thread receiverThread; + private volatile Thread senderThread; /* Lock held by current receiving or connecting thread */ private final Object receiveLock = new Object(); @@ -326,7 +326,7 @@ public class SctpChannelImpl extends SctpChannel private void receiverCleanup() throws IOException { synchronized (stateLock) { - receiverThread = 0; + receiverThread = null; if (state == ChannelState.KILLPENDING) kill(); } @@ -334,7 +334,7 @@ public class SctpChannelImpl extends SctpChannel private void senderCleanup() throws IOException { synchronized (stateLock) { - senderThread = 0; + senderThread = null; if (state == ChannelState.KILLPENDING) kill(); } @@ -367,7 +367,7 @@ public class SctpChannelImpl extends SctpChannel if (!isOpen()) { return false; } - receiverThread = NativeThread.current(); + receiverThread = NativeThread.threadToSignal(); } for (;;) { InetAddress ia = isa.getAddress(); @@ -472,7 +472,7 @@ public class SctpChannelImpl extends SctpChannel if (!isOpen()) { return false; } - receiverThread = NativeThread.current(); + receiverThread = NativeThread.threadToSignal(); } if (!isBlocking()) { connected = Net.pollConnect(fd, 0); @@ -484,7 +484,7 @@ public class SctpChannelImpl extends SctpChannel } } finally { synchronized (stateLock) { - receiverThread = 0; + receiverThread = null; if (state == ChannelState.KILLPENDING) { kill(); connected = false; @@ -541,10 +541,10 @@ public class SctpChannelImpl extends SctpChannel if (state != ChannelState.KILLED) SctpNet.preClose(fdVal); - if (receiverThread != 0) + if (receiverThread != null) NativeThread.signal(receiverThread); - if (senderThread != 0) + if (senderThread != null) NativeThread.signal(senderThread); if (!isRegistered()) @@ -644,7 +644,7 @@ public class SctpChannelImpl extends SctpChannel /* Postpone the kill if there is a waiting reader * or writer thread. */ - if (receiverThread == 0 && senderThread == 0) { + if (receiverThread == null && senderThread == null) { state = ChannelState.KILLED; SctpNet.close(fdVal); } else { @@ -743,7 +743,7 @@ public class SctpChannelImpl extends SctpChannel synchronized (stateLock) { if(!isOpen()) return null; - receiverThread = NativeThread.current(); + receiverThread = NativeThread.threadToSignal(); } do { @@ -936,7 +936,7 @@ public class SctpChannelImpl extends SctpChannel synchronized (stateLock) { if(!isOpen()) return 0; - senderThread = NativeThread.current(); + senderThread = NativeThread.threadToSignal(); } do { @@ -1031,7 +1031,7 @@ public class SctpChannelImpl extends SctpChannel ensureSendOpen(); SctpNet.shutdown(fdVal, -1); - if (senderThread != 0) + if (senderThread != null) NativeThread.signal(senderThread); isShutdown = true; } diff --git a/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java b/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java index 31e83d72f96..c08c6dc88d0 100644 --- a/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java +++ b/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java @@ -81,9 +81,9 @@ public class SctpMultiChannelImpl extends SctpMultiChannel private final int fdVal; - /* IDs of native threads doing send and receives, for signalling */ - private volatile long receiverThread; - private volatile long senderThread; + /* Threads doing send and receives, for signalling */ + private volatile Thread receiverThread; + private volatile Thread senderThread; /* Lock held by current receiving thread */ private final Object receiveLock = new Object(); @@ -265,7 +265,7 @@ public class SctpMultiChannelImpl extends SctpMultiChannel private void receiverCleanup() throws IOException { synchronized (stateLock) { - receiverThread = 0; + receiverThread = null; if (state == ChannelState.KILLPENDING) kill(); } @@ -273,7 +273,7 @@ public class SctpMultiChannelImpl extends SctpMultiChannel private void senderCleanup() throws IOException { synchronized (stateLock) { - senderThread = 0; + senderThread = null; if (state == ChannelState.KILLPENDING) kill(); } @@ -290,10 +290,10 @@ public class SctpMultiChannelImpl extends SctpMultiChannel if (state != ChannelState.KILLED) SctpNet.preClose(fdVal); - if (receiverThread != 0) + if (receiverThread != null) NativeThread.signal(receiverThread); - if (senderThread != 0) + if (senderThread != null) NativeThread.signal(senderThread); if (!isRegistered()) @@ -378,7 +378,7 @@ public class SctpMultiChannelImpl extends SctpMultiChannel assert !isOpen() && !isRegistered(); /* Postpone the kill if there is a thread sending or receiving. */ - if (receiverThread == 0 && senderThread == 0) { + if (receiverThread == null && senderThread == null) { state = ChannelState.KILLED; SctpNet.close(fdVal); } else { @@ -484,7 +484,7 @@ public class SctpMultiChannelImpl extends SctpMultiChannel synchronized (stateLock) { if(!isOpen()) return null; - receiverThread = NativeThread.current(); + receiverThread = NativeThread.threadToSignal(); } do { @@ -765,7 +765,7 @@ public class SctpMultiChannelImpl extends SctpMultiChannel synchronized (stateLock) { if(!isOpen()) return 0; - senderThread = NativeThread.current(); + senderThread = NativeThread.threadToSignal(); /* Determine what address or association to send to */ Association assoc = messageInfo.association(); diff --git a/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java b/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java index 4b2be742c6d..f72e0938eb5 100644 --- a/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java +++ b/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,8 +58,8 @@ public class SctpServerChannelImpl extends SctpServerChannel private final int fdVal; - /* IDs of native thread doing accept, for signalling */ - private volatile long thread; + /* thread doing accept, for signalling */ + private volatile Thread thread; /* Lock held by thread currently blocked in this channel */ private final Object lock = new Object(); @@ -200,7 +200,7 @@ public class SctpServerChannelImpl extends SctpServerChannel private void acceptCleanup() throws IOException { synchronized (stateLock) { - thread = 0; + thread = null; if (state == ChannelState.KILLPENDING) kill(); } @@ -222,7 +222,7 @@ public class SctpServerChannelImpl extends SctpServerChannel begin(); if (!isOpen()) return null; - thread = NativeThread.current(); + thread = NativeThread.threadToSignal(); for (;;) { n = Net.accept(fd, newfd, isaa); if ((n == IOStatus.INTERRUPTED) && isOpen()) @@ -253,7 +253,7 @@ public class SctpServerChannelImpl extends SctpServerChannel synchronized (stateLock) { if (state != ChannelState.KILLED) SctpNet.preClose(fdVal); - if (thread != 0) + if (thread != null) NativeThread.signal(thread); if (!isRegistered()) kill(); @@ -273,7 +273,7 @@ public class SctpServerChannelImpl extends SctpServerChannel assert !isOpen() && !isRegistered(); // Postpone the kill if there is a thread in accept - if (thread == 0) { + if (thread == null) { state = ChannelState.KILLED; SctpNet.close(fdVal); } else { diff --git a/test/docs/ProblemList.txt b/test/docs/ProblemList.txt index c846678665d..d856f9c955e 100644 --- a/test/docs/ProblemList.txt +++ b/test/docs/ProblemList.txt @@ -1,6 +1,6 @@ ########################################################################### # -# Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved. # 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,3 +39,16 @@ # More than one label is allowed but must be on the same line. # ############################################################################# + +############################################################################# + +# Preview project specific failures go here at the end of the file. +# +# These are NOT failures that occur with the '--enable-preview' option +# specified; those go in the appropriate ProblemList-enable-preview.txt file. +# These are failures that occur WITHOUT the '--enable-preview' option +# specified AND occur because of some issue with preview project code, +# in either implementation or test code. + +############################################################################# + diff --git a/test/hotspot/gtest/aarch64/aarch64-asmtest.py b/test/hotspot/gtest/aarch64/aarch64-asmtest.py index 48b19acaa05..1ac2e1a89cd 100644 --- a/test/hotspot/gtest/aarch64/aarch64-asmtest.py +++ b/test/hotspot/gtest/aarch64/aarch64-asmtest.py @@ -1871,6 +1871,12 @@ generate(ThreeRegNEONOp, ["sminp", "sminp", "8B"], ["sminp", "sminp", "16B"], ["sminp", "sminp", "4H"], ["sminp", "sminp", "8H"], ["sminp", "sminp", "2S"], ["sminp", "sminp", "4S"], + ["uminp", "uminp", "8B"], ["uminp", "uminp", "16B"], + ["uminp", "uminp", "4H"], ["uminp", "uminp", "8H"], + ["uminp", "uminp", "2S"], ["uminp", "uminp", "4S"], + ["umaxp", "umaxp", "8B"], ["umaxp", "umaxp", "16B"], + ["umaxp", "umaxp", "4H"], ["umaxp", "umaxp", "8H"], + ["umaxp", "umaxp", "2S"], ["umaxp", "umaxp", "4S"], ["sqdmulh", "sqdmulh", "4H"], ["sqdmulh", "sqdmulh", "8H"], ["sqdmulh", "sqdmulh", "2S"], ["sqdmulh", "sqdmulh", "4S"], ["shsubv", "shsub", "8B"], ["shsubv", "shsub", "16B"], @@ -2252,7 +2258,7 @@ generate(SVEVectorOp, [["add", "ZZZ"], ["uqsub", "ZPZ", "m", "dn"], ]) -generate(SVEReductionOp, [["andv", 0], ["orv", 0], ["eorv", 0], ["smaxv", 0], ["sminv", 0], +generate(SVEReductionOp, [["andv", 0], ["orv", 0], ["eorv", 0], ["smaxv", 0], ["sminv", 0], ["umaxv", 0], ["uminv", 0], ["fminv", 2], ["fmaxv", 2], ["fadda", 2], ["uaddv", 0]]) generate(AddWideNEONOp, diff --git a/test/hotspot/gtest/aarch64/asmtest.out.h b/test/hotspot/gtest/aarch64/asmtest.out.h index 34a5f8ca68e..22bb6c57784 100644 --- a/test/hotspot/gtest/aarch64/asmtest.out.h +++ b/test/hotspot/gtest/aarch64/asmtest.out.h @@ -826,107 +826,119 @@ __ sminp(v10, __ T8H, v11, v12); // sminp v10.8H, v11.8H, v12.8H __ sminp(v20, __ T2S, v21, v22); // sminp v20.2S, v21.2S, v22.2S __ sminp(v10, __ T4S, v11, v12); // sminp v10.4S, v11.4S, v12.4S - __ sqdmulh(v4, __ T4H, v5, v6); // sqdmulh v4.4H, v5.4H, v6.4H - __ sqdmulh(v24, __ T8H, v25, v26); // sqdmulh v24.8H, v25.8H, v26.8H - __ sqdmulh(v17, __ T2S, v18, v19); // sqdmulh v17.2S, v18.2S, v19.2S - __ sqdmulh(v17, __ T4S, v18, v19); // sqdmulh v17.4S, v18.4S, v19.4S - __ shsubv(v22, __ T8B, v23, v24); // shsub v22.8B, v23.8B, v24.8B - __ shsubv(v3, __ T16B, v4, v5); // shsub v3.16B, v4.16B, v5.16B - __ shsubv(v29, __ T4H, v30, v31); // shsub v29.4H, v30.4H, v31.4H - __ shsubv(v15, __ T8H, v16, v17); // shsub v15.8H, v16.8H, v17.8H - __ shsubv(v22, __ T2S, v23, v24); // shsub v22.2S, v23.2S, v24.2S - __ shsubv(v19, __ T4S, v20, v21); // shsub v19.4S, v20.4S, v21.4S + __ uminp(v4, __ T8B, v5, v6); // uminp v4.8B, v5.8B, v6.8B + __ uminp(v24, __ T16B, v25, v26); // uminp v24.16B, v25.16B, v26.16B + __ uminp(v17, __ T4H, v18, v19); // uminp v17.4H, v18.4H, v19.4H + __ uminp(v17, __ T8H, v18, v19); // uminp v17.8H, v18.8H, v19.8H + __ uminp(v22, __ T2S, v23, v24); // uminp v22.2S, v23.2S, v24.2S + __ uminp(v3, __ T4S, v4, v5); // uminp v3.4S, v4.4S, v5.4S + __ umaxp(v29, __ T8B, v30, v31); // umaxp v29.8B, v30.8B, v31.8B + __ umaxp(v15, __ T16B, v16, v17); // umaxp v15.16B, v16.16B, v17.16B + __ umaxp(v22, __ T4H, v23, v24); // umaxp v22.4H, v23.4H, v24.4H + __ umaxp(v19, __ T8H, v20, v21); // umaxp v19.8H, v20.8H, v21.8H + __ umaxp(v19, __ T2S, v20, v21); // umaxp v19.2S, v20.2S, v21.2S + __ umaxp(v22, __ T4S, v23, v24); // umaxp v22.4S, v23.4S, v24.4S + __ sqdmulh(v2, __ T4H, v3, v4); // sqdmulh v2.4H, v3.4H, v4.4H + __ sqdmulh(v15, __ T8H, v16, v17); // sqdmulh v15.8H, v16.8H, v17.8H + __ sqdmulh(v6, __ T2S, v7, v8); // sqdmulh v6.2S, v7.2S, v8.2S + __ sqdmulh(v12, __ T4S, v13, v14); // sqdmulh v12.4S, v13.4S, v14.4S + __ shsubv(v16, __ T8B, v17, v18); // shsub v16.8B, v17.8B, v18.8B + __ shsubv(v11, __ T16B, v12, v13); // shsub v11.16B, v12.16B, v13.16B + __ shsubv(v13, __ T4H, v14, v15); // shsub v13.4H, v14.4H, v15.4H + __ shsubv(v23, __ T8H, v24, v25); // shsub v23.8H, v24.8H, v25.8H + __ shsubv(v1, __ T2S, v2, v3); // shsub v1.2S, v2.2S, v3.2S + __ shsubv(v30, __ T4S, v31, v0); // shsub v30.4S, v31.4S, v0.4S __ fmin(v19, __ T2S, v20, v21); // fmin v19.2S, v20.2S, v21.2S - __ fmin(v22, __ T4S, v23, v24); // fmin v22.4S, v23.4S, v24.4S - __ fmin(v2, __ T2D, v3, v4); // fmin v2.2D, v3.2D, v4.2D - __ fmin(v15, __ T4H, v16, v17); // fmin v15.4H, v16.4H, v17.4H - __ fmin(v6, __ T8H, v7, v8); // fmin v6.8H, v7.8H, v8.8H - __ facgt(v12, __ T2S, v13, v14); // facgt v12.2S, v13.2S, v14.2S - __ facgt(v16, __ T4S, v17, v18); // facgt v16.4S, v17.4S, v18.4S - __ facgt(v11, __ T2D, v12, v13); // facgt v11.2D, v12.2D, v13.2D - __ facgt(v13, __ T4H, v14, v15); // facgt v13.4H, v14.4H, v15.4H - __ facgt(v23, __ T8H, v24, v25); // facgt v23.8H, v24.8H, v25.8H + __ fmin(v5, __ T4S, v6, v7); // fmin v5.4S, v6.4S, v7.4S + __ fmin(v17, __ T2D, v18, v19); // fmin v17.2D, v18.2D, v19.2D + __ fmin(v2, __ T4H, v3, v4); // fmin v2.4H, v3.4H, v4.4H + __ fmin(v16, __ T8H, v17, v18); // fmin v16.8H, v17.8H, v18.8H + __ facgt(v22, __ T2S, v23, v24); // facgt v22.2S, v23.2S, v24.2S + __ facgt(v13, __ T4S, v14, v15); // facgt v13.4S, v14.4S, v15.4S + __ facgt(v10, __ T2D, v11, v12); // facgt v10.2D, v11.2D, v12.2D + __ facgt(v21, __ T4H, v22, v23); // facgt v21.4H, v22.4H, v23.4H + __ facgt(v29, __ T8H, v30, v31); // facgt v29.8H, v30.8H, v31.8H // VectorScalarNEONInstruction - __ fmlavs(v15, __ T2S, v0, v1, 0); // fmla v15.2S, v0.2S, v1.S[0] - __ mulvs(v2, __ T4S, v3, v4, 2); // mul v2.4S, v3.4S, v4.S[2] - __ fmlavs(v1, __ T2D, v2, v3, 1); // fmla v1.2D, v2.2D, v3.D[1] - __ fmlsvs(v11, __ T2S, v12, v13, 1); // fmls v11.2S, v12.2S, v13.S[1] - __ mulvs(v5, __ T4S, v6, v7, 1); // mul v5.4S, v6.4S, v7.S[1] - __ fmlsvs(v14, __ T2D, v15, v16, 1); // fmls v14.2D, v15.2D, v16.D[1] - __ fmulxvs(v6, __ T2S, v7, v8, 1); // fmulx v6.2S, v7.2S, v8.S[1] + __ fmlavs(v6, __ T2S, v7, v8, 1); // fmla v6.2S, v7.2S, v8.S[1] __ mulvs(v1, __ T4S, v2, v3, 3); // mul v1.4S, v2.4S, v3.S[3] - __ fmulxvs(v15, __ T2D, v0, v1, 0); // fmulx v15.2D, v0.2D, v1.D[0] - __ mulvs(v9, __ T4H, v10, v11, 3); // mul v9.4H, v10.4H, v11.H[3] - __ mulvs(v4, __ T8H, v5, v6, 4); // mul v4.8H, v5.8H, v6.H[4] - __ mulvs(v13, __ T2S, v14, v15, 1); // mul v13.2S, v14.2S, v15.S[1] - __ mulvs(v3, __ T4S, v4, v5, 1); // mul v3.4S, v4.4S, v5.S[1] + __ fmlavs(v15, __ T2D, v0, v1, 0); // fmla v15.2D, v0.2D, v1.D[0] + __ fmlsvs(v9, __ T2S, v10, v11, 1); // fmls v9.2S, v10.2S, v11.S[1] + __ mulvs(v4, __ T4S, v5, v6, 2); // mul v4.4S, v5.4S, v6.S[2] + __ fmlsvs(v13, __ T2D, v14, v15, 1); // fmls v13.2D, v14.2D, v15.D[1] + __ fmulxvs(v3, __ T2S, v4, v5, 0); // fmulx v3.2S, v4.2S, v5.S[0] + __ mulvs(v11, __ T4S, v12, v13, 2); // mul v11.4S, v12.4S, v13.S[2] + __ fmulxvs(v12, __ T2D, v13, v14, 1); // fmulx v12.2D, v13.2D, v14.D[1] + __ mulvs(v15, __ T4H, v0, v1, 0); // mul v15.4H, v0.4H, v1.H[0] + __ mulvs(v9, __ T8H, v10, v11, 6); // mul v9.8H, v10.8H, v11.H[6] + __ mulvs(v11, __ T2S, v12, v13, 0); // mul v11.2S, v12.2S, v13.S[0] + __ mulvs(v1, __ T4S, v2, v3, 2); // mul v1.4S, v2.4S, v3.S[2] // NEONVectorCompare - __ cm(Assembler::GT, v21, __ T8B, v22, v23); // cmgt v21.8B, v22.8B, v23.8B - __ cm(Assembler::GT, v23, __ T16B, v24, v25); // cmgt v23.16B, v24.16B, v25.16B - __ cm(Assembler::GT, v31, __ T4H, v0, v1); // cmgt v31.4H, v0.4H, v1.4H - __ cm(Assembler::GT, v25, __ T8H, v26, v27); // cmgt v25.8H, v26.8H, v27.8H - __ cm(Assembler::GT, v2, __ T2S, v3, v4); // cmgt v2.2S, v3.2S, v4.2S - __ cm(Assembler::GT, v31, __ T4S, v0, v1); // cmgt v31.4S, v0.4S, v1.4S - __ cm(Assembler::GT, v27, __ T2D, v28, v29); // cmgt v27.2D, v28.2D, v29.2D - __ cm(Assembler::GE, v18, __ T8B, v19, v20); // cmge v18.8B, v19.8B, v20.8B - __ cm(Assembler::GE, v10, __ T16B, v11, v12); // cmge v10.16B, v11.16B, v12.16B - __ cm(Assembler::GE, v23, __ T4H, v24, v25); // cmge v23.4H, v24.4H, v25.4H - __ cm(Assembler::GE, v19, __ T8H, v20, v21); // cmge v19.8H, v20.8H, v21.8H - __ cm(Assembler::GE, v3, __ T2S, v4, v5); // cmge v3.2S, v4.2S, v5.2S - __ cm(Assembler::GE, v18, __ T4S, v19, v20); // cmge v18.4S, v19.4S, v20.4S - __ cm(Assembler::GE, v0, __ T2D, v1, v2); // cmge v0.2D, v1.2D, v2.2D - __ cm(Assembler::EQ, v25, __ T8B, v26, v27); // cmeq v25.8B, v26.8B, v27.8B - __ cm(Assembler::EQ, v26, __ T16B, v27, v28); // cmeq v26.16B, v27.16B, v28.16B - __ cm(Assembler::EQ, v23, __ T4H, v24, v25); // cmeq v23.4H, v24.4H, v25.4H - __ cm(Assembler::EQ, v2, __ T8H, v3, v4); // cmeq v2.8H, v3.8H, v4.8H - __ cm(Assembler::EQ, v18, __ T2S, v19, v20); // cmeq v18.2S, v19.2S, v20.2S - __ cm(Assembler::EQ, v12, __ T4S, v13, v14); // cmeq v12.4S, v13.4S, v14.4S - __ cm(Assembler::EQ, v4, __ T2D, v5, v6); // cmeq v4.2D, v5.2D, v6.2D - __ cm(Assembler::HI, v28, __ T8B, v29, v30); // cmhi v28.8B, v29.8B, v30.8B - __ cm(Assembler::HI, v30, __ T16B, v31, v0); // cmhi v30.16B, v31.16B, v0.16B - __ cm(Assembler::HI, v29, __ T4H, v30, v31); // cmhi v29.4H, v30.4H, v31.4H - __ cm(Assembler::HI, v16, __ T8H, v17, v18); // cmhi v16.8H, v17.8H, v18.8H - __ cm(Assembler::HI, v27, __ T2S, v28, v29); // cmhi v27.2S, v28.2S, v29.2S - __ cm(Assembler::HI, v6, __ T4S, v7, v8); // cmhi v6.4S, v7.4S, v8.4S - __ cm(Assembler::HI, v9, __ T2D, v10, v11); // cmhi v9.2D, v10.2D, v11.2D - __ cm(Assembler::HS, v29, __ T8B, v30, v31); // cmhs v29.8B, v30.8B, v31.8B - __ cm(Assembler::HS, v18, __ T16B, v19, v20); // cmhs v18.16B, v19.16B, v20.16B - __ cm(Assembler::HS, v7, __ T4H, v8, v9); // cmhs v7.4H, v8.4H, v9.4H - __ cm(Assembler::HS, v4, __ T8H, v5, v6); // cmhs v4.8H, v5.8H, v6.8H - __ cm(Assembler::HS, v7, __ T2S, v8, v9); // cmhs v7.2S, v8.2S, v9.2S + __ cm(Assembler::GT, v18, __ T8B, v19, v20); // cmgt v18.8B, v19.8B, v20.8B + __ cm(Assembler::GT, v0, __ T16B, v1, v2); // cmgt v0.16B, v1.16B, v2.16B + __ cm(Assembler::GT, v25, __ T4H, v26, v27); // cmgt v25.4H, v26.4H, v27.4H + __ cm(Assembler::GT, v26, __ T8H, v27, v28); // cmgt v26.8H, v27.8H, v28.8H + __ cm(Assembler::GT, v23, __ T2S, v24, v25); // cmgt v23.2S, v24.2S, v25.2S + __ cm(Assembler::GT, v2, __ T4S, v3, v4); // cmgt v2.4S, v3.4S, v4.4S + __ cm(Assembler::GT, v18, __ T2D, v19, v20); // cmgt v18.2D, v19.2D, v20.2D + __ cm(Assembler::GE, v12, __ T8B, v13, v14); // cmge v12.8B, v13.8B, v14.8B + __ cm(Assembler::GE, v4, __ T16B, v5, v6); // cmge v4.16B, v5.16B, v6.16B + __ cm(Assembler::GE, v28, __ T4H, v29, v30); // cmge v28.4H, v29.4H, v30.4H + __ cm(Assembler::GE, v30, __ T8H, v31, v0); // cmge v30.8H, v31.8H, v0.8H + __ cm(Assembler::GE, v29, __ T2S, v30, v31); // cmge v29.2S, v30.2S, v31.2S + __ cm(Assembler::GE, v16, __ T4S, v17, v18); // cmge v16.4S, v17.4S, v18.4S + __ cm(Assembler::GE, v27, __ T2D, v28, v29); // cmge v27.2D, v28.2D, v29.2D + __ cm(Assembler::EQ, v6, __ T8B, v7, v8); // cmeq v6.8B, v7.8B, v8.8B + __ cm(Assembler::EQ, v9, __ T16B, v10, v11); // cmeq v9.16B, v10.16B, v11.16B + __ cm(Assembler::EQ, v29, __ T4H, v30, v31); // cmeq v29.4H, v30.4H, v31.4H + __ cm(Assembler::EQ, v18, __ T8H, v19, v20); // cmeq v18.8H, v19.8H, v20.8H + __ cm(Assembler::EQ, v7, __ T2S, v8, v9); // cmeq v7.2S, v8.2S, v9.2S + __ cm(Assembler::EQ, v4, __ T4S, v5, v6); // cmeq v4.4S, v5.4S, v6.4S + __ cm(Assembler::EQ, v7, __ T2D, v8, v9); // cmeq v7.2D, v8.2D, v9.2D + __ cm(Assembler::HI, v15, __ T8B, v16, v17); // cmhi v15.8B, v16.8B, v17.8B + __ cm(Assembler::HI, v9, __ T16B, v10, v11); // cmhi v9.16B, v10.16B, v11.16B + __ cm(Assembler::HI, v23, __ T4H, v24, v25); // cmhi v23.4H, v24.4H, v25.4H + __ cm(Assembler::HI, v8, __ T8H, v9, v10); // cmhi v8.8H, v9.8H, v10.8H + __ cm(Assembler::HI, v2, __ T2S, v3, v4); // cmhi v2.2S, v3.2S, v4.2S + __ cm(Assembler::HI, v28, __ T4S, v29, v30); // cmhi v28.4S, v29.4S, v30.4S + __ cm(Assembler::HI, v21, __ T2D, v22, v23); // cmhi v21.2D, v22.2D, v23.2D + __ cm(Assembler::HS, v31, __ T8B, v0, v1); // cmhs v31.8B, v0.8B, v1.8B + __ cm(Assembler::HS, v5, __ T16B, v6, v7); // cmhs v5.16B, v6.16B, v7.16B + __ cm(Assembler::HS, v27, __ T4H, v28, v29); // cmhs v27.4H, v28.4H, v29.4H + __ cm(Assembler::HS, v0, __ T8H, v1, v2); // cmhs v0.8H, v1.8H, v2.8H + __ cm(Assembler::HS, v17, __ T2S, v18, v19); // cmhs v17.2S, v18.2S, v19.2S __ cm(Assembler::HS, v15, __ T4S, v16, v17); // cmhs v15.4S, v16.4S, v17.4S - __ cm(Assembler::HS, v9, __ T2D, v10, v11); // cmhs v9.2D, v10.2D, v11.2D - __ fcm(Assembler::EQ, v23, __ T2S, v24, v25); // fcmeq v23.2S, v24.2S, v25.2S + __ cm(Assembler::HS, v4, __ T2D, v5, v6); // cmhs v4.2D, v5.2D, v6.2D + __ fcm(Assembler::EQ, v26, __ T2S, v27, v28); // fcmeq v26.2S, v27.2S, v28.2S __ fcm(Assembler::EQ, v8, __ T4S, v9, v10); // fcmeq v8.4S, v9.4S, v10.4S - __ fcm(Assembler::EQ, v2, __ T2D, v3, v4); // fcmeq v2.2D, v3.2D, v4.2D - __ fcm(Assembler::GT, v28, __ T2S, v29, v30); // fcmgt v28.2S, v29.2S, v30.2S - __ fcm(Assembler::GT, v21, __ T4S, v22, v23); // fcmgt v21.4S, v22.4S, v23.4S - __ fcm(Assembler::GT, v31, __ T2D, v0, v1); // fcmgt v31.2D, v0.2D, v1.2D - __ fcm(Assembler::GE, v5, __ T2S, v6, v7); // fcmge v5.2S, v6.2S, v7.2S - __ fcm(Assembler::GE, v27, __ T4S, v28, v29); // fcmge v27.4S, v28.4S, v29.4S + __ fcm(Assembler::EQ, v28, __ T2D, v29, v30); // fcmeq v28.2D, v29.2D, v30.2D + __ fcm(Assembler::GT, v22, __ T2S, v23, v24); // fcmgt v22.2S, v23.2S, v24.2S + __ fcm(Assembler::GT, v27, __ T4S, v28, v29); // fcmgt v27.4S, v28.4S, v29.4S + __ fcm(Assembler::GT, v27, __ T2D, v28, v29); // fcmgt v27.2D, v28.2D, v29.2D + __ fcm(Assembler::GE, v25, __ T2S, v26, v27); // fcmge v25.2S, v26.2S, v27.2S + __ fcm(Assembler::GE, v23, __ T4S, v24, v25); // fcmge v23.4S, v24.4S, v25.4S __ fcm(Assembler::GE, v0, __ T2D, v1, v2); // fcmge v0.2D, v1.2D, v2.2D // SVEComparisonWithZero - __ sve_fcm(Assembler::EQ, p8, __ S, p6, z15, 0.0); // fcmeq p8.s, p6/z, z15.s, #0.0 - __ sve_fcm(Assembler::GT, p4, __ D, p6, z28, 0.0); // fcmgt p4.d, p6/z, z28.d, #0.0 - __ sve_fcm(Assembler::GE, p13, __ D, p0, z25, 0.0); // fcmge p13.d, p0/z, z25.d, #0.0 - __ sve_fcm(Assembler::LT, p2, __ D, p0, z6, 0.0); // fcmlt p2.d, p0/z, z6.d, #0.0 - __ sve_fcm(Assembler::LE, p2, __ S, p2, z15, 0.0); // fcmle p2.s, p2/z, z15.s, #0.0 - __ sve_fcm(Assembler::NE, p3, __ S, p7, z5, 0.0); // fcmne p3.s, p7/z, z5.s, #0.0 + __ sve_fcm(Assembler::EQ, p2, __ D, p0, z6, 0.0); // fcmeq p2.d, p0/z, z6.d, #0.0 + __ sve_fcm(Assembler::GT, p2, __ S, p2, z15, 0.0); // fcmgt p2.s, p2/z, z15.s, #0.0 + __ sve_fcm(Assembler::GE, p3, __ S, p7, z5, 0.0); // fcmge p3.s, p7/z, z5.s, #0.0 + __ sve_fcm(Assembler::LT, p3, __ D, p5, z20, 0.0); // fcmlt p3.d, p5/z, z20.d, #0.0 + __ sve_fcm(Assembler::LE, p3, __ S, p4, z11, 0.0); // fcmle p3.s, p4/z, z11.s, #0.0 + __ sve_fcm(Assembler::NE, p15, __ D, p0, z6, 0.0); // fcmne p15.d, p0/z, z6.d, #0.0 // SVEComparisonWithImm - __ sve_cmp(Assembler::EQ, p3, __ S, p5, z20, -10); // cmpeq p3.s, p5/z, z20.s, #-10 - __ sve_cmp(Assembler::GT, p5, __ S, p7, z8, -10); // cmpgt p5.s, p7/z, z8.s, #-10 - __ sve_cmp(Assembler::GE, p8, __ H, p7, z2, 13); // cmpge p8.h, p7/z, z2.h, #13 - __ sve_cmp(Assembler::LT, p1, __ S, p7, z27, -2); // cmplt p1.s, p7/z, z27.s, #-2 - __ sve_cmp(Assembler::LE, p6, __ S, p6, z28, -11); // cmple p6.s, p6/z, z28.s, #-11 - __ sve_cmp(Assembler::NE, p1, __ H, p4, z14, -5); // cmpne p1.h, p4/z, z14.h, #-5 - __ sve_cmp(Assembler::HS, p13, __ H, p1, z23, 90); // cmphs p13.h, p1/z, z23.h, #90 - __ sve_cmp(Assembler::HI, p8, __ B, p4, z4, 66); // cmphi p8.b, p4/z, z4.b, #66 - __ sve_cmp(Assembler::LS, p9, __ H, p3, z13, 11); // cmpls p9.h, p3/z, z13.h, #11 - __ sve_cmp(Assembler::LO, p8, __ S, p5, z3, 21); // cmplo p8.s, p5/z, z3.s, #21 + __ sve_cmp(Assembler::EQ, p6, __ D, p0, z30, 11); // cmpeq p6.d, p0/z, z30.d, #11 + __ sve_cmp(Assembler::GT, p11, __ H, p3, z29, 12); // cmpgt p11.h, p3/z, z29.h, #12 + __ sve_cmp(Assembler::GE, p8, __ B, p0, z24, -2); // cmpge p8.b, p0/z, z24.b, #-2 + __ sve_cmp(Assembler::LT, p5, __ H, p6, z16, 7); // cmplt p5.h, p6/z, z16.h, #7 + __ sve_cmp(Assembler::LE, p6, __ S, p4, z4, -12); // cmple p6.s, p4/z, z4.s, #-12 + __ sve_cmp(Assembler::NE, p0, __ S, p4, z19, -3); // cmpne p0.s, p4/z, z19.s, #-3 + __ sve_cmp(Assembler::HS, p7, __ B, p4, z12, 15); // cmphs p7.b, p4/z, z12.b, #15 + __ sve_cmp(Assembler::HI, p10, __ B, p1, z23, 30); // cmphi p10.b, p1/z, z23.b, #30 + __ sve_cmp(Assembler::LS, p9, __ D, p4, z13, 67); // cmpls p9.d, p4/z, z13.d, #67 + __ sve_cmp(Assembler::LO, p3, __ D, p0, z2, 16); // cmplo p3.d, p0/z, z2.d, #16 // SpecialCases __ ccmn(zr, zr, 3u, Assembler::LE); // ccmn xzr, xzr, #3, LE @@ -1198,239 +1210,241 @@ __ fmovd(v0, -1.0625); // fmov d0, #-1.0625 // LSEOp - __ swp(Assembler::xword, r6, r7, r19); // swp x6, x7, [x19] - __ ldadd(Assembler::xword, r13, r28, r17); // ldadd x13, x28, [x17] - __ ldbic(Assembler::xword, r16, r6, r2); // ldclr x16, x6, [x2] - __ ldeor(Assembler::xword, r29, r3, r4); // ldeor x29, x3, [x4] - __ ldorr(Assembler::xword, r6, r16, r20); // ldset x6, x16, [x20] - __ ldsmin(Assembler::xword, r13, r12, r20); // ldsmin x13, x12, [x20] - __ ldsmax(Assembler::xword, r8, r25, r20); // ldsmax x8, x25, [x20] - __ ldumin(Assembler::xword, r19, r0, r11); // ldumin x19, x0, [x11] - __ ldumax(Assembler::xword, r24, r6, r20); // ldumax x24, x6, [x20] + __ swp(Assembler::xword, r6, r16, r20); // swp x6, x16, [x20] + __ ldadd(Assembler::xword, r13, r12, r20); // ldadd x13, x12, [x20] + __ ldbic(Assembler::xword, r8, r25, r20); // ldclr x8, x25, [x20] + __ ldeor(Assembler::xword, r19, r0, r11); // ldeor x19, x0, [x11] + __ ldorr(Assembler::xword, r24, r6, r20); // ldset x24, x6, [x20] + __ ldsmin(Assembler::xword, zr, r14, r16); // ldsmin xzr, x14, [x16] + __ ldsmax(Assembler::xword, r6, r0, r7); // ldsmax x6, x0, [x7] + __ ldumin(Assembler::xword, r15, r19, r26); // ldumin x15, x19, [x26] + __ ldumax(Assembler::xword, r9, r10, r23); // ldumax x9, x10, [x23] // LSEOp - __ swpa(Assembler::xword, zr, r14, r16); // swpa xzr, x14, [x16] - __ ldadda(Assembler::xword, r6, r0, r7); // ldadda x6, x0, [x7] - __ ldbica(Assembler::xword, r15, r19, r26); // ldclra x15, x19, [x26] - __ ldeora(Assembler::xword, r9, r10, r23); // ldeora x9, x10, [x23] - __ ldorra(Assembler::xword, r21, r22, r28); // ldseta x21, x22, [x28] - __ ldsmina(Assembler::xword, r2, r3, r15); // ldsmina x2, x3, [x15] - __ ldsmaxa(Assembler::xword, r19, r20, r7); // ldsmaxa x19, x20, [x7] - __ ldumina(Assembler::xword, r4, r29, r7); // ldumina x4, x29, [x7] - __ ldumaxa(Assembler::xword, r0, r9, r16); // ldumaxa x0, x9, [x16] + __ swpa(Assembler::xword, r21, r22, r28); // swpa x21, x22, [x28] + __ ldadda(Assembler::xword, r2, r3, r15); // ldadda x2, x3, [x15] + __ ldbica(Assembler::xword, r19, r20, r7); // ldclra x19, x20, [x7] + __ ldeora(Assembler::xword, r4, r29, r7); // ldeora x4, x29, [x7] + __ ldorra(Assembler::xword, r0, r9, r16); // ldseta x0, x9, [x16] + __ ldsmina(Assembler::xword, r20, r23, r4); // ldsmina x20, x23, [x4] + __ ldsmaxa(Assembler::xword, r16, r10, r23); // ldsmaxa x16, x10, [x23] + __ ldumina(Assembler::xword, r11, r25, r6); // ldumina x11, x25, [x6] + __ ldumaxa(Assembler::xword, zr, r16, r13); // ldumaxa xzr, x16, [x13] // LSEOp - __ swpal(Assembler::xword, r20, r23, r4); // swpal x20, x23, [x4] - __ ldaddal(Assembler::xword, r16, r10, r23); // ldaddal x16, x10, [x23] - __ ldbical(Assembler::xword, r11, r25, r6); // ldclral x11, x25, [x6] - __ ldeoral(Assembler::xword, zr, r16, r13); // ldeoral xzr, x16, [x13] - __ ldorral(Assembler::xword, r23, r12, r1); // ldsetal x23, x12, [x1] - __ ldsminal(Assembler::xword, r14, r9, r21); // ldsminal x14, x9, [x21] - __ ldsmaxal(Assembler::xword, r16, r26, r15); // ldsmaxal x16, x26, [x15] - __ lduminal(Assembler::xword, r4, r4, r15); // lduminal x4, x4, [x15] - __ ldumaxal(Assembler::xword, r8, r6, r30); // ldumaxal x8, x6, [x30] + __ swpal(Assembler::xword, r23, r12, r1); // swpal x23, x12, [x1] + __ ldaddal(Assembler::xword, r14, r9, r21); // ldaddal x14, x9, [x21] + __ ldbical(Assembler::xword, r16, r26, r15); // ldclral x16, x26, [x15] + __ ldeoral(Assembler::xword, r4, r4, r15); // ldeoral x4, x4, [x15] + __ ldorral(Assembler::xword, r8, r6, r30); // ldsetal x8, x6, [x30] + __ ldsminal(Assembler::xword, r4, r29, r17); // ldsminal x4, x29, [x17] + __ ldsmaxal(Assembler::xword, r29, r26, r9); // ldsmaxal x29, x26, [x9] + __ lduminal(Assembler::xword, r15, r2, r11); // lduminal x15, x2, [x11] + __ ldumaxal(Assembler::xword, r29, r3, r7); // ldumaxal x29, x3, [x7] // LSEOp - __ swpl(Assembler::xword, r4, r29, r17); // swpl x4, x29, [x17] - __ ldaddl(Assembler::xword, r29, r26, r9); // ldaddl x29, x26, [x9] - __ ldbicl(Assembler::xword, r15, r2, r11); // ldclrl x15, x2, [x11] - __ ldeorl(Assembler::xword, r29, r3, r7); // ldeorl x29, x3, [x7] - __ ldorrl(Assembler::xword, r1, r27, r21); // ldsetl x1, x27, [x21] - __ ldsminl(Assembler::xword, r16, r14, r8); // ldsminl x16, x14, [x8] - __ ldsmaxl(Assembler::xword, r16, r22, r25); // ldsmaxl x16, x22, [x25] - __ lduminl(Assembler::xword, r5, r20, r21); // lduminl x5, x20, [x21] - __ ldumaxl(Assembler::xword, r16, r23, r16); // ldumaxl x16, x23, [x16] + __ swpl(Assembler::xword, r1, r27, r21); // swpl x1, x27, [x21] + __ ldaddl(Assembler::xword, r16, r14, r8); // ldaddl x16, x14, [x8] + __ ldbicl(Assembler::xword, r16, r22, r25); // ldclrl x16, x22, [x25] + __ ldeorl(Assembler::xword, r5, r20, r21); // ldeorl x5, x20, [x21] + __ ldorrl(Assembler::xword, r16, r23, r16); // ldsetl x16, x23, [x16] + __ ldsminl(Assembler::xword, r30, r20, r20); // ldsminl x30, x20, [x20] + __ ldsmaxl(Assembler::xword, r0, r4, r19); // ldsmaxl x0, x4, [x19] + __ lduminl(Assembler::xword, r24, r4, r20); // lduminl x24, x4, [x20] + __ ldumaxl(Assembler::xword, r4, r24, r26); // ldumaxl x4, x24, [x26] // LSEOp - __ swp(Assembler::word, r30, r20, r20); // swp w30, w20, [x20] - __ ldadd(Assembler::word, r0, r4, r19); // ldadd w0, w4, [x19] - __ ldbic(Assembler::word, r24, r4, r20); // ldclr w24, w4, [x20] - __ ldeor(Assembler::word, r4, r24, r26); // ldeor w4, w24, [x26] - __ ldorr(Assembler::word, r19, r2, r8); // ldset w19, w2, [x8] - __ ldsmin(Assembler::word, r8, r14, r24); // ldsmin w8, w14, [x24] - __ ldsmax(Assembler::word, r16, zr, r22); // ldsmax w16, wzr, [x22] - __ ldumin(Assembler::word, r4, zr, r1); // ldumin w4, wzr, [x1] - __ ldumax(Assembler::word, r10, r20, r12); // ldumax w10, w20, [x12] + __ swp(Assembler::word, r19, r2, r8); // swp w19, w2, [x8] + __ ldadd(Assembler::word, r8, r14, r24); // ldadd w8, w14, [x24] + __ ldbic(Assembler::word, r16, zr, r22); // ldclr w16, wzr, [x22] + __ ldeor(Assembler::word, r4, zr, r1); // ldeor w4, wzr, [x1] + __ ldorr(Assembler::word, r10, r20, r12); // ldset w10, w20, [x12] + __ ldsmin(Assembler::word, r0, r9, r7); // ldsmin w0, w9, [x7] + __ ldsmax(Assembler::word, r24, r16, r4); // ldsmax w24, w16, [x4] + __ ldumin(Assembler::word, r27, r6, r10); // ldumin w27, w6, [x10] + __ ldumax(Assembler::word, r27, r24, r13); // ldumax w27, w24, [x13] // LSEOp - __ swpa(Assembler::word, r0, r9, r7); // swpa w0, w9, [x7] - __ ldadda(Assembler::word, r24, r16, r4); // ldadda w24, w16, [x4] - __ ldbica(Assembler::word, r27, r6, r10); // ldclra w27, w6, [x10] - __ ldeora(Assembler::word, r27, r24, r13); // ldeora w27, w24, [x13] - __ ldorra(Assembler::word, r16, zr, r22); // ldseta w16, wzr, [x22] - __ ldsmina(Assembler::word, r22, r20, sp); // ldsmina w22, w20, [sp] - __ ldsmaxa(Assembler::word, r29, r9, r14); // ldsmaxa w29, w9, [x14] - __ ldumina(Assembler::word, r20, r7, r20); // ldumina w20, w7, [x20] - __ ldumaxa(Assembler::word, r28, r9, r11); // ldumaxa w28, w9, [x11] + __ swpa(Assembler::word, r16, zr, r22); // swpa w16, wzr, [x22] + __ ldadda(Assembler::word, r22, r20, sp); // ldadda w22, w20, [sp] + __ ldbica(Assembler::word, r29, r9, r14); // ldclra w29, w9, [x14] + __ ldeora(Assembler::word, r20, r7, r20); // ldeora w20, w7, [x20] + __ ldorra(Assembler::word, r28, r9, r11); // ldseta w28, w9, [x11] + __ ldsmina(Assembler::word, r14, r12, r20); // ldsmina w14, w12, [x20] + __ ldsmaxa(Assembler::word, r1, r24, r9); // ldsmaxa w1, w24, [x9] + __ ldumina(Assembler::word, r19, r13, r19); // ldumina w19, w13, [x19] + __ ldumaxa(Assembler::word, r16, r16, r5); // ldumaxa w16, w16, [x5] // LSEOp - __ swpal(Assembler::word, r14, r12, r20); // swpal w14, w12, [x20] - __ ldaddal(Assembler::word, r1, r24, r9); // ldaddal w1, w24, [x9] - __ ldbical(Assembler::word, r19, r13, r19); // ldclral w19, w13, [x19] - __ ldeoral(Assembler::word, r16, r16, r5); // ldeoral w16, w16, [x5] - __ ldorral(Assembler::word, r0, r3, r12); // ldsetal w0, w3, [x12] - __ ldsminal(Assembler::word, r8, r15, r15); // ldsminal w8, w15, [x15] - __ ldsmaxal(Assembler::word, r16, r4, r15); // ldsmaxal w16, w4, [x15] - __ lduminal(Assembler::word, r30, r5, r0); // lduminal w30, w5, [x0] - __ ldumaxal(Assembler::word, r10, r22, r27); // ldumaxal w10, w22, [x27] + __ swpal(Assembler::word, r0, r3, r12); // swpal w0, w3, [x12] + __ ldaddal(Assembler::word, r8, r15, r15); // ldaddal w8, w15, [x15] + __ ldbical(Assembler::word, r16, r4, r15); // ldclral w16, w4, [x15] + __ ldeoral(Assembler::word, r30, r5, r0); // ldeoral w30, w5, [x0] + __ ldorral(Assembler::word, r10, r22, r27); // ldsetal w10, w22, [x27] + __ ldsminal(Assembler::word, r3, r0, r9); // ldsminal w3, w0, [x9] + __ ldsmaxal(Assembler::word, r19, r29, r10); // ldsmaxal w19, w29, [x10] + __ lduminal(Assembler::word, r24, r4, r20); // lduminal w24, w4, [x20] + __ ldumaxal(Assembler::word, r7, r24, r29); // ldumaxal w7, w24, [x29] // LSEOp - __ swpl(Assembler::word, r3, r0, r9); // swpl w3, w0, [x9] - __ ldaddl(Assembler::word, r19, r29, r10); // ldaddl w19, w29, [x10] - __ ldbicl(Assembler::word, r24, r4, r20); // ldclrl w24, w4, [x20] - __ ldeorl(Assembler::word, r7, r24, r29); // ldeorl w7, w24, [x29] - __ ldorrl(Assembler::word, r14, r21, r11); // ldsetl w14, w21, [x11] - __ ldsminl(Assembler::word, r27, r13, r15); // ldsminl w27, w13, [x15] - __ ldsmaxl(Assembler::word, zr, r17, r14); // ldsmaxl wzr, w17, [x14] - __ lduminl(Assembler::word, r3, r30, r16); // lduminl w3, w30, [x16] - __ ldumaxl(Assembler::word, r22, r20, r7); // ldumaxl w22, w20, [x7] + __ swpl(Assembler::word, r14, r21, r11); // swpl w14, w21, [x11] + __ ldaddl(Assembler::word, r27, r13, r15); // ldaddl w27, w13, [x15] + __ ldbicl(Assembler::word, zr, r17, r14); // ldclrl wzr, w17, [x14] + __ ldeorl(Assembler::word, r3, r30, r16); // ldeorl w3, w30, [x16] + __ ldorrl(Assembler::word, r22, r20, r7); // ldsetl w22, w20, [x7] + __ ldsminl(Assembler::word, r20, r3, r1); // ldsminl w20, w3, [x1] + __ ldsmaxl(Assembler::word, r26, r19, r9); // ldsmaxl w26, w19, [x9] + __ lduminl(Assembler::word, r16, r17, r21); // lduminl w16, w17, [x21] + __ ldumaxl(Assembler::word, r0, r4, r2); // ldumaxl w0, w4, [x2] // SHA3SIMDOp - __ bcax(v20, __ T16B, v3, v1, v26); // bcax v20.16B, v3.16B, v1.16B, v26.16B - __ eor3(v19, __ T16B, v9, v16, v17); // eor3 v19.16B, v9.16B, v16.16B, v17.16B - __ rax1(v21, __ T2D, v0, v4); // rax1 v21.2D, v0.2D, v4.2D - __ xar(v2, __ T2D, v24, v14, 12); // xar v2.2D, v24.2D, v14.2D, #12 + __ bcax(v24, __ T16B, v14, v6, v11); // bcax v24.16B, v14.16B, v6.16B, v11.16B + __ eor3(v21, __ T16B, v14, v17, v30); // eor3 v21.16B, v14.16B, v17.16B, v30.16B + __ rax1(v12, __ T2D, v3, v3); // rax1 v12.2D, v3.2D, v3.2D + __ xar(v23, __ T2D, v9, v3, 49); // xar v23.2D, v9.2D, v3.2D, #49 // SHA512SIMDOp - __ sha512h(v11, __ T2D, v21, v14); // sha512h q11, q21, v14.2D - __ sha512h2(v17, __ T2D, v30, v12); // sha512h2 q17, q30, v12.2D - __ sha512su0(v3, __ T2D, v3); // sha512su0 v3.2D, v3.2D - __ sha512su1(v23, __ T2D, v9, v3); // sha512su1 v23.2D, v9.2D, v3.2D + __ sha512h(v28, __ T2D, v3, v19); // sha512h q28, q3, v19.2D + __ sha512h2(v23, __ T2D, v7, v26); // sha512h2 q23, q7, v26.2D + __ sha512su0(v21, __ T2D, v14); // sha512su0 v21.2D, v14.2D + __ sha512su1(v5, __ T2D, v8, v26); // sha512su1 v5.2D, v8.2D, v26.2D // SVEBinaryImmOp - __ sve_add(z24, __ D, 26u); // add z24.d, z24.d, #0x1a - __ sve_sub(z19, __ S, 62u); // sub z19.s, z19.s, #0x3e - __ sve_and(z26, __ S, 917504u); // and z26.s, z26.s, #0xe0000 - __ sve_eor(z8, __ D, 18442240474082197503u); // eor z8.d, z8.d, #0xfff0000000003fff - __ sve_orr(z18, __ S, 253952u); // orr z18.s, z18.s, #0x3e000 + __ sve_add(z5, __ S, 146u); // add z5.s, z5.s, #0x92 + __ sve_sub(z17, __ B, 31u); // sub z17.b, z17.b, #0x1f + __ sve_and(z9, __ S, 16744448u); // and z9.s, z9.s, #0xff8000 + __ sve_eor(z12, __ H, 33279u); // eor z12.h, z12.h, #0x81ff + __ sve_orr(z11, __ H, 49663u); // orr z11.h, z11.h, #0xc1ff // SVEBinaryImmOp - __ sve_add(z9, __ S, 97u); // add z9.s, z9.s, #0x61 - __ sve_sub(z8, __ H, 118u); // sub z8.h, z8.h, #0x76 - __ sve_and(z19, __ S, 1056980736u); // and z19.s, z19.s, #0x3f003f00 - __ sve_eor(z25, __ S, 3758350339u); // eor z25.s, z25.s, #0xe003e003 - __ sve_orr(z9, __ S, 4294459391u); // orr z9.s, z9.s, #0xfff83fff + __ sve_add(z31, __ S, 72u); // add z31.s, z31.s, #0x48 + __ sve_sub(z16, __ H, 218u); // sub z16.h, z16.h, #0xda + __ sve_and(z23, __ D, 562675075514368u); // and z23.d, z23.d, #0x1ffc000000000 + __ sve_eor(z8, __ B, 243u); // eor z8.b, z8.b, #0xf3 + __ sve_orr(z10, __ B, 239u); // orr z10.b, z10.b, #0xef // SVEBinaryImmOp - __ sve_add(z23, __ D, 183u); // add z23.d, z23.d, #0xb7 - __ sve_sub(z8, __ H, 41u); // sub z8.h, z8.h, #0x29 - __ sve_and(z28, __ D, 8064u); // and z28.d, z28.d, #0x1f80 - __ sve_eor(z15, __ D, 18428729675200069887u); // eor z15.d, z15.d, #0xffc00000000000ff - __ sve_orr(z0, __ B, 239u); // orr z0.b, z0.b, #0xef + __ sve_add(z22, __ S, 5u); // add z22.s, z22.s, #0x5 + __ sve_sub(z3, __ S, 209u); // sub z3.s, z3.s, #0xd1 + __ sve_and(z5, __ D, 17870287719452639231u); // and z5.d, z5.d, #0xf80003ffffffffff + __ sve_eor(z17, __ B, 128u); // eor z17.b, z17.b, #0x80 + __ sve_orr(z30, __ H, 49663u); // orr z30.h, z30.h, #0xc1ff // SVEBinaryImmOp - __ sve_add(z5, __ D, 243u); // add z5.d, z5.d, #0xf3 - __ sve_sub(z19, __ S, 8u); // sub z19.s, z19.s, #0x8 - __ sve_and(z13, __ H, 32256u); // and z13.h, z13.h, #0x7e00 - __ sve_eor(z0, __ S, 4294967293u); // eor z0.s, z0.s, #0xfffffffd - __ sve_orr(z21, __ S, 4294965263u); // orr z21.s, z21.s, #0xfffff80f + __ sve_add(z2, __ D, 168u); // add z2.d, z2.d, #0xa8 + __ sve_sub(z23, __ S, 240u); // sub z23.s, z23.s, #0xf0 + __ sve_and(z12, __ H, 1u); // and z12.h, z12.h, #0x1 + __ sve_eor(z15, __ S, 1u); // eor z15.s, z15.s, #0x1 + __ sve_orr(z19, __ D, 18446532967477018623u); // orr z19.d, z19.d, #0xffff3fffffffffff // SVEBinaryImmOp - __ sve_add(z12, __ H, 20u); // add z12.h, z12.h, #0x14 - __ sve_sub(z0, __ H, 190u); // sub z0.h, z0.h, #0xbe - __ sve_and(z23, __ B, 239u); // and z23.b, z23.b, #0xef - __ sve_eor(z27, __ D, 18442240474082197503u); // eor z27.d, z27.d, #0xfff0000000003fff - __ sve_orr(z22, __ B, 124u); // orr z22.b, z22.b, #0x7c + __ sve_add(z13, __ S, 179u); // add z13.s, z13.s, #0xb3 + __ sve_sub(z2, __ B, 88u); // sub z2.b, z2.b, #0x58 + __ sve_and(z20, __ H, 57855u); // and z20.h, z20.h, #0xe1ff + __ sve_eor(z24, __ H, 33279u); // eor z24.h, z24.h, #0x81ff + __ sve_orr(z20, __ S, 917504u); // orr z20.s, z20.s, #0xe0000 // SVEBinaryImmOp - __ sve_add(z20, __ H, 165u); // add z20.h, z20.h, #0xa5 - __ sve_sub(z24, __ D, 72u); // sub z24.d, z24.d, #0x48 - __ sve_and(z31, __ S, 4026535935u); // and z31.s, z31.s, #0xf0000fff - __ sve_eor(z21, __ B, 128u); // eor z21.b, z21.b, #0x80 - __ sve_orr(z30, __ S, 4294967293u); // orr z30.s, z30.s, #0xfffffffd + __ sve_add(z21, __ H, 247u); // add z21.h, z21.h, #0xf7 + __ sve_sub(z22, __ D, 253u); // sub z22.d, z22.d, #0xfd + __ sve_and(z26, __ S, 1610637312u); // and z26.s, z26.s, #0x60006000 + __ sve_eor(z11, __ H, 51199u); // eor z11.h, z11.h, #0xc7ff + __ sve_orr(z5, __ B, 128u); // orr z5.b, z5.b, #0x80 // SVEVectorOp - __ sve_add(z26, __ H, z18, z19); // add z26.h, z18.h, z19.h - __ sve_sub(z11, __ S, z13, z29); // sub z11.s, z13.s, z29.s - __ sve_fadd(z5, __ S, z1, z14); // fadd z5.s, z1.s, z14.s - __ sve_fmul(z2, __ S, z7, z10); // fmul z2.s, z7.s, z10.s - __ sve_fsub(z19, __ S, z4, z26); // fsub z19.s, z4.s, z26.s - __ sve_sqadd(z2, __ B, z3, z30); // sqadd z2.b, z3.b, z30.b - __ sve_sqsub(z20, __ D, z5, z20); // sqsub z20.d, z5.d, z20.d - __ sve_uqadd(z29, __ H, z13, z13); // uqadd z29.h, z13.h, z13.h - __ sve_uqsub(z14, __ H, z30, z1); // uqsub z14.h, z30.h, z1.h - __ sve_abs(z28, __ D, p0, z3); // abs z28.d, p0/m, z3.d - __ sve_add(z9, __ B, p6, z9); // add z9.b, p6/m, z9.b, z9.b - __ sve_and(z26, __ B, p2, z14); // and z26.b, p2/m, z26.b, z14.b - __ sve_asr(z20, __ D, p6, z7); // asr z20.d, p6/m, z20.d, z7.d - __ sve_bic(z20, __ D, p4, z6); // bic z20.d, p4/m, z20.d, z6.d - __ sve_clz(z13, __ H, p0, z29); // clz z13.h, p0/m, z29.h - __ sve_cnt(z9, __ B, p0, z1); // cnt z9.b, p0/m, z1.b - __ sve_eor(z27, __ B, p6, z15); // eor z27.b, p6/m, z27.b, z15.b - __ sve_lsl(z4, __ D, p7, z17); // lsl z4.d, p7/m, z4.d, z17.d - __ sve_lsr(z2, __ B, p0, z24); // lsr z2.b, p0/m, z2.b, z24.b - __ sve_mul(z26, __ B, p7, z13); // mul z26.b, p7/m, z26.b, z13.b - __ sve_neg(z22, __ D, p3, z16); // neg z22.d, p3/m, z16.d - __ sve_not(z17, __ D, p1, z11); // not z17.d, p1/m, z11.d - __ sve_orr(z16, __ B, p0, z16); // orr z16.b, p0/m, z16.b, z16.b - __ sve_rbit(z28, __ D, p1, z23); // rbit z28.d, p1/m, z23.d - __ sve_revb(z28, __ D, p4, z10); // revb z28.d, p4/m, z10.d - __ sve_smax(z17, __ S, p7, z7); // smax z17.s, p7/m, z17.s, z7.s - __ sve_smin(z4, __ H, p3, z24); // smin z4.h, p3/m, z4.h, z24.h - __ sve_umax(z9, __ B, p2, z11); // umax z9.b, p2/m, z9.b, z11.b - __ sve_umin(z4, __ S, p5, z22); // umin z4.s, p5/m, z4.s, z22.s - __ sve_sub(z4, __ H, p0, z15); // sub z4.h, p0/m, z4.h, z15.h - __ sve_fabs(z4, __ D, p7, z26); // fabs z4.d, p7/m, z26.d - __ sve_fadd(z5, __ S, p5, z26); // fadd z5.s, p5/m, z5.s, z26.s - __ sve_fdiv(z31, __ S, p0, z25); // fdiv z31.s, p0/m, z31.s, z25.s - __ sve_fmax(z8, __ D, p1, z3); // fmax z8.d, p1/m, z8.d, z3.d - __ sve_fmin(z7, __ D, p6, z24); // fmin z7.d, p6/m, z7.d, z24.d - __ sve_fmul(z24, __ S, p7, z17); // fmul z24.s, p7/m, z24.s, z17.s - __ sve_fneg(z10, __ S, p3, z30); // fneg z10.s, p3/m, z30.s - __ sve_frintm(z8, __ S, p6, z29); // frintm z8.s, p6/m, z29.s - __ sve_frintn(z31, __ D, p5, z31); // frintn z31.d, p5/m, z31.d - __ sve_frintp(z0, __ D, p5, z7); // frintp z0.d, p5/m, z7.d - __ sve_fsqrt(z29, __ S, p6, z22); // fsqrt z29.s, p6/m, z22.s - __ sve_fsub(z29, __ S, p6, z20); // fsub z29.s, p6/m, z29.s, z20.s - __ sve_fmad(z6, __ D, p4, z18, z13); // fmad z6.d, p4/m, z18.d, z13.d - __ sve_fmla(z21, __ S, p2, z0, z19); // fmla z21.s, p2/m, z0.s, z19.s - __ sve_fmls(z28, __ D, p1, z17, z6); // fmls z28.d, p1/m, z17.d, z6.d - __ sve_fmsb(z20, __ D, p6, z28, z14); // fmsb z20.d, p6/m, z28.d, z14.d - __ sve_fnmad(z14, __ S, p4, z10, z26); // fnmad z14.s, p4/m, z10.s, z26.s - __ sve_fnmsb(z24, __ D, p0, z11, z15); // fnmsb z24.d, p0/m, z11.d, z15.d - __ sve_fnmla(z23, __ D, p5, z20, z28); // fnmla z23.d, p5/m, z20.d, z28.d - __ sve_fnmls(z20, __ D, p7, z24, z0); // fnmls z20.d, p7/m, z24.d, z0.d - __ sve_mla(z6, __ B, p5, z13, z12); // mla z6.b, p5/m, z13.b, z12.b - __ sve_mls(z13, __ S, p7, z26, z23); // mls z13.s, p7/m, z26.s, z23.s - __ sve_and(z6, z2, z29); // and z6.d, z2.d, z29.d - __ sve_eor(z0, z29, z23); // eor z0.d, z29.d, z23.d - __ sve_orr(z4, z5, z8); // orr z4.d, z5.d, z8.d - __ sve_bic(z13, z17, z13); // bic z13.d, z17.d, z13.d - __ sve_uzp1(z8, __ H, z10, z8); // uzp1 z8.h, z10.h, z8.h - __ sve_uzp2(z19, __ S, z0, z29); // uzp2 z19.s, z0.s, z29.s - __ sve_fabd(z16, __ D, p3, z23); // fabd z16.d, p3/m, z16.d, z23.d - __ sve_bext(z23, __ B, z30, z13); // bext z23.b, z30.b, z13.b - __ sve_bdep(z25, __ H, z22, z0); // bdep z25.h, z22.h, z0.h - __ sve_eor3(z25, z30, z11); // eor3 z25.d, z25.d, z30.d, z11.d - __ sve_sqadd(z14, __ H, p5, z22); // sqadd z14.h, p5/m, z14.h, z22.h - __ sve_sqsub(z5, __ H, p4, z0); // sqsub z5.h, p4/m, z5.h, z0.h - __ sve_uqadd(z9, __ D, p0, z3); // uqadd z9.d, p0/m, z9.d, z3.d - __ sve_uqsub(z14, __ H, p1, z29); // uqsub z14.h, p1/m, z14.h, z29.h + __ sve_add(z2, __ H, z7, z10); // add z2.h, z7.h, z10.h + __ sve_sub(z19, __ H, z4, z26); // sub z19.h, z4.h, z26.h + __ sve_fadd(z2, __ S, z3, z30); // fadd z2.s, z3.s, z30.s + __ sve_fmul(z20, __ D, z5, z20); // fmul z20.d, z5.d, z20.d + __ sve_fsub(z29, __ S, z13, z13); // fsub z29.s, z13.s, z13.s + __ sve_sqadd(z14, __ H, z30, z1); // sqadd z14.h, z30.h, z1.h + __ sve_sqsub(z28, __ D, z3, z3); // sqsub z28.d, z3.d, z3.d + __ sve_uqadd(z9, __ B, z25, z9); // uqadd z9.b, z25.b, z9.b + __ sve_uqsub(z26, __ B, z10, z14); // uqsub z26.b, z10.b, z14.b + __ sve_abs(z20, __ D, p6, z7); // abs z20.d, p6/m, z7.d + __ sve_add(z20, __ D, p4, z6); // add z20.d, p4/m, z20.d, z6.d + __ sve_and(z13, __ H, p0, z29); // and z13.h, p0/m, z13.h, z29.h + __ sve_asr(z9, __ B, p0, z1); // asr z9.b, p0/m, z9.b, z1.b + __ sve_bic(z27, __ B, p6, z15); // bic z27.b, p6/m, z27.b, z15.b + __ sve_clz(z4, __ D, p7, z17); // clz z4.d, p7/m, z17.d + __ sve_cnt(z2, __ B, p0, z24); // cnt z2.b, p0/m, z24.b + __ sve_eor(z26, __ B, p7, z13); // eor z26.b, p7/m, z26.b, z13.b + __ sve_lsl(z22, __ D, p3, z16); // lsl z22.d, p3/m, z22.d, z16.d + __ sve_lsr(z17, __ D, p1, z11); // lsr z17.d, p1/m, z17.d, z11.d + __ sve_mul(z16, __ B, p0, z16); // mul z16.b, p0/m, z16.b, z16.b + __ sve_neg(z28, __ D, p1, z23); // neg z28.d, p1/m, z23.d + __ sve_not(z28, __ S, p4, z10); // not z28.s, p4/m, z10.s + __ sve_orr(z17, __ S, p7, z7); // orr z17.s, p7/m, z17.s, z7.s + __ sve_rbit(z4, __ H, p3, z24); // rbit z4.h, p3/m, z24.h + __ sve_revb(z9, __ H, p2, z11); // revb z9.h, p2/m, z11.h + __ sve_smax(z4, __ S, p5, z22); // smax z4.s, p5/m, z4.s, z22.s + __ sve_smin(z4, __ H, p0, z15); // smin z4.h, p0/m, z4.h, z15.h + __ sve_umax(z4, __ D, p7, z26); // umax z4.d, p7/m, z4.d, z26.d + __ sve_umin(z5, __ H, p5, z26); // umin z5.h, p5/m, z5.h, z26.h + __ sve_sub(z31, __ B, p0, z25); // sub z31.b, p0/m, z31.b, z25.b + __ sve_fabs(z8, __ D, p1, z3); // fabs z8.d, p1/m, z3.d + __ sve_fadd(z7, __ D, p6, z24); // fadd z7.d, p6/m, z7.d, z24.d + __ sve_fdiv(z24, __ S, p7, z17); // fdiv z24.s, p7/m, z24.s, z17.s + __ sve_fmax(z10, __ S, p3, z30); // fmax z10.s, p3/m, z10.s, z30.s + __ sve_fmin(z8, __ S, p6, z29); // fmin z8.s, p6/m, z8.s, z29.s + __ sve_fmul(z31, __ D, p5, z31); // fmul z31.d, p5/m, z31.d, z31.d + __ sve_fneg(z0, __ D, p5, z7); // fneg z0.d, p5/m, z7.d + __ sve_frintm(z29, __ S, p6, z22); // frintm z29.s, p6/m, z22.s + __ sve_frintn(z29, __ S, p6, z20); // frintn z29.s, p6/m, z20.s + __ sve_frintp(z6, __ S, p4, z18); // frintp z6.s, p4/m, z18.s + __ sve_fsqrt(z26, __ S, p5, z8); // fsqrt z26.s, p5/m, z8.s + __ sve_fsub(z19, __ S, p2, z28); // fsub z19.s, p2/m, z19.s, z28.s + __ sve_fmad(z17, __ D, p1, z30, z20); // fmad z17.d, p1/m, z30.d, z20.d + __ sve_fmla(z28, __ D, p3, z17, z14); // fmla z28.d, p3/m, z17.d, z14.d + __ sve_fmls(z10, __ S, p6, z11, z24); // fmls z10.s, p6/m, z11.s, z24.s + __ sve_fmsb(z11, __ D, p3, z28, z23); // fmsb z11.d, p3/m, z28.d, z23.d + __ sve_fnmad(z20, __ D, p7, z23, z20); // fnmad z20.d, p7/m, z23.d, z20.d + __ sve_fnmsb(z24, __ D, p0, z27, z6); // fnmsb z24.d, p0/m, z27.d, z6.d + __ sve_fnmla(z13, __ D, p3, z4, z13); // fnmla z13.d, p3/m, z4.d, z13.d + __ sve_fnmls(z26, __ S, p5, z20, z6); // fnmls z26.s, p5/m, z20.s, z6.s + __ sve_mla(z29, __ S, p7, z0, z29); // mla z29.s, p7/m, z0.s, z29.s + __ sve_mls(z3, __ D, p1, z5, z8); // mls z3.d, p1/m, z5.d, z8.d + __ sve_and(z13, z17, z13); // and z13.d, z17.d, z13.d + __ sve_eor(z8, z10, z8); // eor z8.d, z10.d, z8.d + __ sve_orr(z19, z0, z29); // orr z19.d, z0.d, z29.d + __ sve_bic(z16, z13, z23); // bic z16.d, z13.d, z23.d + __ sve_uzp1(z23, __ B, z30, z13); // uzp1 z23.b, z30.b, z13.b + __ sve_uzp2(z25, __ H, z22, z0); // uzp2 z25.h, z22.h, z0.h + __ sve_fabd(z25, __ S, p7, z11); // fabd z25.s, p7/m, z25.s, z11.s + __ sve_bext(z14, __ H, z23, z22); // bext z14.h, z23.h, z22.h + __ sve_bdep(z5, __ H, z18, z0); // bdep z5.h, z18.h, z0.h + __ sve_eor3(z9, z2, z3); // eor3 z9.d, z9.d, z2.d, z3.d + __ sve_sqadd(z14, __ H, p1, z29); // sqadd z14.h, p1/m, z14.h, z29.h + __ sve_sqsub(z14, __ D, p5, z4); // sqsub z14.d, p5/m, z14.d, z4.d + __ sve_uqadd(z27, __ S, p3, z22); // uqadd z27.s, p3/m, z27.s, z22.s + __ sve_uqsub(z31, __ S, p6, z11); // uqsub z31.s, p6/m, z31.s, z11.s // SVEReductionOp - __ sve_andv(v14, __ D, p5, z4); // andv d14, p5, z4.d - __ sve_orv(v27, __ S, p3, z22); // orv s27, p3, z22.s - __ sve_eorv(v31, __ S, p6, z11); // eorv s31, p6, z11.s - __ sve_smaxv(v12, __ B, p4, z28); // smaxv b12, p4, z28.b - __ sve_sminv(v28, __ D, p4, z4); // sminv d28, p4, z4.d - __ sve_fminv(v6, __ D, p0, z15); // fminv d6, p0, z15.d - __ sve_fmaxv(v1, __ D, p5, z18); // fmaxv d1, p5, z18.d - __ sve_fadda(v2, __ S, p2, z4); // fadda s2, p2, s2, z4.s - __ sve_uaddv(v11, __ S, p2, z28); // uaddv d11, p2, z28.s + __ sve_andv(v12, __ B, p4, z28); // andv b12, p4, z28.b + __ sve_orv(v28, __ D, p4, z4); // orv d28, p4, z4.d + __ sve_eorv(v6, __ S, p0, z15); // eorv s6, p0, z15.s + __ sve_smaxv(v1, __ S, p5, z18); // smaxv s1, p5, z18.s + __ sve_sminv(v2, __ H, p2, z4); // sminv h2, p2, z4.h + __ sve_umaxv(v11, __ S, p2, z28); // umaxv s11, p2, z28.s + __ sve_uminv(v3, __ H, p5, z31); // uminv h3, p5, z31.h + __ sve_fminv(v24, __ S, p5, z15); // fminv s24, p5, z15.s + __ sve_fmaxv(v6, __ S, p3, z8); // fmaxv s6, p3, z8.s + __ sve_fadda(v21, __ D, p7, z4); // fadda d21, p7, d21, z4.d + __ sve_uaddv(v24, __ B, p5, z6); // uaddv d24, p5, z6.b // AddWideNEONOp - __ saddwv(v3, v4, __ T8H, v5, __ T8B); // saddw v3.8H, v4.8H, v5.8B - __ saddwv2(v21, v22, __ T8H, v23, __ T16B); // saddw2 v21.8H, v22.8H, v23.16B - __ saddwv(v31, v0, __ T4S, v1, __ T4H); // saddw v31.4S, v0.4S, v1.4H - __ saddwv2(v11, v12, __ T4S, v13, __ T8H); // saddw2 v11.4S, v12.4S, v13.8H - __ saddwv(v24, v25, __ T2D, v26, __ T2S); // saddw v24.2D, v25.2D, v26.2S - __ saddwv2(v21, v22, __ T2D, v23, __ T4S); // saddw2 v21.2D, v22.2D, v23.4S - __ uaddwv(v15, v16, __ T8H, v17, __ T8B); // uaddw v15.8H, v16.8H, v17.8B - __ uaddwv2(v12, v13, __ T8H, v14, __ T16B); // uaddw2 v12.8H, v13.8H, v14.16B - __ uaddwv(v6, v7, __ T4S, v8, __ T4H); // uaddw v6.4S, v7.4S, v8.4H - __ uaddwv2(v13, v14, __ T4S, v15, __ T8H); // uaddw2 v13.4S, v14.4S, v15.8H - __ uaddwv(v8, v9, __ T2D, v10, __ T2S); // uaddw v8.2D, v9.2D, v10.2S - __ uaddwv2(v15, v16, __ T2D, v17, __ T4S); // uaddw2 v15.2D, v16.2D, v17.4S + __ saddwv(v4, v5, __ T8H, v6, __ T8B); // saddw v4.8H, v5.8H, v6.8B + __ saddwv2(v10, v11, __ T8H, v12, __ T16B); // saddw2 v10.8H, v11.8H, v12.16B + __ saddwv(v9, v10, __ T4S, v11, __ T4H); // saddw v9.4S, v10.4S, v11.4H + __ saddwv2(v25, v26, __ T4S, v27, __ T8H); // saddw2 v25.4S, v26.4S, v27.8H + __ saddwv(v10, v11, __ T2D, v12, __ T2S); // saddw v10.2D, v11.2D, v12.2S + __ saddwv2(v5, v6, __ T2D, v7, __ T4S); // saddw2 v5.2D, v6.2D, v7.4S + __ uaddwv(v31, v0, __ T8H, v1, __ T8B); // uaddw v31.8H, v0.8H, v1.8B + __ uaddwv2(v22, v23, __ T8H, v24, __ T16B); // uaddw2 v22.8H, v23.8H, v24.16B + __ uaddwv(v25, v26, __ T4S, v27, __ T4H); // uaddw v25.4S, v26.4S, v27.4H + __ uaddwv2(v15, v16, __ T4S, v17, __ T8H); // uaddw2 v15.4S, v16.4S, v17.8H + __ uaddwv(v3, v4, __ T2D, v5, __ T2S); // uaddw v3.2D, v4.2D, v5.2S + __ uaddwv2(v18, v19, __ T2D, v20, __ T4S); // uaddw2 v18.2D, v19.2D, v20.4S __ bind(forth); @@ -1449,30 +1463,30 @@ 0x9101a1a0, 0xb10a5cc8, 0xd10810aa, 0xf10fd061, 0x120cb166, 0x321764bc, 0x52174681, 0x720c0227, 0x9241018e, 0xb25a2969, 0xd278b411, 0xf26aad01, - 0x14000000, 0x17ffffd7, 0x140004bb, 0x94000000, - 0x97ffffd4, 0x940004b8, 0x3400000a, 0x34fffa2a, - 0x340096aa, 0x35000008, 0x35fff9c8, 0x35009648, - 0xb400000b, 0xb4fff96b, 0xb40095eb, 0xb500001d, - 0xb5fff91d, 0xb500959d, 0x10000013, 0x10fff8b3, - 0x10009533, 0x90000013, 0x36300016, 0x3637f836, - 0x363094b6, 0x3758000c, 0x375ff7cc, 0x3758944c, + 0x14000000, 0x17ffffd7, 0x140004c9, 0x94000000, + 0x97ffffd4, 0x940004c6, 0x3400000a, 0x34fffa2a, + 0x3400986a, 0x35000008, 0x35fff9c8, 0x35009808, + 0xb400000b, 0xb4fff96b, 0xb40097ab, 0xb500001d, + 0xb5fff91d, 0xb500975d, 0x10000013, 0x10fff8b3, + 0x100096f3, 0x90000013, 0x36300016, 0x3637f836, + 0x36309676, 0x3758000c, 0x375ff7cc, 0x3758960c, 0x128313a0, 0x528a32c7, 0x7289173b, 0x92ab3acc, 0xd2a0bf94, 0xf2c285e8, 0x9358722f, 0x330e652f, 0x53067f3b, 0x93577c53, 0xb34a1aac, 0xd35a4016, 0x13946c63, 0x93c3dbc8, 0x54000000, 0x54fff5a0, - 0x54009220, 0x54000001, 0x54fff541, 0x540091c1, - 0x54000002, 0x54fff4e2, 0x54009162, 0x54000002, - 0x54fff482, 0x54009102, 0x54000003, 0x54fff423, - 0x540090a3, 0x54000003, 0x54fff3c3, 0x54009043, - 0x54000004, 0x54fff364, 0x54008fe4, 0x54000005, - 0x54fff305, 0x54008f85, 0x54000006, 0x54fff2a6, - 0x54008f26, 0x54000007, 0x54fff247, 0x54008ec7, - 0x54000008, 0x54fff1e8, 0x54008e68, 0x54000009, - 0x54fff189, 0x54008e09, 0x5400000a, 0x54fff12a, - 0x54008daa, 0x5400000b, 0x54fff0cb, 0x54008d4b, - 0x5400000c, 0x54fff06c, 0x54008cec, 0x5400000d, - 0x54fff00d, 0x54008c8d, 0x5400000e, 0x54ffefae, - 0x54008c2e, 0x5400000f, 0x54ffef4f, 0x54008bcf, + 0x540093e0, 0x54000001, 0x54fff541, 0x54009381, + 0x54000002, 0x54fff4e2, 0x54009322, 0x54000002, + 0x54fff482, 0x540092c2, 0x54000003, 0x54fff423, + 0x54009263, 0x54000003, 0x54fff3c3, 0x54009203, + 0x54000004, 0x54fff364, 0x540091a4, 0x54000005, + 0x54fff305, 0x54009145, 0x54000006, 0x54fff2a6, + 0x540090e6, 0x54000007, 0x54fff247, 0x54009087, + 0x54000008, 0x54fff1e8, 0x54009028, 0x54000009, + 0x54fff189, 0x54008fc9, 0x5400000a, 0x54fff12a, + 0x54008f6a, 0x5400000b, 0x54fff0cb, 0x54008f0b, + 0x5400000c, 0x54fff06c, 0x54008eac, 0x5400000d, + 0x54fff00d, 0x54008e4d, 0x5400000e, 0x54ffefae, + 0x54008dee, 0x5400000f, 0x54ffef4f, 0x54008d8f, 0xd40658e1, 0xd4014d22, 0xd4046543, 0xd4273f60, 0xd44cad80, 0xd503201f, 0xd503203f, 0xd503205f, 0xd503209f, 0xd50320bf, 0xd503219f, 0xd50323bf, @@ -1613,30 +1627,33 @@ 0x0eb26e30, 0x4eae6dac, 0x2e2d6d8b, 0x6e2b6d49, 0x2e686ce6, 0x6e606ffe, 0x2eb36e51, 0x6ebd6f9b, 0x0e3eafbc, 0x4e20affe, 0x0e69ad07, 0x4e6cad6a, - 0x0eb6aeb4, 0x4eacad6a, 0x0e66b4a4, 0x4e7ab738, - 0x0eb3b651, 0x4eb3b651, 0x0e3826f6, 0x4e252483, - 0x0e7f27dd, 0x4e71260f, 0x0eb826f6, 0x4eb52693, - 0x0eb5f693, 0x4eb8f6f6, 0x4ee4f462, 0x0ed1360f, - 0x4ec834e6, 0x2eaeedac, 0x6eb2ee30, 0x6eeded8b, - 0x2ecf2dcd, 0x6ed92f17, 0x0f81100f, 0x4f848862, - 0x4fc31841, 0x0fad518b, 0x4fa780c5, 0x4fd059ee, - 0x2fa890e6, 0x4fa38841, 0x6fc1900f, 0x0f7b8149, - 0x4f4688a4, 0x0faf81cd, 0x4fa58083, 0x0e3736d5, - 0x4e393717, 0x0e61341f, 0x4e7b3759, 0x0ea43462, - 0x4ea1341f, 0x4efd379b, 0x0e343e72, 0x4e2c3d6a, - 0x0e793f17, 0x4e753e93, 0x0ea53c83, 0x4eb43e72, - 0x4ee23c20, 0x2e3b8f59, 0x6e3c8f7a, 0x2e798f17, - 0x6e648c62, 0x2eb48e72, 0x6eae8dac, 0x6ee68ca4, - 0x2e3e37bc, 0x6e2037fe, 0x2e7f37dd, 0x6e723630, - 0x2ebd379b, 0x6ea834e6, 0x6eeb3549, 0x2e3f3fdd, - 0x6e343e72, 0x2e693d07, 0x6e663ca4, 0x2ea93d07, - 0x6eb13e0f, 0x6eeb3d49, 0x0e39e717, 0x4e2ae528, - 0x4e64e462, 0x2ebee7bc, 0x6eb7e6d5, 0x6ee1e41f, - 0x2e27e4c5, 0x6e3de79b, 0x6e62e420, 0x659239e8, - 0x65d03b94, 0x65d0232d, 0x65d120c2, 0x659129f2, - 0x65933ca3, 0x25969683, 0x25961d15, 0x254d1c48, - 0x259e3f61, 0x25953b96, 0x255b91d1, 0x247686ed, - 0x24309098, 0x2462edb9, 0x24a57468, 0xba5fd3e3, + 0x0eb6aeb4, 0x4eacad6a, 0x2e26aca4, 0x6e3aaf38, + 0x2e73ae51, 0x6e73ae51, 0x2eb8aef6, 0x6ea5ac83, + 0x2e3fa7dd, 0x6e31a60f, 0x2e78a6f6, 0x6e75a693, + 0x2eb5a693, 0x6eb8a6f6, 0x0e64b462, 0x4e71b60f, + 0x0ea8b4e6, 0x4eaeb5ac, 0x0e322630, 0x4e2d258b, + 0x0e6f25cd, 0x4e792717, 0x0ea32441, 0x4ea027fe, + 0x0eb5f693, 0x4ea7f4c5, 0x4ef3f651, 0x0ec43462, + 0x4ed23630, 0x2eb8eef6, 0x6eafedcd, 0x6eeced6a, + 0x2ed72ed5, 0x6edf2fdd, 0x0fa810e6, 0x4fa38841, + 0x4fc1100f, 0x0fab5149, 0x4f8688a4, 0x4fcf59cd, + 0x2f859083, 0x4f8d898b, 0x6fce99ac, 0x0f41800f, + 0x4f6b8949, 0x0f8d818b, 0x4f838841, 0x0e343672, + 0x4e223420, 0x0e7b3759, 0x4e7c377a, 0x0eb93717, + 0x4ea43462, 0x4ef43672, 0x0e2e3dac, 0x4e263ca4, + 0x0e7e3fbc, 0x4e603ffe, 0x0ebf3fdd, 0x4eb23e30, + 0x4efd3f9b, 0x2e288ce6, 0x6e2b8d49, 0x2e7f8fdd, + 0x6e748e72, 0x2ea98d07, 0x6ea68ca4, 0x6ee98d07, + 0x2e31360f, 0x6e2b3549, 0x2e793717, 0x6e6a3528, + 0x2ea43462, 0x6ebe37bc, 0x6ef736d5, 0x2e213c1f, + 0x6e273cc5, 0x2e7d3f9b, 0x6e623c20, 0x2eb33e51, + 0x6eb13e0f, 0x6ee63ca4, 0x0e3ce77a, 0x4e2ae528, + 0x4e7ee7bc, 0x2eb8e6f6, 0x6ebde79b, 0x6efde79b, + 0x2e3be759, 0x6e39e717, 0x6e62e420, 0x65d220c2, + 0x659029f2, 0x65903ca3, 0x65d13683, 0x65913173, + 0x65d320cf, 0x25cb83c6, 0x254c0fbb, 0x251e0308, + 0x25473a05, 0x25943096, 0x259d9270, 0x2423d187, + 0x242786fa, 0x24f0f1b9, 0x24e42043, 0xba5fd3e3, 0x3a5f03e5, 0xfa411be4, 0x7a42cbe2, 0x93df03ff, 0xc820ffff, 0x8822fc7f, 0xc8247cbf, 0x88267fff, 0x4e010fe0, 0x5e040420, 0x4e081fe1, 0x4e0c1fe1, @@ -1703,55 +1720,55 @@ 0x1e741000, 0x1e743000, 0x1e761000, 0x1e763000, 0x1e781000, 0x1e783000, 0x1e7a1000, 0x1e7a3000, 0x1e7c1000, 0x1e7c3000, 0x1e7e1000, 0x1e7e3000, - 0xf8268267, 0xf82d023c, 0xf8301046, 0xf83d2083, - 0xf8263290, 0xf82d528c, 0xf8284299, 0xf8337160, - 0xf8386286, 0xf8bf820e, 0xf8a600e0, 0xf8af1353, - 0xf8a922ea, 0xf8b53396, 0xf8a251e3, 0xf8b340f4, - 0xf8a470fd, 0xf8a06209, 0xf8f48097, 0xf8f002ea, - 0xf8eb10d9, 0xf8ff21b0, 0xf8f7302c, 0xf8ee52a9, - 0xf8f041fa, 0xf8e471e4, 0xf8e863c6, 0xf864823d, - 0xf87d013a, 0xf86f1162, 0xf87d20e3, 0xf86132bb, - 0xf870510e, 0xf8704336, 0xf86572b4, 0xf8706217, - 0xb83e8294, 0xb8200264, 0xb8381284, 0xb8242358, - 0xb8333102, 0xb828530e, 0xb83042df, 0xb824703f, - 0xb82a6194, 0xb8a080e9, 0xb8b80090, 0xb8bb1146, - 0xb8bb21b8, 0xb8b032df, 0xb8b653f4, 0xb8bd41c9, - 0xb8b47287, 0xb8bc6169, 0xb8ee828c, 0xb8e10138, - 0xb8f3126d, 0xb8f020b0, 0xb8e03183, 0xb8e851ef, - 0xb8f041e4, 0xb8fe7005, 0xb8ea6376, 0xb8638120, - 0xb873015d, 0xb8781284, 0xb86723b8, 0xb86e3175, - 0xb87b51ed, 0xb87f41d1, 0xb863721e, 0xb87660f4, - 0xce216874, 0xce104533, 0xce648c15, 0xce8e3302, - 0xce6e82ab, 0xce6c87d1, 0xcec08063, 0xce638937, - 0x25e0c358, 0x25a1c7d3, 0x0580785a, 0x05426328, - 0x05009892, 0x25a0cc29, 0x2561cec8, 0x058044b3, - 0x05401c99, 0x05006b49, 0x25e0d6f7, 0x2561c528, - 0x0583c8bc, 0x0542522f, 0x05001ec0, 0x25e0de65, - 0x25a1c113, 0x05803cad, 0x0540f3c0, 0x0500ab15, - 0x2560c28c, 0x2561d7c0, 0x05801ed7, 0x0542633b, - 0x05003696, 0x2560d4b4, 0x25e1c918, 0x058021ff, - 0x05400e15, 0x0500f3de, 0x0473025a, 0x04bd05ab, - 0x658e0025, 0x658a08e2, 0x659a0493, 0x043e1062, - 0x04f418b4, 0x046d15bd, 0x04611fce, 0x04d6a07c, - 0x04001929, 0x041a09da, 0x04d098f4, 0x04db10d4, - 0x0459a3ad, 0x041aa029, 0x041919fb, 0x04d39e24, - 0x04118302, 0x04101dba, 0x04d7ae16, 0x04dea571, - 0x04180210, 0x05e786fc, 0x05e4915c, 0x04881cf1, - 0x044a0f04, 0x04090969, 0x048b16c4, 0x044101e4, - 0x04dcbf44, 0x65809745, 0x658d833f, 0x65c68468, - 0x65c79b07, 0x65829e38, 0x049dafca, 0x6582bba8, - 0x65c0b7ff, 0x65c1b4e0, 0x658dbadd, 0x65819a9d, - 0x65ed9246, 0x65b30815, 0x65e6263c, 0x65eebb94, - 0x65bad14e, 0x65efe178, 0x65fc5697, 0x65e07f14, - 0x040c55a6, 0x04977f4d, 0x043d3046, 0x04b733a0, - 0x046830a4, 0x04ed322d, 0x05686948, 0x05bd6c13, - 0x65c88ef0, 0x450db3d7, 0x4540b6d9, 0x043e3979, - 0x445896ce, 0x445a9005, 0x44d98069, 0x445b87ae, - 0x04da348e, 0x04982edb, 0x0499397f, 0x0408338c, - 0x04ca309c, 0x65c721e6, 0x65c63641, 0x65982882, - 0x04812b8b, 0x0e251083, 0x4e3712d5, 0x0e61101f, - 0x4e6d118b, 0x0eba1338, 0x4eb712d5, 0x2e31120f, - 0x6e2e11ac, 0x2e6810e6, 0x6e6f11cd, 0x2eaa1128, - 0x6eb1120f, + 0xf8268290, 0xf82d028c, 0xf8281299, 0xf8332160, + 0xf8383286, 0xf83f520e, 0xf82640e0, 0xf82f7353, + 0xf82962ea, 0xf8b58396, 0xf8a201e3, 0xf8b310f4, + 0xf8a420fd, 0xf8a03209, 0xf8b45097, 0xf8b042ea, + 0xf8ab70d9, 0xf8bf61b0, 0xf8f7802c, 0xf8ee02a9, + 0xf8f011fa, 0xf8e421e4, 0xf8e833c6, 0xf8e4523d, + 0xf8fd413a, 0xf8ef7162, 0xf8fd60e3, 0xf86182bb, + 0xf870010e, 0xf8701336, 0xf86522b4, 0xf8703217, + 0xf87e5294, 0xf8604264, 0xf8787284, 0xf8646358, + 0xb8338102, 0xb828030e, 0xb83012df, 0xb824203f, + 0xb82a3194, 0xb82050e9, 0xb8384090, 0xb83b7146, + 0xb83b61b8, 0xb8b082df, 0xb8b603f4, 0xb8bd11c9, + 0xb8b42287, 0xb8bc3169, 0xb8ae528c, 0xb8a14138, + 0xb8b3726d, 0xb8b060b0, 0xb8e08183, 0xb8e801ef, + 0xb8f011e4, 0xb8fe2005, 0xb8ea3376, 0xb8e35120, + 0xb8f3415d, 0xb8f87284, 0xb8e763b8, 0xb86e8175, + 0xb87b01ed, 0xb87f11d1, 0xb863221e, 0xb87630f4, + 0xb8745023, 0xb87a4133, 0xb87072b1, 0xb8606044, + 0xce262dd8, 0xce1179d5, 0xce638c6c, 0xce83c537, + 0xce73807c, 0xce7a84f7, 0xcec081d5, 0xce7a8905, + 0x25a0d245, 0x2521c3f1, 0x05808909, 0x05400d2c, + 0x0500154b, 0x25a0c91f, 0x2561db50, 0x0582d157, + 0x054026a8, 0x05001eca, 0x25a0c0b6, 0x25a1da23, + 0x05822dc5, 0x05400e11, 0x0500155e, 0x25e0d502, + 0x25a1de17, 0x0580040c, 0x0540000f, 0x050287b3, + 0x25a0d66d, 0x2521cb02, 0x05801d74, 0x05400d38, + 0x05007854, 0x2560def5, 0x25e1dfb6, 0x05801c3a, + 0x0540158b, 0x05000e05, 0x046a00e2, 0x047a0493, + 0x659e0062, 0x65d408b4, 0x658d05bd, 0x046113ce, + 0x04e3187c, 0x04291729, 0x042e1d5a, 0x04d6b8f4, + 0x04c010d4, 0x045a03ad, 0x04108029, 0x041b19fb, + 0x04d9be24, 0x041aa302, 0x04191dba, 0x04d38e16, + 0x04d18571, 0x04100210, 0x04d7a6fc, 0x049eb15c, + 0x04981cf1, 0x05678f04, 0x05648969, 0x048816c4, + 0x044a01e4, 0x04c91f44, 0x044b1745, 0x0401033f, + 0x04dca468, 0x65c09b07, 0x658d9e38, 0x65868fca, + 0x65879ba8, 0x65c297ff, 0x04ddb4e0, 0x6582badd, + 0x6580ba9d, 0x6581b246, 0x658db51a, 0x65818b93, + 0x65f487d1, 0x65ee0e3c, 0x65b8396a, 0x65f7af8b, + 0x65f4def4, 0x65e6e378, 0x65ed4c8d, 0x65a6769a, + 0x049d5c1d, 0x04c864a3, 0x042d322d, 0x04a83148, + 0x047d3013, 0x04f731b0, 0x052d6bd7, 0x05606ed9, + 0x65889d79, 0x4556b2ee, 0x4540b645, 0x04223869, + 0x445887ae, 0x44da948e, 0x44998edb, 0x449b997f, + 0x041a338c, 0x04d8309c, 0x049921e6, 0x04883641, + 0x044a2882, 0x04892b8b, 0x044b37e3, 0x658735f8, + 0x65862d06, 0x65d83c95, 0x040134d8, 0x0e2610a4, + 0x4e2c116a, 0x0e6b1149, 0x4e7b1359, 0x0eac116a, + 0x4ea710c5, 0x2e21101f, 0x6e3812f6, 0x2e7b1359, + 0x6e71120f, 0x2ea51083, 0x6eb41272, }; // END Generated code -- do not edit diff --git a/test/hotspot/gtest/gc/g1/test_g1CardSetContainers.cpp b/test/hotspot/gtest/gc/g1/test_g1CardSetContainers.cpp index d83d8ffeef6..91951b35405 100644 --- a/test/hotspot/gtest/gc/g1/test_g1CardSetContainers.cpp +++ b/test/hotspot/gtest/gc/g1/test_g1CardSetContainers.cpp @@ -25,6 +25,7 @@ #include "gc/g1/g1HeapRegionBounds.inline.hpp" #include "gc/shared/cardTable.hpp" #include "memory/allocation.inline.hpp" +#include "runtime/atomic.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/powerOfTwo.hpp" #include "unittest.hpp" @@ -82,48 +83,48 @@ void G1CardSetContainersTest::cardset_inlineptr_test(uint bits_per_card) { G1AddCardResult res; - G1CardSet::ContainerPtr value = G1CardSetInlinePtr(); + Atomic value{}; for (uint i = 0; i < CardsPerSet; i++) { { - G1CardSetInlinePtr cards(&value, value); + G1CardSetInlinePtr cards(&value, value.load_relaxed()); res = cards.add(i + 1, bits_per_card, CardsPerSet); ASSERT_TRUE(res == Added); } { - G1CardSetInlinePtr cards(&value, value); + G1CardSetInlinePtr cards(&value, value.load_relaxed()); ASSERT_TRUE(cards.contains(i + 1, bits_per_card)); } } for (uint i = 0; i < CardsPerSet; i++) { - G1CardSetInlinePtr cards(value); + G1CardSetInlinePtr cards(value.load_relaxed()); ASSERT_TRUE(cards.contains(i + 1, bits_per_card)); } // Try to add again, should all return that the card had been added. for (uint i = 0; i < CardsPerSet; i++) { - G1CardSetInlinePtr cards(&value, value); + G1CardSetInlinePtr cards(&value, value.load_relaxed()); res = cards.add(i + 1, bits_per_card, CardsPerSet); ASSERT_TRUE(res == Found); } // Should be no more space in set. { - G1CardSetInlinePtr cards(&value, value); + G1CardSetInlinePtr cards(&value, value.load_relaxed()); res = cards.add(CardsPerSet + 1, bits_per_card, CardsPerSet); ASSERT_TRUE(res == Overflow); } // Cards should still be in the set. for (uint i = 0; i < CardsPerSet; i++) { - G1CardSetInlinePtr cards(value); + G1CardSetInlinePtr cards(value.load_relaxed()); ASSERT_TRUE(cards.contains(i + 1, bits_per_card)); } // Boundary cards should not be in the set. { - G1CardSetInlinePtr cards(value); + G1CardSetInlinePtr cards(value.load_relaxed()); ASSERT_TRUE(!cards.contains(0, bits_per_card)); ASSERT_TRUE(!cards.contains(CardsPerSet + 1, bits_per_card)); } @@ -131,7 +132,7 @@ void G1CardSetContainersTest::cardset_inlineptr_test(uint bits_per_card) { // Verify iteration finds all cards too and only those. { G1FindCardsInRange found(1, CardsPerSet); - G1CardSetInlinePtr cards(value); + G1CardSetInlinePtr cards(value.load_relaxed()); cards.iterate(found, bits_per_card); found.verify_all_found(); } diff --git a/test/hotspot/gtest/gc/shenandoah/test_shenandoahCollectorPolicy.cpp b/test/hotspot/gtest/gc/shenandoah/test_shenandoahCollectorPolicy.cpp index b5c974f65ad..70d458ec5e5 100644 --- a/test/hotspot/gtest/gc/shenandoah/test_shenandoahCollectorPolicy.cpp +++ b/test/hotspot/gtest/gc/shenandoah/test_shenandoahCollectorPolicy.cpp @@ -28,7 +28,7 @@ TEST(ShenandoahCollectorPolicyTest, track_degen_cycles_sanity) { ShenandoahCollectorPolicy policy; EXPECT_EQ(policy.consecutive_degenerated_gc_count(), 0UL); - EXPECT_EQ(policy.generational_should_upgrade_degenerated_gc(), false); + EXPECT_EQ(policy.should_upgrade_degenerated_gc(), false); } TEST(ShenandoahCollectorPolicyTest, track_degen_cycles_no_upgrade) { @@ -36,7 +36,7 @@ TEST(ShenandoahCollectorPolicyTest, track_degen_cycles_no_upgrade) { policy.record_degenerated(true, true, true); policy.record_degenerated(true, true, true); EXPECT_EQ(policy.consecutive_degenerated_gc_count(), 2UL); - EXPECT_EQ(policy.generational_should_upgrade_degenerated_gc(), false); + EXPECT_EQ(policy.should_upgrade_degenerated_gc(), false); } TEST(ShenandoahCollectorPolicyTest, track_degen_cycles_upgrade) { @@ -44,7 +44,7 @@ TEST(ShenandoahCollectorPolicyTest, track_degen_cycles_upgrade) { policy.record_degenerated(true, true, false); policy.record_degenerated(true, true, false); EXPECT_EQ(policy.consecutive_degenerated_gc_count(), 2UL); - EXPECT_EQ(policy.generational_should_upgrade_degenerated_gc(), true); + EXPECT_EQ(policy.should_upgrade_degenerated_gc(), true); } TEST(ShenandoahCollectorPolicyTest, track_degen_cycles_reset_progress) { @@ -52,7 +52,7 @@ TEST(ShenandoahCollectorPolicyTest, track_degen_cycles_reset_progress) { policy.record_degenerated(true, true, false); policy.record_degenerated(true, true, true); EXPECT_EQ(policy.consecutive_degenerated_gc_count(), 2UL); - EXPECT_EQ(policy.generational_should_upgrade_degenerated_gc(), false); + EXPECT_EQ(policy.should_upgrade_degenerated_gc(), false); } TEST(ShenandoahCollectorPolicyTest, track_degen_cycles_full_reset) { @@ -60,7 +60,7 @@ TEST(ShenandoahCollectorPolicyTest, track_degen_cycles_full_reset) { policy.record_degenerated(true, true, false); policy.record_success_full(); EXPECT_EQ(policy.consecutive_degenerated_gc_count(), 0UL); - EXPECT_EQ(policy.generational_should_upgrade_degenerated_gc(), false); + EXPECT_EQ(policy.should_upgrade_degenerated_gc(), false); } TEST(ShenandoahCollectorPolicyTest, track_degen_cycles_reset) { @@ -68,5 +68,5 @@ TEST(ShenandoahCollectorPolicyTest, track_degen_cycles_reset) { policy.record_degenerated(true, true, false); policy.record_success_concurrent(true, true); EXPECT_EQ(policy.consecutive_degenerated_gc_count(), 0UL); - EXPECT_EQ(policy.generational_should_upgrade_degenerated_gc(), false); + EXPECT_EQ(policy.should_upgrade_degenerated_gc(), false); } diff --git a/test/hotspot/gtest/gc/z/test_zForwarding.cpp b/test/hotspot/gtest/gc/z/test_zForwarding.cpp index 5275b78fb82..6b66d43ae7f 100644 --- a/test/hotspot/gtest/gc/z/test_zForwarding.cpp +++ b/test/hotspot/gtest/gc/z/test_zForwarding.cpp @@ -44,11 +44,12 @@ using namespace testing; class ZForwardingTest : public ZTest { public: // Setup and tear down - ZHeap* _old_heap; - ZGenerationOld* _old_old; - ZGenerationYoung* _old_young; - ZAddressReserver _zaddress_reserver; - zoffset _page_offset; + ZHeap* _old_heap; + ZGenerationOld* _old_old; + ZGenerationYoung* _old_young; + ZAddressReserver _zaddress_reserver; + ZPhysicalMemoryBackingMocker _physical_backing; + zoffset _page_offset; virtual void SetUp() { _old_heap = ZHeap::_heap; @@ -73,8 +74,16 @@ public: GTEST_SKIP() << "Unable to reserve memory"; } - char* const addr = (char*)untype(ZOffset::address_unsafe(_page_offset)); - os::commit_memory(addr, ZGranuleSize, /* executable */ false); + // Setup backing storage + _physical_backing.SetUp(ZGranuleSize); + + size_t committed = _physical_backing()->commit(zbacking_offset(0), ZGranuleSize, 0); + + if (committed != ZGranuleSize) { + GTEST_SKIP() << "Unable to commit memory"; + } + + _physical_backing()->map(ZOffset::address_unsafe(_page_offset), ZGranuleSize, zbacking_offset(0)); } virtual void TearDown() { @@ -84,10 +93,12 @@ public: ZGeneration::_young = _old_young; if (_page_offset != zoffset::invalid) { - char* const addr = (char*)untype(ZOffset::address_unsafe(_page_offset)); - os::uncommit_memory(addr, ZGranuleSize, false /* executable */); + _physical_backing()->unmap(ZOffset::address_unsafe(_page_offset), ZGranuleSize); + _physical_backing()->uncommit(zbacking_offset(0), ZGranuleSize); } + _physical_backing.TearDown(); + _zaddress_reserver.TearDown(); } diff --git a/test/hotspot/gtest/gc/z/zunittest.hpp b/test/hotspot/gtest/gc/z/zunittest.hpp index 2464f821380..13a8eb10f8a 100644 --- a/test/hotspot/gtest/gc/z/zunittest.hpp +++ b/test/hotspot/gtest/gc/z/zunittest.hpp @@ -28,6 +28,7 @@ #include "gc/z/zArguments.hpp" #include "gc/z/zInitialize.hpp" #include "gc/z/zNUMA.hpp" +#include "gc/z/zPhysicalMemoryManager.hpp" #include "gc/z/zRangeRegistry.hpp" #include "gc/z/zVirtualMemory.inline.hpp" #include "gc/z/zVirtualMemoryManager.hpp" @@ -104,6 +105,54 @@ public: } }; + class ZPhysicalMemoryBackingMocker { + size_t _old_max; + ZPhysicalMemoryBacking* _backing; + bool _active; + + static size_t set_max(size_t max_capacity) { + size_t old_max = ZBackingOffsetMax; + + ZBackingOffsetMax = max_capacity; + ZBackingIndexMax = checked_cast(ZBackingOffsetMax >> ZGranuleSizeShift); + + return old_max; + } + + public: + ZPhysicalMemoryBackingMocker() + : _old_max(0), + _backing(nullptr), + _active(false) {} + + void SetUp(size_t max_capacity) { + GTEST_EXPECT_FALSE(_active) << "SetUp called twice without a TearDown"; + + _old_max = set_max(max_capacity); + + char* const mem = (char*)os::malloc(sizeof(ZPhysicalMemoryBacking), mtTest); + _backing = new (mem) ZPhysicalMemoryBacking(ZGranuleSize); + + _active = true; + } + + void TearDown() { + GTEST_EXPECT_TRUE(_active) << "TearDown called without a preceding SetUp"; + + _active = false; + + _backing->~ZPhysicalMemoryBacking(); + os::free(_backing); + _backing = nullptr; + + set_max(_old_max); + } + + ZPhysicalMemoryBacking* operator()() { + return _backing; + } + }; + private: ZAddressOffsetMaxSetter _zaddress_offset_max_setter; unsigned int _rand_seed; diff --git a/test/hotspot/gtest/metaspace/test_blocktree.cpp b/test/hotspot/gtest/metaspace/test_blocktree.cpp index 6d1e8d2884d..3bcd79c98ad 100644 --- a/test/hotspot/gtest/metaspace/test_blocktree.cpp +++ b/test/hotspot/gtest/metaspace/test_blocktree.cpp @@ -74,7 +74,7 @@ TEST_VM(metaspace, BlockTree_basic) { MetaWord* p = nullptr; MetaWord arr[10000]; - ASSERT_LE(BlockTree::MinWordSize, (size_t)6); // Sanity check. Adjust if Node is changed. + ASSERT_LE(BlockTree::MinWordSize, (size_t)7); // Sanity check. Adjust if Node is changed. const size_t minws = BlockTree::MinWordSize; diff --git a/test/hotspot/gtest/nmt/test_nmt_buffer_overflow_detection.cpp b/test/hotspot/gtest/nmt/test_nmt_buffer_overflow_detection.cpp index 5752d6df75d..c65808d3f4d 100644 --- a/test/hotspot/gtest/nmt/test_nmt_buffer_overflow_detection.cpp +++ b/test/hotspot/gtest/nmt/test_nmt_buffer_overflow_detection.cpp @@ -32,8 +32,6 @@ #include "unittest.hpp" #include "testutils.hpp" -#if !INCLUDE_ASAN - // This prefix shows up on any c heap corruption NMT detects. If unsure which assert will // come, just use this one. #define COMMON_NMT_HEAP_CORRUPTION_MESSAGE_PREFIX "NMT has detected a memory corruption bug." @@ -52,6 +50,8 @@ /////// +#if !INCLUDE_ASAN + static void test_overwrite_front() { address p = (address) os::malloc(1, mtTest); *(p - 1) = 'a'; @@ -190,4 +190,78 @@ TEST_VM_FATAL_ERROR_MSG(NMT, memory_corruption_call_stack, ".*header canary.*") os::free(p); } +#else // ASAN is enabled + +#define DEFINE_ASAN_TEST(test_function) \ + DEFINE_TEST(test_function, ".*AddressSanitizer.*") + +static void test_write_header() { + const size_t SIZE = 10; + char* p = (char*)os::malloc(SIZE, mtTest); + // sizeof(MallocHeader) == 16, pick anywheree in [p - 16, p) + *(uint16_t*)((char*)p - 5) = 1; +} + +static void test_read_header() { + const size_t SIZE = 10; + char* p = (char*)os::malloc(SIZE, mtTest); + // sizeof(MallocHeader) == 16, pick anywheree in [p - 16, p) + uint16_t read_canary = *(uint16_t*)((char*)p - 5); +} + +static void test_write_footer() { + const size_t SIZE = 10; + char* p = (char*)os::malloc(SIZE, mtTest); + uint16_t* footer_ptr = (uint16_t*)(p + SIZE); + *footer_ptr = 1; +} + +static void test_read_footer() { + const size_t SIZE = 10; + char* p = (char*)os::malloc(SIZE, mtTest); + uint16_t* footer_ptr = (uint16_t*)(p + SIZE); + uint16_t read_footer = *footer_ptr; +} + +static void test_write_header_after_realloc() { + const size_t SIZE = 10; + char* p = (char*)os::malloc(SIZE, mtTest); + p = (char*)os::realloc(p, 2 * SIZE, mtTest); + // sizeof(MallocHeader) == 16, pick anywheree in [p - 16, p) + *(uint16_t*)((char*)p - 5) = 1; +} + +static void test_read_header_after_realloc() { + const size_t SIZE = 10; + char* p = (char*)os::malloc(SIZE, mtTest); + p = (char*)os::realloc(p, 2 * SIZE, mtTest); + // sizeof(MallocHeader) == 16, pick anywheree in [p - 16, p) + uint16_t read_canary = *(uint16_t*)((char*)p - 5); +} + +static void test_write_footer_after_realloc() { + const size_t SIZE = 10; + char* p = (char*)os::malloc(SIZE, mtTest); + p = (char*)os::realloc(p, 2 * SIZE, mtTest); + uint16_t* footer_ptr = (uint16_t*)(p + 2 * SIZE); + *footer_ptr = 1; +} + +static void test_read_footer_after_realloc() { + const size_t SIZE = 10; + char* p = (char*)os::malloc(SIZE, mtTest); + p = (char*)os::realloc(p, 2 * SIZE, mtTest); + uint16_t* footer_ptr = (uint16_t*)(p + 2 * SIZE); + uint16_t read_footer = *footer_ptr; +} + +DEFINE_ASAN_TEST(test_write_header); +DEFINE_ASAN_TEST(test_read_header); +DEFINE_ASAN_TEST(test_write_footer); +DEFINE_ASAN_TEST(test_read_footer); +DEFINE_ASAN_TEST(test_write_header_after_realloc); +DEFINE_ASAN_TEST(test_read_header_after_realloc); +DEFINE_ASAN_TEST(test_write_footer_after_realloc); +DEFINE_ASAN_TEST(test_read_footer_after_realloc); + #endif // !INCLUDE_ASAN diff --git a/test/hotspot/gtest/nmt/test_nmt_cornercases.cpp b/test/hotspot/gtest/nmt/test_nmt_cornercases.cpp index d1da65cb396..24ab9888521 100644 --- a/test/hotspot/gtest/nmt/test_nmt_cornercases.cpp +++ b/test/hotspot/gtest/nmt/test_nmt_cornercases.cpp @@ -88,7 +88,6 @@ TEST_VM(NMT, realloc_failure_overflowing_size) { TEST_VM(NMT, realloc_failure_gigantic_size) { check_failing_realloc(SIZE_MAX - M); } -#endif // !INCLUDE_ASAN static void* do_realloc(void* p, size_t old_size, size_t new_size, uint8_t old_content, bool check_nmt_header) { @@ -154,8 +153,8 @@ TEST_VM(NMT, HeaderKeepsIntegrityAfterRevival) { size_t some_size = 16; void* p = os::malloc(some_size, mtTest); ASSERT_NOT_NULL(p) << "Failed to malloc()"; - MallocHeader* hdr = MallocTracker::malloc_header(p); - hdr->mark_block_as_dead(); - hdr->revive(); + MallocHeader* hdr = MallocHeader::kill_block(p); + MallocHeader::revive_block(p); check_expected_malloc_header(p, mtTest, some_size); } +#endif // !INCLUDE_ASAN \ No newline at end of file diff --git a/test/hotspot/gtest/runtime/test_atomic.cpp b/test/hotspot/gtest/runtime/test_atomic.cpp index 753dde0ca57..80e67ef0bf9 100644 --- a/test/hotspot/gtest/runtime/test_atomic.cpp +++ b/test/hotspot/gtest/runtime/test_atomic.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,15 +22,100 @@ * */ +#include "cppstdlib/new.hpp" #include "cppstdlib/type_traits.hpp" #include "metaprogramming/primitiveConversions.hpp" #include "runtime/atomic.hpp" +#include "runtime/os.hpp" #include "unittest.hpp" // These tests of Atomic only verify functionality. They don't verify // atomicity. +template +struct AtomicInitializationTestSupport { + struct Holder { + Atomic _explicitly_initialized; + Atomic _default_initialized; + Atomic _value_initialized; + + Holder() + : _explicitly_initialized(T()), + /* _default_initialized */ + _value_initialized{} + {} + }; + + struct HolderNoConstructor { + Atomic _default_initialized; + }; + + void test() { + T t = T(); + + { + Holder h; + + EXPECT_EQ(t, h._explicitly_initialized.load_relaxed()); + EXPECT_EQ(t, h._default_initialized.load_relaxed()); + EXPECT_EQ(t, h._value_initialized.load_relaxed()); + } + + { + Holder h{}; + + EXPECT_EQ(t, h._explicitly_initialized.load_relaxed()); + EXPECT_EQ(t, h._default_initialized.load_relaxed()); + EXPECT_EQ(t, h._value_initialized.load_relaxed()); + } + + { + alignas(Holder) char mem[sizeof(Holder)]; + memset(mem, 0xFF, sizeof(Holder)); + Holder* h = new (mem) Holder(); + + EXPECT_EQ(t, h->_explicitly_initialized.load_relaxed()); + EXPECT_EQ(t, h->_default_initialized.load_relaxed()); + EXPECT_EQ(t, h->_value_initialized.load_relaxed()); + } + + // No-constructor variant + + { + HolderNoConstructor h; + + EXPECT_EQ(t, h._default_initialized.load_relaxed()); + } + + { + HolderNoConstructor h{}; + + EXPECT_EQ(t, h._default_initialized.load_relaxed()); + } + + { + alignas(HolderNoConstructor) char mem[sizeof(HolderNoConstructor)]; + memset(mem, 0xFF, sizeof(HolderNoConstructor)); + HolderNoConstructor* h = new (mem) HolderNoConstructor(); + + EXPECT_EQ(t, h->_default_initialized.load_relaxed()); + } + } +}; + +TEST_VM(AtomicInitializationTest, byte) { + AtomicInitializationTestSupport().test(); +} + +TEST_VM(AtomicInitializationTest, integer) { + AtomicInitializationTestSupport().test(); +} + +TEST_VM(AtomicInitializationTest, pointer) { + AtomicInitializationTestSupport().test(); +} + template struct AtomicIntegerArithmeticTestSupport { Atomic _test_value; diff --git a/test/hotspot/gtest/runtime/test_os_reserve_between.cpp b/test/hotspot/gtest/runtime/test_os_reserve_between.cpp index 8e68be22749..7c256c7c3db 100644 --- a/test/hotspot/gtest/runtime/test_os_reserve_between.cpp +++ b/test/hotspot/gtest/runtime/test_os_reserve_between.cpp @@ -335,6 +335,8 @@ TEST_VM(os, attempt_reserve_memory_randomization_cornercases) { // Test that, regardless where the hole is in the [min, max) range, if we probe nonrandomly, we will fill that hole // as long as the range size is smaller than the number of probe attempts +// On AIX, the allocation granularity is too large and not well suited for 'small' holes, so we avoid the test +#if !defined(_AIX) TEST_VM(os, attempt_reserve_memory_between_small_range_fill_hole) { const size_t ps = os::vm_page_size(); const size_t ag = allocation_granularity(); @@ -348,3 +350,4 @@ TEST_VM(os, attempt_reserve_memory_between_small_range_fill_hole) { } } } +#endif diff --git a/test/hotspot/gtest/utilities/test_growableArray.cpp b/test/hotspot/gtest/utilities/test_growableArray.cpp index 45fc9498d27..6958da18ac3 100644 --- a/test/hotspot/gtest/utilities/test_growableArray.cpp +++ b/test/hotspot/gtest/utilities/test_growableArray.cpp @@ -232,12 +232,111 @@ protected: } } + template + static void test_remove_range(ArrayClass* a) { + // Seed initial + for (int i = 0; i < 10; i++) { + a->append(i); + } + ASSERT_EQ(a->length(), 10); + + // Remove empty range from the non-empty list, should not modify the list. + a->remove_range(0, 0); + ASSERT_EQ(a->length(), 10); + + // Remove one element from head, should result in [1 ... 9] + a->remove_range(0, 1); + ASSERT_EQ(a->length(), 9); + for (int i = 0; i < a->length(); i++) { + ASSERT_EQ(a->at(i), i + 1); + } + + // Remove one element from tail, should result in [1 ... 8] + a->remove_range(8, 9); + ASSERT_EQ(a->length(), 8); + for (int i = 0; i < a->length(); i++) { + ASSERT_EQ(a->at(i), i + 1); + } + + // Remove another empty range from the non-empty list, should not modify + a->remove_range(1, 1); + ASSERT_EQ(a->length(), 8); + + // Remove some elements from the middle, should result in [1 2 7 8] + a->remove_range(2, 6); + ASSERT_EQ(a->length(), 4); + ASSERT_EQ(a->at(0), 1); + ASSERT_EQ(a->at(1), 2); + ASSERT_EQ(a->at(2), 7); + ASSERT_EQ(a->at(3), 8); + + // Remove the rest of the elements one by one + a->remove_range(0, 1); + ASSERT_EQ(a->length(), 3); + ASSERT_EQ(a->at(0), 2); + ASSERT_EQ(a->at(1), 7); + ASSERT_EQ(a->at(2), 8); + + a->remove_range(0, 1); + ASSERT_EQ(a->length(), 2); + ASSERT_EQ(a->at(0), 7); + ASSERT_EQ(a->at(1), 8); + + a->remove_range(0, 1); + ASSERT_EQ(a->length(), 1); + ASSERT_EQ(a->at(0), 8); + + a->remove_range(0, 1); + ASSERT_EQ(a->length(), 0); + + // Remove elements from empty list with empty range, should be accepted + a->remove_range(0, 0); + ASSERT_EQ(a->length(), 0); + } + + template + static void test_remove_till(ArrayClass* a) { + // Seed initial + for (int i = 0; i < 10; i++) { + a->append(i); + } + ASSERT_EQ(a->length(), 10); + + // Remove empty range from non-empty list, should work + a->remove_till(0); + ASSERT_EQ(a->length(), 10); + + // Remove one element from head, should result in [1 ... 9] + a->remove_till(1); + ASSERT_EQ(a->length(), 9); + for (int i = 0; i < a->length(); i++) { + ASSERT_EQ(a->at(i), i + 1); + } + + // Remove two elements from head, should result in [3 ... 9] + a->remove_till(2); + ASSERT_EQ(a->length(), 7); + for (int i = 0; i < a->length(); i++) { + ASSERT_EQ(a->at(i), i + 3); + } + + // Remove remaining elements, should result in [] + a->remove_till(a->length()); + ASSERT_EQ(a->length(), 0); + + // Remove empty range from empty list, should work + a->remove_till(0); + ASSERT_EQ(a->length(), 0); + } + // Supported by all GrowableArrays enum TestEnum { Append, Clear, Capacity, - Iterator + Iterator, + RemoveRange, + RemoveTill }; template @@ -259,6 +358,14 @@ protected: test_iterator(a); break; + case RemoveRange: + test_remove_range(a); + break; + + case RemoveTill: + test_remove_till(a); + break; + default: fatal("Missing dispatch"); break; @@ -451,6 +558,14 @@ TEST_VM_F(GrowableArrayTest, iterator) { with_all_types_all_0(Iterator); } +TEST_VM_F(GrowableArrayTest, remove_range) { + with_all_types_all_0(RemoveRange); +} + +TEST_VM_F(GrowableArrayTest, remove_till) { + with_all_types_all_0(RemoveTill); +} + TEST_VM_F(GrowableArrayTest, copy) { with_no_cheap_array_append1(Copy1); } diff --git a/test/hotspot/gtest/utilities/test_metaspaceClosure.cpp b/test/hotspot/gtest/utilities/test_metaspaceClosure.cpp index b2acf45c470..c98b38b8c3c 100644 --- a/test/hotspot/gtest/utilities/test_metaspaceClosure.cpp +++ b/test/hotspot/gtest/utilities/test_metaspaceClosure.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,6 +21,7 @@ * questions. */ +#include "cds/aotGrowableArray.inline.hpp" #include "memory/allocation.hpp" #include "memory/metadataFactory.hpp" #include "memory/metaspaceClosure.hpp" @@ -58,7 +59,7 @@ public: class MyUniqueMetaspaceClosure : public MetaspaceClosure { static constexpr int SIZE = 10; - MyMetaData* _visited[SIZE]; + void* _visited[SIZE]; int _count; public: MyUniqueMetaspaceClosure() { @@ -71,11 +72,22 @@ public: virtual bool do_ref(Ref* ref, bool read_only) { MyMetaData* ptr = (MyMetaData*)ref->obj(); assert(_count < SIZE, "out of bounds"); - _visited[_count++] = ptr; + for (int i = 0; i < _count; i++) { + if (_visited[i] == (void*)ptr) { + // We have walked this before. + return false; + } + } + + // Found a new pointer. Let's walk it + _visited[_count++] = (void*)ptr; return true; // recurse } bool has_visited(MyMetaData* p) { + return has_visited((void*)p); + } + bool has_visited(void* p) { for (int i = 0; i < SIZE; i++) { if (_visited[i] == p) { return true; @@ -83,6 +95,9 @@ public: } return false; } + int visited_count() { + return _count; + } }; // iterate an Array @@ -104,7 +119,9 @@ TEST_VM(MetaspaceClosure, MSOPointerArrayRef) { MyUniqueMetaspaceClosure closure; closure.push(&array); + closure.finish(); + EXPECT_TRUE(closure.has_visited(array)) << "must be"; EXPECT_TRUE(closure.has_visited(&x)) << "must be"; EXPECT_TRUE(closure.has_visited(&y)) << "must be"; EXPECT_TRUE(closure.has_visited(&z)) << "must be"; @@ -130,8 +147,85 @@ TEST_VM(MetaspaceClosure, MSOArrayRef) { MyUniqueMetaspaceClosure closure; closure.push(&array); + closure.finish(); + EXPECT_TRUE(closure.has_visited(array)) << "must be"; EXPECT_TRUE(closure.has_visited(&x)) << "must be"; EXPECT_TRUE(closure.has_visited(&y)) << "must be"; EXPECT_TRUE(closure.has_visited(&z)) << "must be"; } + +// iterate an Array +TEST_VM(MetaspaceClosure, OtherArrayRef) { + JavaThread* THREAD = JavaThread::current(); + ClassLoaderData* cld = ClassLoaderData::the_null_class_loader_data(); + Array* array = MetadataFactory::new_array(cld, 4, THREAD); + + MyUniqueMetaspaceClosure closure; + closure.push(&array); + closure.finish(); + + EXPECT_TRUE(closure.has_visited(array)) << "must be"; +} + +// iterate an AOTGrowableArray +TEST_VM(MetaspaceClosure, GrowableArray_MSOPointer) { + AOTGrowableArray* array = new(mtClass) AOTGrowableArray(2, mtClass); + + MyMetaData x; + MyMetaData y; + MyMetaData z; + + array->push(&x); + array->push(&y); + y._a = &z; + + MyUniqueMetaspaceClosure closure; + closure.push(&array); + closure.finish(); + + EXPECT_TRUE(closure.has_visited(array)) << "must be"; + EXPECT_TRUE(closure.has_visited(&x)) << "must be"; + EXPECT_TRUE(closure.has_visited(&y)) << "must be"; + EXPECT_TRUE(closure.has_visited(&z)) << "must be"; +} + +// iterate an AOTGrowableArray +TEST_VM(MetaspaceClosure, GrowableArray_MSO) { + AOTGrowableArray* array = new(mtClass) AOTGrowableArray(4, mtClass); + + for (int i = 0; i < array->length(); i++) { + EXPECT_TRUE(array->at(i)._a == nullptr) << "should be initialized to null"; + EXPECT_TRUE(array->at(i)._b == nullptr) << "should be initialized to null"; + } + + MyMetaData x; + MyMetaData y; + MyMetaData z; + + z._a = &x; + z._b = &y; + y._a = &z; + array->push(z); + + MyUniqueMetaspaceClosure closure; + closure.push(&array); + closure.finish(); + + EXPECT_TRUE(closure.has_visited(array)) << "must be"; + EXPECT_TRUE(closure.has_visited(&x)) << "must be"; + EXPECT_TRUE(closure.has_visited(&y)) << "must be"; + EXPECT_TRUE(closure.has_visited(&z)) << "must be"; +} + +// iterate an AOTGrowableArray +TEST_VM(MetaspaceClosure, GrowableArray_jlong) { + AOTGrowableArray* array = new(mtClass) AOTGrowableArray(4, mtClass); + + MyUniqueMetaspaceClosure closure; + closure.push(&array); + closure.finish(); + + EXPECT_TRUE(closure.has_visited(array)) << "must be"; + EXPECT_TRUE(closure.visited_count() == 2) << "must visit buffer inside GrowableArray"; +} diff --git a/test/hotspot/jtreg/ProblemList-AotJdk.txt b/test/hotspot/jtreg/ProblemList-AotJdk.txt index e27e85645f5..0a2177b8edb 100644 --- a/test/hotspot/jtreg/ProblemList-AotJdk.txt +++ b/test/hotspot/jtreg/ProblemList-AotJdk.txt @@ -56,3 +56,16 @@ compiler/ciReplay/TestInliningProtectionDomain.java 0000000 generic-all # These tests fail often with AotJdk due to JDK-8323727 compiler/arguments/TestStressReflectiveCode.java 8323727 generic-all compiler/arraycopy/TestCloneWithStressReflectiveCode.java 8323727 generic-all + +############################################################################# + +# Preview project specific failures go here at the end of the file. +# +# These are NOT failures that occur with the '--enable-preview' option +# specified; those go in the appropriate ProblemList-enable-preview.txt file. +# These are failures that occur WITHOUT the '--enable-preview' option +# specified AND occur because of some issue with preview project code, +# in either implementation or test code. + +############################################################################# + diff --git a/test/hotspot/jtreg/ProblemList-StaticJdk.txt b/test/hotspot/jtreg/ProblemList-StaticJdk.txt index 1e5538ca5b9..a6112169f8d 100644 --- a/test/hotspot/jtreg/ProblemList-StaticJdk.txt +++ b/test/hotspot/jtreg/ProblemList-StaticJdk.txt @@ -1,3 +1,32 @@ +# +# Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. +# 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. +# + +############################################################################# +# +# List of quarantined tests for testing in StaticJdk mode. +# +############################################################################# + # Dynamically link with JDK/VM native libraries gtest/GTestWrapper.java 8356201 generic-all gtest/LargePageGtests.java#use-large-pages 8356201 generic-all @@ -6,3 +35,16 @@ gtest/MetaspaceGtests.java#no-ccs 8356201 generic-all gtest/NMTGtests.java#nmt-detail 8356201 generic-all gtest/NMTGtests.java#nmt-off 8356201 generic-all gtest/NMTGtests.java#nmt-summary 8356201 generic-all + +############################################################################# + +# Preview project specific failures go here at the end of the file. +# +# These are NOT failures that occur with the '--enable-preview' option +# specified; those go in the appropriate ProblemList-enable-preview.txt file. +# These are failures that occur WITHOUT the '--enable-preview' option +# specified AND occur because of some issue with preview project code, +# in either implementation or test code. + +############################################################################# + diff --git a/test/hotspot/jtreg/ProblemList-Virtual.txt b/test/hotspot/jtreg/ProblemList-Virtual.txt index 31684662194..7c4846a9fb2 100644 --- a/test/hotspot/jtreg/ProblemList-Virtual.txt +++ b/test/hotspot/jtreg/ProblemList-Virtual.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -77,3 +77,15 @@ vmTestbase/nsk/jdi/VMOutOfMemoryException/VMOutOfMemoryException001/VMOutOfMemor # to make progress when all other threads are currently suspended. vmTestbase/nsk/jdi/ThreadReference/isSuspended/issuspended002/TestDescription.java 8338713 generic-all +############################################################################# + +# Preview project specific failures go here at the end of the file. +# +# These are NOT failures that occur with the '--enable-preview' option +# specified; those go in the appropriate ProblemList-enable-preview.txt file. +# These are failures that occur WITHOUT the '--enable-preview' option +# specified AND occur because of some issue with preview project code, +# in either implementation or test code. + +############################################################################# + diff --git a/test/hotspot/jtreg/ProblemList-Xcomp.txt b/test/hotspot/jtreg/ProblemList-Xcomp.txt index 758bb32e968..e4f1774e6e0 100644 --- a/test/hotspot/jtreg/ProblemList-Xcomp.txt +++ b/test/hotspot/jtreg/ProblemList-Xcomp.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -46,3 +46,16 @@ vmTestbase/nsk/jvmti/scenarios/capability/CM03/cm03t001/TestDescription.java 829 vmTestbase/nsk/stress/thread/thread006.java 8321476 linux-all gc/arguments/TestNewSizeFlags.java 8299116 macosx-aarch64 + +############################################################################# + +# Preview project specific failures go here at the end of the file. +# +# These are NOT failures that occur with the '--enable-preview' option +# specified; those go in the appropriate ProblemList-enable-preview.txt file. +# These are failures that occur WITHOUT the '--enable-preview' option +# specified AND occur because of some issue with preview project code, +# in either implementation or test code. + +############################################################################# + diff --git a/test/hotspot/jtreg/ProblemList-enable-preview.txt b/test/hotspot/jtreg/ProblemList-enable-preview.txt index 31e09d372a8..1a831a0dde3 100644 --- a/test/hotspot/jtreg/ProblemList-enable-preview.txt +++ b/test/hotspot/jtreg/ProblemList-enable-preview.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. # 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,6 +25,8 @@ # # List of quarantined tests for testing with --enable-preview # +# These are failures that ONLY occur with the '--enable-preview' option +# specified. There are separate sub-sections for each preview project. +# ############################################################################# - diff --git a/test/hotspot/jtreg/ProblemList-jvmti-stress-agent.txt b/test/hotspot/jtreg/ProblemList-jvmti-stress-agent.txt index eb4131691c9..1e84a39c30b 100644 --- a/test/hotspot/jtreg/ProblemList-jvmti-stress-agent.txt +++ b/test/hotspot/jtreg/ProblemList-jvmti-stress-agent.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -96,3 +96,16 @@ serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitorThreadTest.java serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitorTwoAgentsTest.java 0000000 generic-all serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitorVMEventsTest.java#id0 0000000 generic-all serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitorVMEventsTest.java#id1 0000000 generic-all + +############################################################################# + +# Preview project specific failures go here at the end of the file. +# +# These are NOT failures that occur with the '--enable-preview' option +# specified; those go in the appropriate ProblemList-enable-preview.txt file. +# These are failures that occur WITHOUT the '--enable-preview' option +# specified AND occur because of some issue with preview project code, +# in either implementation or test code. + +############################################################################# + diff --git a/test/hotspot/jtreg/ProblemList-zgc.txt b/test/hotspot/jtreg/ProblemList-zgc.txt index 911e3adc9ca..3e52b7169df 100644 --- a/test/hotspot/jtreg/ProblemList-zgc.txt +++ b/test/hotspot/jtreg/ProblemList-zgc.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2019, 2026, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -113,3 +113,16 @@ compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/NativeCallTest.java compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleCodeInstallationTest.java 8343233 generic-aarch64 compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleDebugInfoTest.java 8343233 generic-aarch64 compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/VirtualObjectDebugInfoTest.java 8343233 generic-aarch64 + +############################################################################# + +# Preview project specific failures go here at the end of the file. +# +# These are NOT failures that occur with the '--enable-preview' option +# specified; those go in the appropriate ProblemList-enable-preview.txt file. +# These are failures that occur WITHOUT the '--enable-preview' option +# specified AND occur because of some issue with preview project code, +# in either implementation or test code. + +############################################################################# + diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index 84520b00056..3e4814180f6 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -77,6 +77,8 @@ compiler/interpreter/Test6833129.java 8335266 generic-i586 compiler/c2/aarch64/TestStaticCallStub.java 8359963 linux-aarch64,macosx-aarch64 +compiler/longcountedloops/TestLoopNestTooManyTraps.java 8376591 generic-all + ############################################################################# # :hotspot_gc @@ -181,3 +183,16 @@ vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn001/forceEa vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi005/TestDescription.java 8076494 windows-x64 vmTestbase/nsk/monitoring/ThreadMXBean/findMonitorDeadlockedThreads/find006/TestDescription.java 8310144 macosx-aarch64 + +############################################################################# + +# Preview project specific failures go here at the end of the file. +# +# These are NOT failures that occur with the '--enable-preview' option +# specified; those go in the appropriate ProblemList-enable-preview.txt file. +# These are failures that occur WITHOUT the '--enable-preview' option +# specified AND occur because of some issue with preview project code, +# in either implementation or test code. + +############################################################################# + diff --git a/test/hotspot/jtreg/compiler/c2/TestUnlockNodeNullMemprof.java b/test/hotspot/jtreg/compiler/c2/TestUnlockNodeNullMemprof.java new file mode 100644 index 00000000000..f86dc495fd2 --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/TestUnlockNodeNullMemprof.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8370502 + * @summary Do not segfault while adding node to IGVN worklist + * + * @run main/othervm -Xbatch ${test.main.class} + */ + +package compiler.c2; + +public class TestUnlockNodeNullMemprof { + public static void main(String[] args) { + int[] a = new int[0]; // test only valid when size is 0. + for (int i = 0; i < Integer.valueOf(10000); i++) // test only valid with boxed loop limit + try { + test(a); + } catch (ArrayIndexOutOfBoundsException e) { + } + } + + static void test(int[] a) { + for (int i = 0; i < 1;) { + a[i] = 0; + synchronized (TestUnlockNodeNullMemprof.class) { + } + for (int j = 0; Integer.valueOf(j) < 1;) + j = 0; + } + } +} diff --git a/test/hotspot/jtreg/compiler/c2/TestVerifyLoopOptimizationsHighMemUsage.java b/test/hotspot/jtreg/compiler/c2/TestVerifyLoopOptimizationsHighMemUsage.java new file mode 100644 index 00000000000..ea7f3049ec3 --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/TestVerifyLoopOptimizationsHighMemUsage.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @key stress randomness + * @bug 8370519 + * @summary C2: Hit MemLimit when running with +VerifyLoopOptimizations + * @run main/othervm -XX:CompileCommand=compileonly,${test.main.class}::* -XX:-TieredCompilation -Xbatch + * -XX:+UnlockDiagnosticVMOptions -XX:+IgnoreUnrecognizedVMOptions + * -XX:+StressLoopPeeling -XX:+VerifyLoopOptimizations + * -XX:CompileCommand=memlimit,${test.main.class}::*,600M~crash + * -XX:StressSeed=3106998670 ${test.main.class} + * @run main ${test.main.class} + */ + +package compiler.c2; + +public class TestVerifyLoopOptimizationsHighMemUsage { + public static final int N = 400; + public static long instanceCount = -13L; + public static volatile short sFld = -16143; + public static int iFld = -159; + public static float fArrFld[] = new float[N]; + + public static long lMeth(int i1) { + int i2 = 11, i3 = 37085, i4 = 177, i5 = 190, i6 = -234, i7 = 13060, + iArr[] = new int[N]; + float f = 1.179F; + double d = 2.9685; + long lArr[] = new long[N]; + for (i2 = 15; i2 < 330; ++i2) + for (i4 = 1; i4 < 5; ++i4) { + fArrFld[i4 + 1] = (++i1); + for (i6 = 2; i6 > 1; i6 -= 3) + switch ((i2 * 5) + 54) { + case 156: + if (i4 != 0) + ; + case 168: + case 342: + case 283: + case 281: + case 328: + case 322: + case 228: + case 114: + case 207: + case 209: + case 354: + case 108: + i1 <<= i1; + case 398: + case 144: + case 218: + case 116: + case 296: + case 198: + case 173: + case 105: + case 120: + case 248: + case 140: + case 352: + try { + } catch (ArithmeticException a_e) { + } + case 404: + i5 += (i6 ^ instanceCount); + case 370: + case 211: + case 231: + try { + } catch (ArithmeticException a_e) { + } + case 251: + case 179: + f += (((i6 * sFld) + i4) - + iFld); + } + } + long meth_res = i1 + i2 + i3 + i4 + i5 + i6 + i7 + Float.floatToIntBits(f) + + Double.doubleToLongBits(d) + +checkSum(iArr) + + checkSum(lArr); + return meth_res; + } + + public static long checkSum(int[] a) { + long sum = 0; + for (int j = 0; j < a.length; j++) + sum += (a[j] / (j + 1) + a[j] % (j + 1)); + return sum; + } + + public static long checkSum(long[] a) { + long sum = 0; + for (int j = 0; j < a.length; j++) + sum += (a[j] / (j + 1) + a[j] % (j + 1)); + return sum; + } + + public static void main(String[] strArr) { + for (int i = 0; i < 10; i++) + lMeth(-159); + } +} diff --git a/test/hotspot/jtreg/compiler/c2/gvn/CmpUNodeValueTests.java b/test/hotspot/jtreg/compiler/c2/gvn/CmpUNodeValueTests.java new file mode 100644 index 00000000000..cbcbda3422f --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/gvn/CmpUNodeValueTests.java @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package compiler.c2.gvn; + +import compiler.lib.generators.Generators; +import compiler.lib.ir_framework.*; +import jdk.test.lib.Asserts; + +/* + * @test + * @bug 8375653 + * @summary Test that Value computations of CmpUNode are being performed as expected. + * @library /test/lib / + * @run driver ${test.main.class} + */ +public class CmpUNodeValueTests { + public static void main(String[] args) { + TestFramework.run(); + } + + @DontInline + public static int one() { + return 1; + } + + // Move to a separate method to prevent javac folding the constant comparison + @ForceInline + public static int oneInline() { + return 1; + } + + @Run(test = {"testIntControl", "testIntLT", "testIntLE", "testIntGT", "testIntGE", "testIntEQ", "testIntNE", + "testLongControl", "testLongLT", "testLongLE", "testLongGT", "testLongGE", "testLongEQ", "testLongNE"}) + public void run() { + var stream = Generators.G.longs(); + long x = stream.next(); + long y = stream.next(); + + Asserts.assertEQ(0, testIntControl(false, false)); + Asserts.assertEQ(0, testIntControl(false, true)); + Asserts.assertEQ(0, testIntControl(true, false)); + Asserts.assertEQ(1, testIntControl(true, true)); + Asserts.assertEQ(0, testIntLT((int) x)); + Asserts.assertEQ(0, testIntLE(false, false)); + Asserts.assertEQ(0, testIntLE(false, true)); + Asserts.assertEQ(0, testIntLE(true, false)); + Asserts.assertEQ(0, testIntLE(true, true)); + Asserts.assertEQ(0, testIntGT(false, false)); + Asserts.assertEQ(0, testIntGT(false, true)); + Asserts.assertEQ(0, testIntGT(true, false)); + Asserts.assertEQ(0, testIntGT(true, true)); + Asserts.assertEQ(0, testIntGE((int) x, (int) y)); + Asserts.assertEQ(0, testIntEQ()); + Asserts.assertEQ(0, testIntNE(false, false)); + Asserts.assertEQ(0, testIntNE(false, true)); + Asserts.assertEQ(0, testIntNE(true, false)); + Asserts.assertEQ(0, testIntNE(true, true)); + + Asserts.assertEQ(0, testLongControl(false, false)); + Asserts.assertEQ(0, testLongControl(false, true)); + Asserts.assertEQ(0, testLongControl(true, false)); + Asserts.assertEQ(1, testLongControl(true, true)); + Asserts.assertEQ(0, testLongLT((int) x, false)); + Asserts.assertEQ(0, testLongLT((int) x, true)); + Asserts.assertEQ(0, testLongLE(false, false)); + Asserts.assertEQ(0, testLongLE(false, true)); + Asserts.assertEQ(0, testLongLE(true, false)); + Asserts.assertEQ(0, testLongLE(true, true)); + Asserts.assertEQ(0, testLongGT(false, false)); + Asserts.assertEQ(0, testLongGT(false, true)); + Asserts.assertEQ(0, testLongGT(true, false)); + Asserts.assertEQ(0, testLongGT(true, true)); + Asserts.assertEQ(0, testLongGE((int) x, (int) y)); + Asserts.assertEQ(0, testLongEQ()); + Asserts.assertEQ(0, testLongNE(false, false)); + Asserts.assertEQ(0, testLongNE(false, true)); + Asserts.assertEQ(0, testLongNE(true, false)); + Asserts.assertEQ(0, testLongNE(true, true)); + } + + @Test + @IR(applyIfPlatformOr = {"x64", "true", "aarch64", "true"}, counts = {IRNode.CMP_U, "1"}) + int testIntControl(boolean b1, boolean b2) { + int v1 = b1 ? 1 : -1; + int v2 = b2 ? 1 : 0; + return Integer.compareUnsigned(v1, v2) > 0 ? 0 : one(); + } + + @Test + @IR(applyIfPlatformOr = {"x64", "true", "aarch64", "true"}, failOn = {IRNode.CMP_U, IRNode.CALL}) + int testIntLT(int x) { + int v1 = x & Integer.MAX_VALUE; // Unset the highest bit, make v1 non-negative + int v2 = Integer.MIN_VALUE; + return Integer.compareUnsigned(v1, v2) < 0 ? 0 : one(); + } + + @Test + @IR(applyIfPlatformOr = {"x64", "true", "aarch64", "true"}, failOn = {IRNode.CMP_U, IRNode.CALL}) + int testIntLE(boolean b1, boolean b2) { + int v1 = b1 ? 2 : 0; + int v2 = b2 ? -1 : 2; + return Integer.compareUnsigned(v1, v2) <= 0 ? 0 : one(); + } + + @Test + @IR(applyIfPlatformOr = {"x64", "true", "aarch64", "true"}, failOn = {IRNode.CMP_U, IRNode.CALL}) + int testIntGT(boolean b1, boolean b2) { + int v1 = b1 ? Integer.MIN_VALUE : Integer.MAX_VALUE; + int v2 = b2 ? 0 : 2; + return Integer.compareUnsigned(v1, v2) > 0 ? 0 : one(); + } + + @Test + @IR(applyIfPlatformOr = {"x64", "true", "aarch64", "true"}, failOn = {IRNode.CMP_U, IRNode.CALL}) + int testIntGE(int x, int y) { + int v1 = x | Integer.MIN_VALUE; // Set the highest bit, make v1 negative + int v2 = y & Integer.MAX_VALUE; // Unset the highest bit, make v2 non-negative + return Integer.compareUnsigned(v1, v2) >= 0 ? 0 : one(); + } + + @Test + @IR(applyIfPlatformOr = {"x64", "true", "aarch64", "true"}, failOn = {IRNode.CMP_U, IRNode.CALL}) + int testIntEQ() { + return Integer.compareUnsigned(oneInline(), 1) == 0 ? 0 : one(); + } + + @Test + @IR(applyIfPlatformOr = {"x64", "true", "aarch64", "true"}, failOn = {IRNode.CMP_U, IRNode.CALL}) + int testIntNE(boolean b1, boolean b2) { + int v1 = b1 ? 1 : -1; + int v2 = b2 ? 0 : 2; + return Integer.compareUnsigned(v1, v2) != 0 ? 0 : one(); + } + + @Test + @IR(applyIfPlatformOr = {"x64", "true", "aarch64", "true"}, counts = {IRNode.CMP_UL, "1"}) + int testLongControl(boolean b1, boolean b2) { + long v1 = b1 ? 1 : -1; + long v2 = b2 ? 1 : 0; + return Long.compareUnsigned(v1, v2) > 0 ? 0 : one(); + } + + + @Test + @IR(applyIfPlatformOr = {"x64", "true", "aarch64", "true"}, failOn = {IRNode.CMP_UL, IRNode.CALL}) + int testLongLT(int x, boolean b2) { + long v1 = Integer.toUnsignedLong(x); + long v2 = Integer.MIN_VALUE; + return Long.compareUnsigned(v1, v2) < 0 ? 0 : one(); + } + + @Test + @IR(applyIfPlatformOr = {"x64", "true", "aarch64", "true"}, failOn = {IRNode.CMP_UL, IRNode.CALL}) + int testLongLE(boolean b1, boolean b2) { + long v1 = b1 ? 2 : 0; + long v2 = b2 ? -1 : 2; + return Long.compareUnsigned(v1, v2) <= 0 ? 0 : one(); + } + + @Test + @IR(applyIfPlatformOr = {"x64", "true", "aarch64", "true"}, failOn = {IRNode.CMP_UL, IRNode.CALL}) + int testLongGT(boolean b1, boolean b2) { + long v1 = b1 ? Long.MIN_VALUE : Long.MAX_VALUE; + long v2 = b2 ? 0 : 2; + return Long.compareUnsigned(v1, v2) > 0 ? 0 : one(); + } + + @Test + @IR(applyIfPlatformOr = {"x64", "true", "aarch64", "true"}, failOn = {IRNode.CMP_UL, IRNode.CALL}) + int testLongGE(int x, int y) { + long v1 = x | Long.MIN_VALUE; // Set the highest bit, make v1 negative + long v2 = y & Long.MAX_VALUE; // Unset the highest bit, make v2 non-negative + return Long.compareUnsigned(v1, v2) >= 0 ? 0 : one(); + } + + @Test + @IR(applyIfPlatformOr = {"x64", "true", "aarch64", "true"}, failOn = {IRNode.CMP_UL, IRNode.CALL}) + int testLongEQ() { + return Long.compareUnsigned(oneInline(), 1L) == 0 ? 0 : one(); + } + + @Test + @IR(applyIfPlatformOr = {"x64", "true", "aarch64", "true"}, failOn = {IRNode.CMP_UL, IRNode.CALL}) + int testLongNE(boolean b1, boolean b2) { + long v1 = b1 ? 1 : -1; + long v2 = b2 ? 0 : 2; + return Long.compareUnsigned(v1, v2) != 0 ? 0 : one(); + } +} diff --git a/test/hotspot/jtreg/compiler/ccp/TestCmpUMonotonicity.java b/test/hotspot/jtreg/compiler/ccp/TestCmpUMonotonicity.java new file mode 100644 index 00000000000..5ebdd9469fc --- /dev/null +++ b/test/hotspot/jtreg/compiler/ccp/TestCmpUMonotonicity.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package compiler.ccp; + +/* + * @test + * @bug 8375653 + * @summary Test that CmpUNode::sub conforms monotonicity + * + * @run main ${test.main.class} + * @run main/othervm -Xbatch -XX:CompileCommand=compileonly,${test.main.class}::test* ${test.main.class} + */ +public class TestCmpUMonotonicity { + public static void main(String[] args) { + for (int i = 0; i < 20000; i++) { + testInt(true, 1, 100, 2); + testInt(false, 1, 100, 2); + testLong(true, 1, 100, 2); + testLong(false, 1, 100, 2); + } + } + + private static int testInt(boolean b, int start, int limit, int step) { + int v2 = b ? 1 : -1; + int v1 = 0; + for (int i = start; i < limit; i *= step) { + if (Integer.compareUnsigned(v1, v2) < 0) { + v1 = 2; + } else { + v1 = 0; + } + } + return v1; + } + + private static long testLong(boolean b, int start, int limit, int step) { + long v2 = b ? 1 : -1; + long v1 = 0; + for (int i = start; i < limit; i *= step) { + if (Long.compareUnsigned(v1, v2) < 0) { + v1 = 2; + } else { + v1 = 0; + } + } + return v1; + } +} diff --git a/test/hotspot/jtreg/compiler/codecache/CheckSegmentedCodeCache.java b/test/hotspot/jtreg/compiler/codecache/CheckSegmentedCodeCache.java index 06b51b1641d..a99f6b83cc6 100644 --- a/test/hotspot/jtreg/compiler/codecache/CheckSegmentedCodeCache.java +++ b/test/hotspot/jtreg/compiler/codecache/CheckSegmentedCodeCache.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test CheckSegmentedCodeCache - * @bug 8015774 + * @bug 8015774 8375598 * @summary Checks VM options related to the segmented code cache * @library /test/lib * @requires vm.flagless @@ -247,5 +247,12 @@ public class CheckSegmentedCodeCache { "-XX:+PrintFlagsFinal", "-version"); verifyCodeHeapSize(pb, "NonNMethodCodeHeapSize", 83886080); + + // A large NonNMethodCodeHeapSize can make the total code cache exceed the platform limit. + // The VM should fail fast during initialization. + pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+SegmentedCodeCache", + "-XX:NonNMethodCodeHeapSize=3G", + "-version"); + failsWith(pb, "Code cache size exceeds platform limit"); } } diff --git a/test/hotspot/jtreg/compiler/corelibs/OptionalFold.java b/test/hotspot/jtreg/compiler/corelibs/OptionalFold.java new file mode 100644 index 00000000000..1f850aaf7cd --- /dev/null +++ b/test/hotspot/jtreg/compiler/corelibs/OptionalFold.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.corelibs; + +import java.util.Optional; + +import compiler.lib.ir_framework.Check; +import compiler.lib.ir_framework.IR; +import compiler.lib.ir_framework.IRNode; +import compiler.lib.ir_framework.Test; +import compiler.lib.ir_framework.TestFramework; + +/* + * @test + * @bug 8372696 + * @summary Verify constant folding for Optional, both present and absent + * @library /test/lib / + * @run driver ${test.main.class} + */ +public class OptionalFold { + + public static void main(String[] args) { + // Somehow fails with -XX:-TieredCompilation + TestFramework.runWithFlags("-XX:+TieredCompilation"); + } + + // Ensure both present and empty values can fold + static final Optional ONE = Optional.of(5), TWO = Optional.empty(); + + @Test + @IR(failOn = {IRNode.ADD_I}) + public int testSum() { + return ONE.orElse(7) + TWO.orElse(12); + } + + @Check(test = "testSum") + public void checkTestSum(int res) { + if (res != 5 + 12) { + throw new RuntimeException("incorrect result: " + res); + } + } + +} diff --git a/test/jdk/javax/sql/rowset/serial/SerialClob/SetAsciiStream.java b/test/hotspot/jtreg/compiler/cpuflags/TestUseAESCTRIntrinsicsWithUseAESDisabled.java similarity index 63% rename from test/jdk/javax/sql/rowset/serial/SerialClob/SetAsciiStream.java rename to test/hotspot/jtreg/compiler/cpuflags/TestUseAESCTRIntrinsicsWithUseAESDisabled.java index 10deaf523e9..b6c28bb6a3b 100644 --- a/test/jdk/javax/sql/rowset/serial/SerialClob/SetAsciiStream.java +++ b/test/hotspot/jtreg/compiler/cpuflags/TestUseAESCTRIntrinsicsWithUseAESDisabled.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,23 +20,20 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -import javax.sql.rowset.serial.SerialClob; -import javax.sql.rowset.serial.SerialException; /** * @test - * @bug 7077451 - * @summary tests if the correct exception is thrown when calling method setAsciiStream() on SerialClob + * @bug 8374516 + * @summary Regression test for -XX:+UseAESCTRIntrinsics -XX:-UseAES crash + * @requires os.arch=="amd64" | os.arch=="x86_64" + * @requires vm.debug + * @run main/othervm -XX:+UseAESCTRIntrinsics -XX:-UseAES compiler.cpuflags.TestUseAESCTRIntrinsicsWithUseAESDisabled */ -public class SetAsciiStream { +package compiler.cpuflags; - public static void main(String[] args) throws Exception { - SerialClob clob = new SerialClob(new char[0]); - try { - clob.setAsciiStream(0); - } catch (SerialException e) { - System.out.println("Test PASSED"); - } +public class TestUseAESCTRIntrinsicsWithUseAESDisabled { + + public static void main(String[] args) { + System.out.println("passed"); } - -} +} \ No newline at end of file diff --git a/test/hotspot/jtreg/compiler/escapeAnalysis/TestCanReduceCheckUsersDifferentIfs.java b/test/hotspot/jtreg/compiler/escapeAnalysis/TestCanReduceCheckUsersDifferentIfs.java index b71f9b2cef2..9e2d3eeb752 100644 --- a/test/hotspot/jtreg/compiler/escapeAnalysis/TestCanReduceCheckUsersDifferentIfs.java +++ b/test/hotspot/jtreg/compiler/escapeAnalysis/TestCanReduceCheckUsersDifferentIfs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -64,7 +64,7 @@ public class TestCanReduceCheckUsersDifferentIfs { // (6) CastPP(phi1) ends up at IfFalse of OuterStripMinedLoopEnd of loop (L). // (7) EA tries to reduce phi1(CheckCastPP(B), CheckCastPP(c)) and looks at // OuterStripMinedLoopEnd and asserts that if it's not an IfNode that it has - // an OpaqueNotNull which obviously is not the case and the assert fails. + // an OpaqueConstantBool which obviously is not the case and the assert fails. // (5) Found to be false after PhaseIdealLoop before EA and is folded away. if (y == 76) { @@ -77,7 +77,7 @@ public class TestCanReduceCheckUsersDifferentIfs { } // Same as testOuterStripMinedLoopEnd() but we find in (7) a ParsePredicate from the - // removed loop (L) which also does not have an OpaqueNotNull and the assert fails. + // removed loop (L) which also does not have an OpaqueConstantBool and the assert fails. static void testParsePredicate() { A a = flag ? new B() : new C(); diff --git a/test/hotspot/jtreg/compiler/igvn/TestMinMaxIdentity.java b/test/hotspot/jtreg/compiler/igvn/TestMinMaxIdentity.java index d358359ff14..5b998caf65c 100644 --- a/test/hotspot/jtreg/compiler/igvn/TestMinMaxIdentity.java +++ b/test/hotspot/jtreg/compiler/igvn/TestMinMaxIdentity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 IBM Corporation. All rights reserved. + * Copyright (c) 2025, 2026 IBM Corporation. All rights reserved. * 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,8 +122,21 @@ public class TestMinMaxIdentity { let("arg2", arg2), """ @Test - @IR(counts = {IRNode.#op, "= 1"}, - phase = CompilePhase.BEFORE_MACRO_EXPANSION) + """, + type.isFloating() ? + """ + @IR(counts = {IRNode.#op, "= 1"}, + phase = CompilePhase.BEFORE_MACRO_EXPANSION, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + @IR(counts = {IRNode.#op, "= 1"}, + phase = CompilePhase.BEFORE_MACRO_EXPANSION, + applyIfPlatform = {"riscv64", "true"}) + """ : + """ + @IR(counts = {IRNode.#op, "= 1"}, + phase = CompilePhase.BEFORE_MACRO_EXPANSION) + """, + """ @Arguments(values = {Argument.NUMBER_42, Argument.NUMBER_42}) public #type $test(#type #arg1, #type #arg2) { int i; diff --git a/test/hotspot/jtreg/compiler/intrinsics/string/TestCountPositives.java b/test/hotspot/jtreg/compiler/intrinsics/string/TestCountPositives.java index 76ef4766159..94136c71c53 100644 --- a/test/hotspot/jtreg/compiler/intrinsics/string/TestCountPositives.java +++ b/test/hotspot/jtreg/compiler/intrinsics/string/TestCountPositives.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/hotspot/jtreg/compiler/intrinsics/string/TestEncodeIntrinsics.java b/test/hotspot/jtreg/compiler/intrinsics/string/TestEncodeIntrinsics.java index 38a516e7521..0165a77d803 100644 --- a/test/hotspot/jtreg/compiler/intrinsics/string/TestEncodeIntrinsics.java +++ b/test/hotspot/jtreg/compiler/intrinsics/string/TestEncodeIntrinsics.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/hotspot/jtreg/compiler/intrinsics/string/TestHasNegatives.java b/test/hotspot/jtreg/compiler/intrinsics/string/TestHasNegatives.java index 6edf2dc2e56..f80b7f63402 100644 --- a/test/hotspot/jtreg/compiler/intrinsics/string/TestHasNegatives.java +++ b/test/hotspot/jtreg/compiler/intrinsics/string/TestHasNegatives.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/hotspot/jtreg/compiler/intrinsics/string/TestOpaqueConstantBoolNodes.java b/test/hotspot/jtreg/compiler/intrinsics/string/TestOpaqueConstantBoolNodes.java new file mode 100644 index 00000000000..b8db97f7ecb --- /dev/null +++ b/test/hotspot/jtreg/compiler/intrinsics/string/TestOpaqueConstantBoolNodes.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8374582 + * @summary Tests the creation and removal of opaque nodes at range checks points in string intrinsics. + * @requires vm.flagless + * @library /test/lib / + * @run driver ${test.main.class} + */ + +package compiler.intrinsics.string; + +import compiler.lib.ir_framework.*; + +public class TestOpaqueConstantBoolNodes { + + static byte[] bytes = new byte[42]; + + public static void main(String[] args) { + TestFramework.runWithFlags( + "-XX:CompileCommand=inline,java.lang.String::*", + "-XX:CompileCommand=inline,java.lang.StringCoding::*", + "-XX:CompileCommand=exclude,jdk.internal.util.Preconditions::checkFromIndexSize"); + } + + @Setup + private static Object[] setup() { + return new Object[] {bytes, 2, 23}; + } + + @Test + @IR(counts = {IRNode.OPAQUE_CONSTANT_BOOL, "3"}, phase = CompilePhase.AFTER_PARSING) + @IR(failOn = {IRNode.OPAQUE_CONSTANT_BOOL}, phase = CompilePhase.AFTER_MACRO_EXPANSION) + @Arguments(setup = "setup") + private static String test(byte[] bytes, int i, int l) { + return new String(bytes, i , l); + } +} + diff --git a/test/hotspot/jtreg/compiler/intrinsics/string/TestRangeCheck.java b/test/hotspot/jtreg/compiler/intrinsics/string/TestRangeCheck.java new file mode 100644 index 00000000000..3b01e0f85a4 --- /dev/null +++ b/test/hotspot/jtreg/compiler/intrinsics/string/TestRangeCheck.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8374582 + * @summary Tests handling of invalid array indices in C2 intrinsic if explicit range check in Java code is not inlined. + * @modules java.base/jdk.internal.access + * @run main/othervm + * -XX:CompileCommand=inline,java.lang.StringCoding::* + * -XX:CompileCommand=exclude,jdk.internal.util.Preconditions::checkFromIndexSize + * ${test.main.class} + */ + +package compiler.intrinsics.string; + +import jdk.internal.access.JavaLangAccess; +import jdk.internal.access.SharedSecrets; + +public class TestRangeCheck { + + private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); + + public static void main(String[] args) { + byte[] bytes = new byte[42]; + for (int i = 0; i < 10_000; ++i) { + test(bytes); + } + } + + private static int test(byte[] bytes) { + try { + // Calling `StringCoding::countPositives`, which is a "front door" + // to the `StringCoding::countPositives0` intrinsic. + // `countPositives` validates its input using + // `Preconditions::checkFromIndexSize`, which also maps to an + // intrinsic. When `checkFromIndexSize` is not inlined, C2 does not + // know about the explicit range checks, and does not cut off the + // dead code. As a result, an invalid value (e.g., `-1`) can be fed + // as input into the `countPositives0` intrinsic, get replaced + // by TOP, and cause a failure in the matcher. + return JLA.countPositives(bytes, -1, 42); + } catch (Exception e) { + return 0; + } + } +} + diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/CompilePhase.java b/test/hotspot/jtreg/compiler/lib/ir_framework/CompilePhase.java index a536808d269..1e3ba7c314e 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/CompilePhase.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/CompilePhase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -161,7 +161,7 @@ public enum CompilePhase { static { for (CompilePhase phase : CompilePhase.values()) { if (phase == PRINT_IDEAL) { - PHASES_BY_PARSED_NAME.put("print_ideal", phase); + PHASES_BY_PARSED_NAME.put("PrintIdeal", phase); } else { PHASES_BY_PARSED_NAME.put(phase.name(), phase); } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java index 3fd8e2eceb4..43cae5aa6c7 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1574,6 +1574,16 @@ public class IRNode { superWordNodes(MAX_REDUCTION_V, "MaxReductionV"); } + public static final String UMIN_REDUCTION_V = PREFIX + "UMIN_REDUCTION_V" + POSTFIX; + static { + superWordNodes(UMIN_REDUCTION_V, "UMinReductionV"); + } + + public static final String UMAX_REDUCTION_V = PREFIX + "UMAX_REDUCTION_V" + POSTFIX; + static { + superWordNodes(UMAX_REDUCTION_V, "UMaxReductionV"); + } + public static final String NEG_VF = VECTOR_PREFIX + "NEG_VF" + POSTFIX; static { vectorNode(NEG_VF, "NegVF", TYPE_FLOAT); @@ -3137,6 +3147,11 @@ public class IRNode { machOnlyNameRegex(REPLICATE_HF_IMM8, "replicateHF_imm8_gt128b"); } + public static final String OPAQUE_CONSTANT_BOOL = PREFIX + "OPAQUE_CONSTANT_BOOL" + POSTFIX; + static { + beforeMatchingNameRegex(OPAQUE_CONSTANT_BOOL, "OpaqueConstantBool"); + } + /* * Utility methods to set up IR_NODE_MAPPINGS. */ diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java index 1fea5da52ef..137efd18136 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java @@ -183,7 +183,7 @@ public class TestFramework { private List flags; private int defaultWarmup = -1; private boolean testClassesOnBootClassPath; - private boolean isAllowNotCompilable = false; + private boolean allowNotCompilable = false; /* * Public interface methods @@ -498,7 +498,7 @@ public class TestFramework { * and else it is ignored silently. */ public TestFramework allowNotCompilable() { - this.isAllowNotCompilable = true; + this.allowNotCompilable = true; return this; } @@ -721,7 +721,7 @@ public class TestFramework { nonWhiteListedFlags.forEach((f) -> System.out.println(" - " + f)); } - System.out.println(""); + System.out.println(); } /** @@ -860,8 +860,8 @@ public class TestFramework { private List anyNonWhitelistedJTregVMAndJavaOptsFlags() { List flags = Arrays.stream(Utils.getTestJavaOpts()) .map(s -> s.replaceFirst("-XX:[+|-]?|-(?=[^D|^e])", "")) - .collect(Collectors.toList()); - List nonWhiteListedFlags = new ArrayList(); + .toList(); + List nonWhiteListedFlags = new ArrayList<>(); for (String flag : flags) { if (flag.contains("agentpath")) { throw new SkippedException("Can't run test with -javaagent"); @@ -877,10 +877,10 @@ public class TestFramework { private void runTestVM(List additionalFlags) { TestVMProcess testVMProcess = new TestVMProcess(additionalFlags, testClass, helperClasses, defaultWarmup, - isAllowNotCompilable, testClassesOnBootClassPath); + allowNotCompilable, testClassesOnBootClassPath); if (shouldVerifyIR) { try { - TestClassParser testClassParser = new TestClassParser(testClass, isAllowNotCompilable); + TestClassParser testClassParser = new TestClassParser(testClass, allowNotCompilable); Matchable testClassMatchable = testClassParser.parse(testVMProcess.getHotspotPidFileName(), testVMProcess.getApplicableIRRules()); IRMatcher matcher = new IRMatcher(testClassMatchable); diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMProcess.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMProcess.java index a172dce1991..931d687b0bc 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMProcess.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMProcess.java @@ -38,7 +38,6 @@ import java.io.File; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; -import java.util.stream.Collectors; /** * This class prepares, creates, and runs the Test VM with verification of proper termination. The class also stores @@ -108,7 +107,7 @@ public class TestVMProcess { cmds.add("-XX:+UnlockDiagnosticVMOptions"); cmds.add("-XX:+WhiteBoxAPI"); // Ignore CompileCommand flags which have an impact on the profiling information. - List jtregVMFlags = Arrays.stream(Utils.getTestJavaOpts()).filter(s -> !s.contains("CompileThreshold")).collect(Collectors.toList()); + List jtregVMFlags = Arrays.stream(Utils.getTestJavaOpts()).filter(s -> !s.contains("CompileThreshold")).toList(); if (!PREFER_COMMAND_LINE_FLAGS) { cmds.addAll(jtregVMFlags); } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/IRMethod.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/IRMethod.java index 714af5c6519..893312c5196 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/IRMethod.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/IRMethod.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,7 @@ import compiler.lib.ir_framework.driver.irmatching.Matchable; import compiler.lib.ir_framework.driver.irmatching.MatchableMatcher; import compiler.lib.ir_framework.driver.irmatching.irrule.IRRule; import compiler.lib.ir_framework.driver.irmatching.parser.VMInfo; +import compiler.lib.ir_framework.driver.network.testvm.java.IRRuleIds; import compiler.lib.ir_framework.shared.TestFormat; import compiler.lib.ir_framework.shared.TestFormatException; @@ -53,14 +54,14 @@ public class IRMethod implements IRMethodMatchable { private final Method method; private final MatchableMatcher matcher; - public IRMethod(Method method, int[] ruleIds, IR[] irAnnos, Compilation compilation, VMInfo vmInfo) { + public IRMethod(Method method, IRRuleIds irRuleIds, IR[] irAnnos, Compilation compilation, VMInfo vmInfo) { this.method = method; - this.matcher = new MatchableMatcher(createIRRules(method, ruleIds, irAnnos, compilation, vmInfo)); + this.matcher = new MatchableMatcher(createIRRules(method, irRuleIds, irAnnos, compilation, vmInfo)); } - private List createIRRules(Method method, int[] ruleIds, IR[] irAnnos, Compilation compilation, VMInfo vmInfo) { + private List createIRRules(Method method, IRRuleIds irRuleIds, IR[] irAnnos, Compilation compilation, VMInfo vmInfo) { List irRules = new ArrayList<>(); - for (int ruleId : ruleIds) { + for (int ruleId : irRuleIds) { try { irRules.add(new IRRule(ruleId, irAnnos[ruleId - 1], compilation, vmInfo)); } catch (TestFormatException e) { @@ -89,13 +90,12 @@ public class IRMethod implements IRMethodMatchable { return new IRMethodMatchResult(method, matcher.match()); } - List match; for (int i = 0; i < 10; i++) { // warm up - match = matcher.match(); + matcher.match(); } long startTime = System.nanoTime(); - match = matcher.match(); + List match = matcher.match(); long endTime = System.nanoTime(); long duration = (endTime - startTime); System.out.println("Verifying IR rules for " + name() + ": " + duration + " ns = " + (duration / 1000000) + " ms"); diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/NotCompilableIRMethod.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/NotCompilableIRMethod.java index d74825c8d4f..cb99ea219fe 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/NotCompilableIRMethod.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/NotCompilableIRMethod.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. * 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,8 +24,7 @@ package compiler.lib.ir_framework.driver.irmatching.irmethod; import compiler.lib.ir_framework.IR; -import compiler.lib.ir_framework.Run; -import compiler.lib.ir_framework.RunMode; +import compiler.lib.ir_framework.Test; import java.lang.reflect.Method; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/NotCompilableIRMethodMatchResult.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/NotCompilableIRMethodMatchResult.java index 011b596cc9e..bea8dc3ab27 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/NotCompilableIRMethodMatchResult.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/NotCompilableIRMethodMatchResult.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,8 +23,7 @@ package compiler.lib.ir_framework.driver.irmatching.irmethod; -import compiler.lib.ir_framework.Run; -import compiler.lib.ir_framework.RunMode; +import compiler.lib.ir_framework.Test; import compiler.lib.ir_framework.driver.irmatching.MatchResult; import compiler.lib.ir_framework.driver.irmatching.visitor.MatchResultVisitor; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/ApplicableIRRulesParser.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/ApplicableIRRulesParser.java index 7aaf0c2b285..be44c3f3d91 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/ApplicableIRRulesParser.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/ApplicableIRRulesParser.java @@ -26,12 +26,15 @@ package compiler.lib.ir_framework.driver.irmatching.parser; import compiler.lib.ir_framework.IR; import compiler.lib.ir_framework.TestFramework; import compiler.lib.ir_framework.driver.irmatching.parser.hotspot.HotSpotPidFileParser; +import compiler.lib.ir_framework.driver.network.testvm.java.IRRuleIds; import compiler.lib.ir_framework.shared.TestFormat; import compiler.lib.ir_framework.shared.TestFrameworkException; import compiler.lib.ir_framework.test.ApplicableIRRulesPrinter; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -75,15 +78,15 @@ public class ApplicableIRRulesParser { * assembly output in {@link HotSpotPidFileParser}. */ private void createTestMethodMap(String applicableIRRules, Class testClass) { - Map irRulesMap = parseApplicableIRRules(applicableIRRules); + Map irRulesMap = parseApplicableIRRules(applicableIRRules); createTestMethodsWithApplicableIRRules(testClass, irRulesMap); } /** * Read the Applicable IR Rules emitted by the Test VM to decide if an @IR rule must be checked for a method. */ - private Map parseApplicableIRRules(String applicableIRRules) { - Map irRulesMap = new HashMap<>(); + private Map parseApplicableIRRules(String applicableIRRules) { + Map irRulesMap = new HashMap<>(); String[] applicableIRRulesLines = getApplicableIRRulesLines(applicableIRRules); for (String s : applicableIRRulesLines) { String line = s.trim(); @@ -92,8 +95,8 @@ public class ApplicableIRRulesParser { throw new TestFrameworkException("Invalid Applicable IR Rules format. No comma found: " + splitLine[0]); } String testName = splitLine[0]; - int[] irRulesIdx = getRuleIndexes(splitLine); - irRulesMap.put(testName, irRulesIdx); + IRRuleIds irRuleIds = parseIrRulesIds(splitLine); + irRulesMap.put(testName, irRuleIds); } return irRulesMap; } @@ -116,24 +119,24 @@ public class ApplicableIRRulesParser { /** * Parse rule indexes from a single line of the Applicable IR Rules in the format: */ - private int[] getRuleIndexes(String[] splitLine) { - int[] irRulesIdx = new int[splitLine.length - 1]; + private IRRuleIds parseIrRulesIds(String[] splitLine) { + List irRuleIds = new ArrayList<>(); for (int i = 1; i < splitLine.length; i++) { try { - irRulesIdx[i - 1] = Integer.parseInt(splitLine[i]); + irRuleIds.add(Integer.parseInt(splitLine[i])); } catch (NumberFormatException e) { throw new TestFrameworkException("Invalid Applicable IR Rules format. No number found: " + splitLine[i]); } } - return irRulesIdx; + return new IRRuleIds(irRuleIds); } - private void createTestMethodsWithApplicableIRRules(Class testClass, Map irRulesMap) { + private void createTestMethodsWithApplicableIRRules(Class testClass, Map irRulesMap) { for (Method m : testClass.getDeclaredMethods()) { IR[] irAnnos = m.getAnnotationsByType(IR.class); if (irAnnos.length > 0) { // Validation of legal @IR attributes and placement of the annotation was already done in Test VM. - int[] irRuleIds = irRulesMap.get(m.getName()); + IRRuleIds irRuleIds = irRulesMap.get(m.getName()); validateIRRuleIds(m, irAnnos, irRuleIds); if (hasAnyApplicableIRRules(irRuleIds)) { testMethods.put(m.getName(), new TestMethod(m, irAnnos, irRuleIds)); @@ -142,18 +145,18 @@ public class ApplicableIRRulesParser { } } - private void validateIRRuleIds(Method m, IR[] irAnnos, int[] ids) { - TestFramework.check(ids != null, "Should find method name in validIrRulesMap for " + m); - TestFramework.check(ids.length > 0, "Did not find any rule indices for " + m); - TestFramework.check((ids[0] >= 1 || ids[0] == ApplicableIRRulesPrinter.NO_RULE_APPLIED) - && ids[ids.length - 1] <= irAnnos.length, + private void validateIRRuleIds(Method m, IR[] irAnnos, IRRuleIds irRuleIds) { + TestFramework.check(irRuleIds != null, "Should find method name in validIrRulesMap for " + m); + TestFramework.check(!irRuleIds.isEmpty(), "Did not find any rule indices for " + m); + TestFramework.check((irRuleIds.first() >= 1 || irRuleIds.first() == ApplicableIRRulesPrinter.NO_RULE_APPLIED) + && irRuleIds.last() <= irAnnos.length, "Invalid IR rule index found in validIrRulesMap for " + m); } /** * Does the list of IR rules contain any applicable IR rules for the given conditions? */ - private boolean hasAnyApplicableIRRules(int[] irRuleIds) { - return irRuleIds[0] != ApplicableIRRulesPrinter.NO_RULE_APPLIED; + private boolean hasAnyApplicableIRRules(IRRuleIds irRuleIds) { + return irRuleIds.first() != ApplicableIRRulesPrinter.NO_RULE_APPLIED; } } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/IRMethodBuilder.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/IRMethodBuilder.java index d7a10acd1cd..46a237576e6 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/IRMethodBuilder.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/IRMethodBuilder.java @@ -71,9 +71,9 @@ class IRMethodBuilder { Test[] testAnnos = testMethod.method().getAnnotationsByType(Test.class); boolean allowMethodNotCompilable = allowNotCompilable || testAnnos[0].allowNotCompilable(); if (allowMethodNotCompilable) { - return new NotCompilableIRMethod(testMethod.method(), testMethod.irRuleIds().length); + return new NotCompilableIRMethod(testMethod.method(), testMethod.irRuleIds().count()); } else { - return new NotCompiledIRMethod(testMethod.method(), testMethod.irRuleIds().length); + return new NotCompiledIRMethod(testMethod.method(), testMethod.irRuleIds().count()); } } } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/TestMethod.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/TestMethod.java index 43f27c80ac6..37989d8810b 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/TestMethod.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/TestMethod.java @@ -26,6 +26,7 @@ package compiler.lib.ir_framework.driver.irmatching.parser; import compiler.lib.ir_framework.IR; import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethod; import compiler.lib.ir_framework.driver.irmatching.parser.hotspot.LoggedMethod; +import compiler.lib.ir_framework.driver.network.testvm.java.IRRuleIds; import java.lang.reflect.Method; @@ -40,9 +41,9 @@ import java.lang.reflect.Method; public class TestMethod { private final Method method; private final IR[] irAnnos; - private final int[] irRuleIds; + private final IRRuleIds irRuleIds; - public TestMethod(Method m, IR[] irAnnos, int[] irRuleIds) { + public TestMethod(Method m, IR[] irAnnos, IRRuleIds irRuleIds) { this.method = m; this.irAnnos = irAnnos; this.irRuleIds = irRuleIds; @@ -56,7 +57,7 @@ public class TestMethod { return irAnnos; } - public int[] irRuleIds() { + public IRRuleIds irRuleIds() { return irRuleIds; } } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/report/FailureMessageBuilder.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/report/FailureMessageBuilder.java index 9cbba83e90b..f52c5f8fb5f 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/report/FailureMessageBuilder.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/report/FailureMessageBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -82,7 +82,8 @@ public class FailureMessageBuilder implements MatchResultVisitor { msg.append(System.lineSeparator()); } msg.append(methodIndex).append(") "); - msg.append("Method \"").append(method) + msg.append("Method \"") + .append(method.getDeclaringClass().getTypeName()).append("::").append(method.getName()) .append("\" - [Failed IR rules: ").append(failedIRRules).append("]:") .append(System.lineSeparator()); } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/IRRuleIds.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/IRRuleIds.java new file mode 100644 index 00000000000..b8ea1765b4f --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/IRRuleIds.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.lib.ir_framework.driver.network.testvm.java; + +import compiler.lib.ir_framework.IR; +import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethod; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Stream; + +/** + * Class to hold the indices of the applicable {@link IR @IR} rules of an {@link IRMethod}. + */ +public class IRRuleIds implements Iterable { + private final List ruleIds; + + public IRRuleIds(List ruleIds) { + this.ruleIds = ruleIds; + } + + public int first() { + return ruleIds.getFirst(); + } + + public int last() { + return ruleIds.getLast(); + } + + public boolean isEmpty() { + return ruleIds.isEmpty(); + } + + public int count() { + return ruleIds.size(); + } + + @Override + public Iterator iterator() { + return ruleIds.iterator(); + } + + public Stream stream() { + return ruleIds.stream(); + } +} diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/test/TestVM.java b/test/hotspot/jtreg/compiler/lib/ir_framework/test/TestVM.java index c5ab318d67d..14551141cd7 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/test/TestVM.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/test/TestVM.java @@ -92,7 +92,7 @@ public class TestVM { static final boolean XCOMP = Platform.isComp(); static final boolean VERBOSE = Boolean.getBoolean("Verbose"); - private static final boolean PRINT_TIMES = Boolean.getBoolean("PrintTimes"); + private static final boolean PRINT_TIMES = Boolean.getBoolean("PrintTimes") || VERBOSE; public static final boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler"); static final boolean EXCLUDE_RANDOM = Boolean.getBoolean("ExcludeRandom"); private static final String TESTLIST = System.getProperty("Test", ""); @@ -588,6 +588,11 @@ public class TestVM { } private void checkTestAnnotations(Method m, Test testAnno) { + List overloads = Arrays.stream(testClass.getDeclaredMethods()).filter(other -> !m.equals(other) && m.getName().equals(other.getName())).toList(); + TestFormat.check(overloads.isEmpty(), + "Cannot overload @Test methods, but method " + m + " has " + overloads.size() + " overload" + (overloads.size() == 1 ? "" : "s") + ":" + + overloads.stream().map(String::valueOf).collect(Collectors.joining("\n - ", "\n - ", "")) + ); TestFormat.check(!testMethodMap.containsKey(m.getName()), "Cannot overload two @Test methods: " + m + ", " + testMethodMap.get(m.getName())); TestFormat.check(testAnno != null, m + " must be a method with a @Test annotation"); @@ -823,14 +828,14 @@ public class TestVM { forceCompileMap.forEach((key, value) -> builder.append("- ").append(key).append(" at CompLevel.").append(value) .append(System.lineSeparator())); throw new TestRunException("Could not force compile the following @ForceCompile methods:" - + System.lineSeparator() + builder.toString()); + + System.lineSeparator() + builder); } /** * Once all framework tests are collected, they are run in this method. */ private void runTests() { - TreeMap durations = (PRINT_TIMES || VERBOSE) ? new TreeMap<>() : null; + TreeMap durations = PRINT_TIMES ? new TreeMap<>() : null; long startTime = System.nanoTime(); List testList; boolean testFilterPresent = testFilterPresent(); @@ -867,11 +872,11 @@ public class TestVM { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); - builder.append(test.toString()).append(":").append(System.lineSeparator()).append(sw.toString()) + builder.append(test).append(":").append(System.lineSeparator()).append(sw) .append(System.lineSeparator()).append(System.lineSeparator()); failures++; } - if (PRINT_TIMES || VERBOSE) { + if (PRINT_TIMES) { long endTime = System.nanoTime(); long duration = (endTime - startTime); durations.put(duration, test.getName()); @@ -886,7 +891,7 @@ public class TestVM { } // Print execution times - if (VERBOSE || PRINT_TIMES) { + if (PRINT_TIMES) { TestFrameworkSocket.write("Test execution times:", PRINT_TIMES_TAG, true); for (Map.Entry entry : durations.entrySet()) { TestFrameworkSocket.write(String.format("%-25s%15d ns%n", entry.getValue() + ":", entry.getKey()), @@ -898,7 +903,7 @@ public class TestVM { // Finally, report all occurred exceptions in a nice format. String msg = System.lineSeparator() + System.lineSeparator() + "Test Failures (" + failures + ")" + System.lineSeparator() + "----------------" + "-".repeat(String.valueOf(failures).length()); - throw new TestRunException(msg + System.lineSeparator() + builder.toString()); + throw new TestRunException(msg + System.lineSeparator() + builder); } } diff --git a/test/hotspot/jtreg/compiler/longcountedloops/TestLoopNestTooManyTraps.java b/test/hotspot/jtreg/compiler/longcountedloops/TestLoopNestTooManyTraps.java new file mode 100644 index 00000000000..502afc56548 --- /dev/null +++ b/test/hotspot/jtreg/compiler/longcountedloops/TestLoopNestTooManyTraps.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2026 IBM Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8350330 + * @summary C2: PhaseIdealLoop::add_parse_predicate() should mirror GraphKit::add_parse_predicate() + * @library /test/lib / + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:-BackgroundCompilation -XX:-ShortRunningLongLoop -XX:-UseOnStackReplacement + * -XX:CompileOnly=*TestLoopNestTooManyTraps::test1 -XX:LoopMaxUnroll=0 + * compiler.longcountedloops.TestLoopNestTooManyTraps + */ + +package compiler.longcountedloops; + +import java.lang.reflect.Method; +import java.util.Objects; +import jdk.test.whitebox.WhiteBox; + +public class TestLoopNestTooManyTraps { + private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + + public static void main(String[] args) throws NoSuchMethodException { + Method methodTest1 = TestLoopNestTooManyTraps.class.getDeclaredMethod("test1", int.class, long.class); + + for (int j = 0; j < 10; j++) { + System.out.println("iteration " + j); + for (int i = 0; i < 20_000; i++) { + test1(1000, 1000); + } + if (!WHITE_BOX.isMethodCompiled(methodTest1)) { + throw new RuntimeException("test1 should be compiled"); + } + System.out.println("iteration 2 " + j); + try { + test1(10000, 1000); + } catch (IndexOutOfBoundsException ioobe) { + } + if (j <= 1) { + if (WHITE_BOX.isMethodCompiled(methodTest1)) { + throw new RuntimeException("test1 should have deoptimized at iteration " + j); + } + } else { + if (!WHITE_BOX.isMethodCompiled(methodTest1)) { + throw new RuntimeException("test1 shouldn't have deoptimized"); + } + } + } + } + + private static void test1(int stop, long length) { + for (int i = 0; i < stop; i++) { + Objects.checkIndex(i, length); + } + } +} diff --git a/test/hotspot/jtreg/compiler/patches/java.base/java/lang/Helper.java b/test/hotspot/jtreg/compiler/patches/java.base/java/lang/Helper.java index e6c8b68fc6f..19eb98af3ba 100644 --- a/test/hotspot/jtreg/compiler/patches/java.base/java/lang/Helper.java +++ b/test/hotspot/jtreg/compiler/patches/java.base/java/lang/Helper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/hotspot/jtreg/compiler/unsafe/OpaqueAccesses.java b/test/hotspot/jtreg/compiler/unsafe/OpaqueAccesses.java index 7977125b9cf..9a31cbbb057 100644 --- a/test/hotspot/jtreg/compiler/unsafe/OpaqueAccesses.java +++ b/test/hotspot/jtreg/compiler/unsafe/OpaqueAccesses.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,15 +65,15 @@ public class OpaqueAccesses { // Finish the line after the node type, skips full line, and eats until before the node types private static final String SKIP = IRNode.MID + IRNode.END + "\\R" + FULL_LINES + "\\s*" + IRNode.START; - private static final String CALL_STATIC_JAVA_AND_THEN_OPAQUE_NOT_NULL = IRNode.START + "CallStaticJava" + SKIP + "OpaqueNotNull" + IRNode.MID + IRNode.END; - private static final String OPAQUE_NOT_NULL_AND_THEN_CALL_STATIC_JAVA = IRNode.START + "OpaqueNotNull" + SKIP + "CallStaticJava" + IRNode.MID + IRNode.END; - /* Having both CallStaticJava and OpaqueNotNull, in any order. We use that in a failOn to make sure we have one + private static final String CALL_STATIC_JAVA_AND_THEN_OPAQUE_CONSTANT_BOOL = IRNode.START + "CallStaticJava" + SKIP + "OpaqueConstantBool" + IRNode.MID + IRNode.END; + private static final String OPAQUE_CONSTANT_BOOL_AND_THEN_CALL_STATIC_JAVA = IRNode.START + "OpaqueConstantBool" + SKIP + "CallStaticJava" + IRNode.MID + IRNode.END; + /* Having both CallStaticJava and OpaqueConstantBool, in any order. We use that in a failOn to make sure we have one * or the other (or none), but not both. - * The CallStaticJava happens when the call is not intrinsified, and the OpaqueNotNull comes from the intrinsic. + * The CallStaticJava happens when the call is not intrinsified, and the OpaqueConstantBool comes from the intrinsic. * We don't want a unfinished intrinsic, with the call nevertheless. */ private static final String BOTH_CALL_STATIC_JAVA_AND_OPAQUE_NOT_NULL = - "(" + CALL_STATIC_JAVA_AND_THEN_OPAQUE_NOT_NULL + ") | (" + OPAQUE_NOT_NULL_AND_THEN_CALL_STATIC_JAVA + ")"; + "(" + CALL_STATIC_JAVA_AND_THEN_OPAQUE_CONSTANT_BOOL + ") | (" + OPAQUE_CONSTANT_BOOL_AND_THEN_CALL_STATIC_JAVA + ")"; @Test diff --git a/test/hotspot/jtreg/compiler/vectorapi/VectorBoxExpandPhi.java b/test/hotspot/jtreg/compiler/vectorapi/VectorBoxExpandPhi.java new file mode 100644 index 00000000000..936d24e4767 --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorapi/VectorBoxExpandPhi.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.vectorapi; + +import jdk.incubator.vector.*; + +/* + * @test + * @bug 8374903 + * @summary C2 crashes when VectorBox Phi and vector Phi have different regions + * @modules jdk.incubator.vector + * @library /test/lib + * + * @run main/othervm -Xbatch -XX:CompileCommand=compileonly,compiler.vectorapi.VectorBoxExpandPhi::test compiler.vectorapi.VectorBoxExpandPhi + */ +public class VectorBoxExpandPhi { + public static void main(String[] args) { + for (int i = 0; i < 10_000; i++) { + test(); + } + } + + public static Object test() { + var v0 = DoubleVector.broadcast(DoubleVector.SPECIES_128, 1.0); + var v1 = (FloatVector)v0.convertShape(VectorOperators.Conversion.ofCast(double.class, float.class), FloatVector.SPECIES_64, 0); + var v2 = (FloatVector)v1.convertShape(VectorOperators.Conversion.ofReinterpret(float.class, float.class), FloatVector.SPECIES_64, 0); + return v2; + } +} diff --git a/test/hotspot/jtreg/compiler/vectorapi/VectorBoxExpandProj.java b/test/hotspot/jtreg/compiler/vectorapi/VectorBoxExpandProj.java new file mode 100644 index 00000000000..5d152834b17 --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorapi/VectorBoxExpandProj.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.vectorapi; + +import jdk.incubator.vector.*; + +/* + * @test + * @bug 8375010 + * @summary C2 crashes when expanding VectorBox with Proj input from vector math call + * @modules jdk.incubator.vector + * @library /test/lib + * + * @run main/othervm -Xbatch -XX:CompileCommand=compileonly,compiler.vectorapi.VectorBoxExpandProj::test compiler.vectorapi.VectorBoxExpandProj + */ +public class VectorBoxExpandProj { + static boolean b; + + public static void main(String[] args) { + for (int i = 0; i < 20_000; i++) { + b = !b; + test(); + } + System.out.println("PASS"); + } + + // TAN returns Proj (not VectorNode). Phi merging creates VectorBox(Phi, Proj). + // expand_vbox_node_helper must handle Proj inputs with vector type. + static Object test() { + var t = DoubleVector.broadcast(DoubleVector.SPECIES_128, 1.0).lanewise(VectorOperators.TAN); + return b ? t.convertShape(VectorOperators.Conversion.ofCast(double.class, double.class), DoubleVector.SPECIES_128, 0) : t; + } +} diff --git a/test/hotspot/jtreg/compiler/vectorapi/VectorUMinMaxReductionTest.java b/test/hotspot/jtreg/compiler/vectorapi/VectorUMinMaxReductionTest.java new file mode 100644 index 00000000000..1c8cc34170e --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorapi/VectorUMinMaxReductionTest.java @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.vectorapi; + +import compiler.lib.generators.*; +import compiler.lib.ir_framework.*; + +import jdk.incubator.vector.*; +import jdk.test.lib.Asserts; + +import java.util.function.BinaryOperator; + +/** + * @test + * @bug 8372980 + * @key randomness + * @summary Add intrinsic support for unsigned min/max reduction operations + * @library /test/lib / + * @modules jdk.incubator.vector + * @run driver compiler.vectorapi.VectorUMinMaxReductionTest + */ + +public class VectorUMinMaxReductionTest { + private static final VectorSpecies B_SPECIES = ByteVector.SPECIES_MAX; + private static final VectorSpecies S_SPECIES = ShortVector.SPECIES_MAX; + private static final VectorSpecies I_SPECIES = IntVector.SPECIES_MAX; + private static final VectorSpecies F_SPECIES = FloatVector.SPECIES_MAX; + private static final VectorSpecies L_SPECIES = LongVector.SPECIES_MAX; + private static final VectorSpecies D_SPECIES = DoubleVector.SPECIES_MAX; + private static final int LENGTH = 256; + private static final Generators RD = Generators.G; + + // Identity values for unsigned min/max operations + private static final byte BYTE_UMIN_IDENTITY = (byte) -1; + private static final byte BYTE_UMAX_IDENTITY = (byte) 0; + private static final short SHORT_UMIN_IDENTITY = (short) -1; + private static final short SHORT_UMAX_IDENTITY = (short) 0; + private static final int INT_UMIN_IDENTITY = -1; + private static final int INT_UMAX_IDENTITY = 0; + private static final long LONG_UMIN_IDENTITY = -1L; + private static final long LONG_UMAX_IDENTITY = 0L; + + private static byte[] ba; + private static short[] sa; + private static int[] ia; + private static long[] la; + private static boolean[] ma; + + static { + ba = new byte[LENGTH]; + sa = new short[LENGTH]; + ia = new int[LENGTH]; + la = new long[LENGTH]; + ma = new boolean[LENGTH]; + + Generator iGen = RD.ints(); + Generator lGen = RD.longs(); + + for (int i = 0; i < LENGTH; i++) { + ba[i] = iGen.next().byteValue(); + sa[i] = iGen.next().shortValue(); + ma[i] = iGen.next() % 2 == 0; + } + RD.fill(iGen, ia); + RD.fill(lGen, la); + } + + // ==================== Helper Functions ==================== + + @DontInline + private static void verifyByte(VectorSpecies species, byte got, byte init, + BinaryOperator op, boolean isMasked) { + byte expected = init; + for (int i = 0; i < species.length(); i++) { + if (!isMasked || ma[i]) { + expected = op.apply(expected, ba[i]); + } + } + Asserts.assertEquals(expected, got); + } + + @DontInline + private static void verifyShort(VectorSpecies species, short got, short init, + BinaryOperator op, boolean isMasked) { + short expected = init; + for (int i = 0; i < species.length(); i++) { + if (!isMasked || ma[i]) { + expected = op.apply(expected, sa[i]); + } + } + Asserts.assertEquals(expected, got); + } + + @DontInline + private static void verifyInt(VectorSpecies species, int got, int init, + BinaryOperator op, boolean isMasked) { + int expected = init; + for (int i = 0; i < species.length(); i++) { + if (!isMasked || ma[i]) { + expected = op.apply(expected, ia[i]); + } + } + Asserts.assertEquals(expected, got); + } + + @DontInline + private static void verifyLong(VectorSpecies species, long got, long init, + BinaryOperator op, boolean isMasked) { + long expected = init; + for (int i = 0; i < species.length(); i++) { + if (!isMasked || ma[i]) { + expected = op.apply(expected, la[i]); + } + } + Asserts.assertEquals(expected, got); + } + + // ==================== Byte Tests ==================== + + @Test + @IR(counts = {IRNode.UMIN_REDUCTION_V, "= 1"}, + applyIfCPUFeature = {"asimd", "true"}) + public static void testByteUMin() { + byte got = ByteVector.fromArray(B_SPECIES, ba, 0).reduceLanes(VectorOperators.UMIN); + verifyByte(B_SPECIES, got, BYTE_UMIN_IDENTITY, VectorMath::minUnsigned, false); + } + + @Test + @IR(counts = {IRNode.UMAX_REDUCTION_V, "= 1"}, + applyIfCPUFeature = {"asimd", "true"}) + public static void testByteUMax() { + byte got = ByteVector.fromArray(B_SPECIES, ba, 0).reduceLanes(VectorOperators.UMAX); + verifyByte(B_SPECIES, got, BYTE_UMAX_IDENTITY, VectorMath::maxUnsigned, false); + } + + @Test + @IR(counts = {IRNode.UMIN_REDUCTION_V, "= 1"}, + applyIfCPUFeature = {"asimd", "true"}) + public static void testByteUMinMasked() { + byte got = ByteVector.fromArray(B_SPECIES, ba, 0) + .reduceLanes(VectorOperators.UMIN, + VectorMask.fromArray(B_SPECIES, ma, 0)); + verifyByte(B_SPECIES, got, BYTE_UMIN_IDENTITY, VectorMath::minUnsigned, true); + } + + @Test + @IR(counts = {IRNode.UMAX_REDUCTION_V, "= 1"}, + applyIfCPUFeature = {"asimd", "true"}) + public static void testByteUMaxMasked() { + byte got = ByteVector.fromArray(B_SPECIES, ba, 0) + .reduceLanes(VectorOperators.UMAX, + VectorMask.fromArray(B_SPECIES, ma, 0)); + verifyByte(B_SPECIES, got, BYTE_UMAX_IDENTITY, VectorMath::maxUnsigned, true); + } + + // ==================== Short Tests ==================== + + @Test + @IR(counts = {IRNode.UMIN_REDUCTION_V, "= 1"}, + applyIfCPUFeature = {"asimd", "true"}) + public static void testShortUMin() { + short got = ShortVector.fromArray(S_SPECIES, sa, 0).reduceLanes(VectorOperators.UMIN); + verifyShort(S_SPECIES, got, SHORT_UMIN_IDENTITY, VectorMath::minUnsigned, false); + } + + @Test + @IR(counts = {IRNode.UMAX_REDUCTION_V, "= 1"}, + applyIfCPUFeature = {"asimd", "true"}) + public static void testShortUMax() { + short got = ShortVector.fromArray(S_SPECIES, sa, 0).reduceLanes(VectorOperators.UMAX); + verifyShort(S_SPECIES, got, SHORT_UMAX_IDENTITY, VectorMath::maxUnsigned, false); + } + + @Test + @IR(counts = {IRNode.UMIN_REDUCTION_V, "= 1"}, + applyIfCPUFeature = {"asimd", "true"}) + public static void testShortUMinMasked() { + short got = ShortVector.fromArray(S_SPECIES, sa, 0) + .reduceLanes(VectorOperators.UMIN, + VectorMask.fromArray(S_SPECIES, ma, 0)); + verifyShort(S_SPECIES, got, SHORT_UMIN_IDENTITY, VectorMath::minUnsigned, true); + } + + @Test + @IR(counts = {IRNode.UMAX_REDUCTION_V, "= 1"}, + applyIfCPUFeature = {"asimd", "true"}) + public static void testShortUMaxMasked() { + short got = ShortVector.fromArray(S_SPECIES, sa, 0) + .reduceLanes(VectorOperators.UMAX, + VectorMask.fromArray(S_SPECIES, ma, 0)); + verifyShort(S_SPECIES, got, SHORT_UMAX_IDENTITY, VectorMath::maxUnsigned, true); + } + + // ==================== Int Tests ==================== + + @Test + @IR(counts = {IRNode.UMIN_REDUCTION_V, "= 1"}, + applyIfCPUFeature = {"asimd", "true"}) + public static void testIntUMin() { + int got = IntVector.fromArray(I_SPECIES, ia, 0).reduceLanes(VectorOperators.UMIN); + verifyInt(I_SPECIES, got, INT_UMIN_IDENTITY, VectorMath::minUnsigned, false); + } + + @Test + @IR(counts = {IRNode.UMAX_REDUCTION_V, "= 1"}, + applyIfCPUFeature = {"asimd", "true"}) + public static void testIntUMax() { + int got = IntVector.fromArray(I_SPECIES, ia, 0).reduceLanes(VectorOperators.UMAX); + verifyInt(I_SPECIES, got, INT_UMAX_IDENTITY, VectorMath::maxUnsigned, false); + } + + @Test + @IR(counts = {IRNode.UMIN_REDUCTION_V, "= 1"}, + applyIfCPUFeature = {"asimd", "true"}) + public static void testIntUMinMasked() { + int got = IntVector.fromArray(I_SPECIES, ia, 0) + .reduceLanes(VectorOperators.UMIN, + VectorMask.fromArray(I_SPECIES, ma, 0)); + verifyInt(I_SPECIES, got, INT_UMIN_IDENTITY, VectorMath::minUnsigned, true); + } + + @Test + @IR(counts = {IRNode.UMAX_REDUCTION_V, "= 1"}, + applyIfCPUFeature = {"asimd", "true"}) + public static void testIntUMaxMasked() { + int got = IntVector.fromArray(I_SPECIES, ia, 0) + .reduceLanes(VectorOperators.UMAX, + VectorMask.fromArray(I_SPECIES, ma, 0)); + verifyInt(I_SPECIES, got, INT_UMAX_IDENTITY, VectorMath::maxUnsigned, true); + } + + // ==================== Long Tests ==================== + + @Test + @IR(counts = {IRNode.UMIN_REDUCTION_V, "= 1"}, + applyIfCPUFeature = {"asimd", "true"}) + public static void testLongUMin() { + long got = LongVector.fromArray(L_SPECIES, la, 0).reduceLanes(VectorOperators.UMIN); + verifyLong(L_SPECIES, got, LONG_UMIN_IDENTITY, VectorMath::minUnsigned, false); + } + + @Test + @IR(counts = {IRNode.UMAX_REDUCTION_V, "= 1"}, + applyIfCPUFeature = {"asimd", "true"}) + public static void testLongUMax() { + long got = LongVector.fromArray(L_SPECIES, la, 0).reduceLanes(VectorOperators.UMAX); + verifyLong(L_SPECIES, got, LONG_UMAX_IDENTITY, VectorMath::maxUnsigned, false); + } + + @Test + @IR(counts = {IRNode.UMIN_REDUCTION_V, "= 1"}, + applyIfCPUFeature = {"asimd", "true"}) + public static void testLongUMinMasked() { + long got = LongVector.fromArray(L_SPECIES, la, 0) + .reduceLanes(VectorOperators.UMIN, + VectorMask.fromArray(L_SPECIES, ma, 0)); + verifyLong(L_SPECIES, got, LONG_UMIN_IDENTITY, VectorMath::minUnsigned, true); + } + + @Test + @IR(counts = {IRNode.UMAX_REDUCTION_V, "= 1"}, + applyIfCPUFeature = {"asimd", "true"}) + public static void testLongUMaxMasked() { + long got = LongVector.fromArray(L_SPECIES, la, 0) + .reduceLanes(VectorOperators.UMAX, + VectorMask.fromArray(L_SPECIES, ma, 0)); + verifyLong(L_SPECIES, got, LONG_UMAX_IDENTITY, VectorMath::maxUnsigned, true); + } + + public static void main(String[] args) { + TestFramework testFramework = new TestFramework(); + testFramework.setDefaultWarmup(10000) + .addFlags("--add-modules=jdk.incubator.vector") + .start(); + } +} diff --git a/test/hotspot/jtreg/compiler/vectorization/TestVectorAlgorithms.java b/test/hotspot/jtreg/compiler/vectorization/TestVectorAlgorithms.java new file mode 100644 index 00000000000..e02563c2fc2 --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorization/TestVectorAlgorithms.java @@ -0,0 +1,556 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test id=vanilla + * @bug 8373026 + * @summary Test auto vectorization and Vector API with some vector + * algorithms. Related benchmark: VectorAlgorithms.java + * @library /test/lib / + * @modules jdk.incubator.vector + * @run driver ${test.main.class} + */ + +/* + * @test id=noSuperWord + * @bug 8373026 + * @library /test/lib / + * @modules jdk.incubator.vector + * @run driver ${test.main.class} -XX:-UseSuperWord + */ + +/* + * @test id=noOptimizeFill + * @bug 8373026 + * @library /test/lib / + * @modules jdk.incubator.vector + * @run driver ${test.main.class} -XX:-OptimizeFill + */ + +package compiler.vectorization; + +import java.util.Map; +import java.util.HashMap; +import jdk.test.lib.Utils; +import java.util.Random; +import java.lang.foreign.*; + +import compiler.lib.ir_framework.*; +import compiler.lib.generators.*; +import static compiler.lib.generators.Generators.G; +import compiler.lib.verify.*; + +/** + * The goal of this benchmark is to show the power of auto vectorization + * and the Vector API. + * + * Please only modify this benchark in synchronization with the JMH benchmark: + * micro/org/openjdk/bench/vm/compiler/VectorAlgorithms.java + */ +public class TestVectorAlgorithms { + private static final Random RANDOM = Utils.getRandomInstance(); + private static final RestrictableGenerator INT_GEN = Generators.G.ints(); + + interface TestFunction { + Object run(int i); + } + + Map> testGroups = new HashMap>(); + + VectorAlgorithmsImpl.Data d; + + public static void main(String[] args) { + TestFramework framework = new TestFramework(); + framework.addFlags("--add-modules=jdk.incubator.vector", + "-XX:CompileCommand=inline,*VectorAlgorithmsImpl*::*"); + framework.addFlags(args); + framework.start(); + } + + public TestVectorAlgorithms () { + testGroups.put("fillI", new HashMap()); + testGroups.get("fillI").put("fillI_loop", i -> { return fillI_loop(d.rI1); }); + testGroups.get("fillI").put("fillI_VectorAPI", i -> { return fillI_VectorAPI(d.rI2); }); + testGroups.get("fillI").put("fillI_Arrays", i -> { return fillI_Arrays(d.rI3); }); + + testGroups.put("iotaI", new HashMap()); + testGroups.get("iotaI").put("iotaI_loop", i -> { return iotaI_loop(d.rI1); }); + testGroups.get("iotaI").put("iotaI_VectorAPI", i -> { return iotaI_VectorAPI(d.rI2); }); + + testGroups.put("copyI", new HashMap()); + testGroups.get("copyI").put("copyI_loop", i -> { return copyI_loop(d.aI, d.rI1); }); + testGroups.get("copyI").put("copyI_VectorAPI", i -> { return copyI_VectorAPI(d.aI, d.rI2); }); + testGroups.get("copyI").put("copyI_System_arraycopy", i -> { return copyI_System_arraycopy(d.aI, d.rI3); }); + + testGroups.put("mapI", new HashMap()); + testGroups.get("mapI").put("mapI_loop", i -> { return mapI_loop(d.aI, d.rI1); }); + testGroups.get("mapI").put("mapI_VectorAPI", i -> { return mapI_VectorAPI(d.aI, d.rI2); }); + + testGroups.put("reduceAddI", new HashMap()); + testGroups.get("reduceAddI").put("reduceAddI_loop", i -> { return reduceAddI_loop(d.aI); }); + testGroups.get("reduceAddI").put("reduceAddI_reassociate", i -> { return reduceAddI_reassociate(d.aI); }); + testGroups.get("reduceAddI").put("reduceAddI_VectorAPI_naive", i -> { return reduceAddI_VectorAPI_naive(d.aI); }); + testGroups.get("reduceAddI").put("reduceAddI_VectorAPI_reduction_after_loop", i -> { return reduceAddI_VectorAPI_reduction_after_loop(d.aI); }); + + testGroups.put("dotProductF", new HashMap()); + testGroups.get("dotProductF").put("dotProductF_loop", i -> { return dotProductF_loop(d.aF, d.bF); }); + testGroups.get("dotProductF").put("dotProductF_VectorAPI_naive", i -> { return dotProductF_VectorAPI_naive(d.aF, d.bF); }); + testGroups.get("dotProductF").put("dotProductF_VectorAPI_reduction_after_loop", i -> { return dotProductF_VectorAPI_reduction_after_loop(d.aF, d.bF); }); + + testGroups.put("hashCodeB", new HashMap()); + testGroups.get("hashCodeB").put("hashCodeB_loop", i -> { return hashCodeB_loop(d.aB); }); + testGroups.get("hashCodeB").put("hashCodeB_Arrays", i -> { return hashCodeB_Arrays(d.aB); }); + testGroups.get("hashCodeB").put("hashCodeB_VectorAPI_v1", i -> { return hashCodeB_VectorAPI_v1(d.aB); }); + testGroups.get("hashCodeB").put("hashCodeB_VectorAPI_v2", i -> { return hashCodeB_VectorAPI_v2(d.aB); }); + + testGroups.put("scanAddI", new HashMap()); + testGroups.get("scanAddI").put("scanAddI_loop", i -> { return scanAddI_loop(d.aI, d.rI1); }); + testGroups.get("scanAddI").put("scanAddI_loop_reassociate", i -> { return scanAddI_loop_reassociate(d.aI, d.rI2); }); + testGroups.get("scanAddI").put("scanAddI_VectorAPI_permute_add", i -> { return scanAddI_VectorAPI_permute_add(d.aI, d.rI4); }); + + testGroups.put("findMinIndexI", new HashMap()); + testGroups.get("findMinIndexI").put("findMinIndexI_loop", i -> { return findMinIndexI_loop(d.aI); }); + testGroups.get("findMinIndexI").put("findMinIndexI_VectorAPI", i -> { return findMinIndexI_VectorAPI(d.aI); }); + + testGroups.put("findI", new HashMap()); + testGroups.get("findI").put("findI_loop", i -> { return findI_loop(d.aI, d.eI[i]); }); + testGroups.get("findI").put("findI_VectorAPI", i -> { return findI_VectorAPI(d.aI, d.eI[i]); }); + + testGroups.put("reverseI", new HashMap()); + testGroups.get("reverseI").put("reverseI_loop", i -> { return reverseI_loop(d.aI, d.rI1); }); + testGroups.get("reverseI").put("reverseI_VectorAPI", i -> { return reverseI_VectorAPI(d.aI, d.rI2); }); + + testGroups.put("filterI", new HashMap()); + testGroups.get("filterI").put("filterI_loop", i -> { return filterI_loop(d.aI, d.rI1, d.eI[i]); }); + testGroups.get("filterI").put("filterI_VectorAPI", i -> { return filterI_VectorAPI(d.aI, d.rI2, d.eI[i]); }); + + testGroups.put("reduceAddIFieldsX4", new HashMap()); + testGroups.get("reduceAddIFieldsX4").put("reduceAddIFieldsX4_loop", i -> { return reduceAddIFieldsX4_loop(d.oopsX4, d.memX4); }); + testGroups.get("reduceAddIFieldsX4").put("reduceAddIFieldsX4_VectorAPI", i -> { return reduceAddIFieldsX4_VectorAPI(d.oopsX4, d.memX4); }); + + testGroups.put("lowerCaseB", new HashMap()); + testGroups.get("lowerCaseB").put("lowerCaseB_loop", i -> { return lowerCaseB_loop(d.strB, d.rB1); }); + testGroups.get("lowerCaseB").put("lowerCaseB_VectorAPI_v1", i -> { return lowerCaseB_VectorAPI_v1(d.strB, d.rB2); }); + testGroups.get("lowerCaseB").put("lowerCaseB_VectorAPI_v2", i -> { return lowerCaseB_VectorAPI_v2(d.strB, d.rB3); }); + } + + @Warmup(100) + @Run(test = {"fillI_loop", + "fillI_VectorAPI", + "fillI_Arrays", + "iotaI_loop", + "iotaI_VectorAPI", + "copyI_loop", + "copyI_VectorAPI", + "copyI_System_arraycopy", + "mapI_loop", + "mapI_VectorAPI", + "reduceAddI_loop", + "reduceAddI_reassociate", + "reduceAddI_VectorAPI_naive", + "reduceAddI_VectorAPI_reduction_after_loop", + "dotProductF_loop", + "dotProductF_VectorAPI_naive", + "dotProductF_VectorAPI_reduction_after_loop", + "hashCodeB_loop", + "hashCodeB_Arrays", + "hashCodeB_VectorAPI_v1", + "hashCodeB_VectorAPI_v2", + "scanAddI_loop", + "scanAddI_loop_reassociate", + "scanAddI_VectorAPI_permute_add", + "findMinIndexI_loop", + "findMinIndexI_VectorAPI", + "findI_loop", + "findI_VectorAPI", + "reverseI_loop", + "reverseI_VectorAPI", + "filterI_loop", + "filterI_VectorAPI", + "reduceAddIFieldsX4_loop", + "reduceAddIFieldsX4_VectorAPI", + "lowerCaseB_loop", + "lowerCaseB_VectorAPI_v1", + "lowerCaseB_VectorAPI_v2"}) + public void runTests(RunInfo info) { + // Repeat many times, so that we also have multiple iterations for post-warmup to potentially recompile + int iters = info.isWarmUp() ? 1 : 20; + for (int iter = 0; iter < iters; iter++) { + // Set up random inputs, random size is important to stress tails. + int size = 100_000 + RANDOM.nextInt(10_000); + int seed = RANDOM.nextInt(); + int numXObjects = 10_000; + d = new VectorAlgorithmsImpl.Data(size, seed, numXObjects); + + // Run all tests + for (Map.Entry> group_entry : testGroups.entrySet()) { + String group_name = group_entry.getKey(); + Map group = group_entry.getValue(); + Object gold = null; + String gold_name = "NONE"; + for (Map.Entry entry : group.entrySet()) { + String name = entry.getKey(); + TestFunction test = entry.getValue(); + Object result = test.run(iter); + if (gold == null) { + gold = result; + gold_name = name; + } else { + try { + Verify.checkEQ(gold, result); + } catch (VerifyException e) { + throw new RuntimeException("Verify.checkEQ failed for group " + group_name + + ", gold " + gold_name + ", test " + name, e); + } + } + } + } + } + } + + @Test + @IR(counts = {IRNode.REPLICATE_I, "= 1", + IRNode.STORE_VECTOR, "> 0"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}, + applyIfAnd = {"UseSuperWord", "true", "OptimizeFill", "false"}) + @IR(counts = {".*CallLeafNoFP.*jint_fill.*", "= 1"}, + phase = CompilePhase.BEFORE_MATCHING, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}, + applyIf = {"OptimizeFill", "true"}) + // By default, the fill intrinsic "jint_fill" is used, but we can disable + // the detection of the fill loop, and then we auto vectorize. + public Object fillI_loop(int[] r) { + return VectorAlgorithmsImpl.fillI_loop(r); + } + + @Test + @IR(counts = {IRNode.REPLICATE_I, "= 1", + IRNode.STORE_VECTOR, "> 0"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) + public Object fillI_VectorAPI(int[] r) { + return VectorAlgorithmsImpl.fillI_VectorAPI(r); + } + + @Test + // Arrays.fill is not necessarily inlined, so we can't check + // for vectors in the IR. + public Object fillI_Arrays(int[] r) { + return VectorAlgorithmsImpl.fillI_Arrays(r); + } + + @Test + @IR(counts = {IRNode.POPULATE_INDEX, "> 0", + IRNode.STORE_VECTOR, "> 0"}, + applyIfCPUFeatureOr = {"avx2", "true", "sve", "true"}, + applyIf = {"UseSuperWord", "true"}) + // Note: the Vector API example below can also vectorize for AVX, + // because it does not use a PopulateIndex. + public Object iotaI_loop(int[] r) { + return VectorAlgorithmsImpl.iotaI_loop(r); + } + + @Test + @IR(counts = {IRNode.ADD_VI, "> 0", + IRNode.STORE_VECTOR, "> 0"}, + applyIfCPUFeature = {"sse4.1", "true"}) + // Note: also works with NEON/asimd, but only with TieredCompilation. + public Object iotaI_VectorAPI(int[] r) { + return VectorAlgorithmsImpl.iotaI_VectorAPI(r); + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", + IRNode.STORE_VECTOR, "> 0"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}, + applyIf = {"UseSuperWord", "true"}) + public Object copyI_loop(int[] a, int[] r) { + return VectorAlgorithmsImpl.copyI_loop(a, r); + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", + IRNode.STORE_VECTOR, "> 0"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) + public Object copyI_VectorAPI(int[] a, int[] r) { + return VectorAlgorithmsImpl.copyI_VectorAPI(a, r); + } + + @Test + @IR(counts = {".*CallLeafNoFP.*jint_disjoint_arraycopy.*", "= 1"}, + phase = CompilePhase.BEFORE_MATCHING, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) + public Object copyI_System_arraycopy(int[] a, int[] r) { + return VectorAlgorithmsImpl.copyI_System_arraycopy(a, r); + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", + IRNode.MUL_VI, "> 0", + IRNode.STORE_VECTOR, "> 0"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}, + applyIf = {"UseSuperWord", "true"}) + public Object mapI_loop(int[] a, int[] r) { + return VectorAlgorithmsImpl.mapI_loop(a, r); + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", + IRNode.MUL_VI, "> 0", + IRNode.STORE_VECTOR, "> 0"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) + public Object mapI_VectorAPI(int[] a, int[] r) { + return VectorAlgorithmsImpl.mapI_VectorAPI(a, r); + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", + IRNode.ADD_REDUCTION_VI, "> 0", + IRNode.ADD_VI, "> 0"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}, + applyIf = {"UseSuperWord", "true"}) + public int reduceAddI_loop(int[] a) { + return VectorAlgorithmsImpl.reduceAddI_loop(a); + } + + @Test + public int reduceAddI_reassociate(int[] a) { + return VectorAlgorithmsImpl.reduceAddI_reassociate(a); + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", + IRNode.ADD_REDUCTION_VI, "> 0"}, // reduceLanes inside loop + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) + public int reduceAddI_VectorAPI_naive(int[] a) { + return VectorAlgorithmsImpl.reduceAddI_VectorAPI_naive(a); + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", + IRNode.ADD_REDUCTION_V, "> 0", + IRNode.MUL_VF, "> 0"}, + applyIfCPUFeature = {"sse4.1", "true"}, + applyIf = {"UseSuperWord", "true"}) + // See also TestReduction.floatAddDotProduct + public float dotProductF_loop(float[] a, float[] b) { + return VectorAlgorithmsImpl.dotProductF_loop(a, b); + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", + IRNode.ADD_REDUCTION_V, "> 0", + IRNode.MUL_VF, "> 0"}, + applyIfCPUFeature = {"sse4.1", "true"}, + applyIf = {"UseSuperWord", "true"}) + public float dotProductF_VectorAPI_naive(float[] a, float[] b) { + return VectorAlgorithmsImpl.dotProductF_VectorAPI_naive(a, b); + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", + IRNode.ADD_REDUCTION_V, "> 0", + IRNode.MUL_VF, "> 0"}, + applyIfCPUFeature = {"sse4.1", "true"}, + applyIf = {"UseSuperWord", "true"}) + public float dotProductF_VectorAPI_reduction_after_loop(float[] a, float[] b) { + return VectorAlgorithmsImpl.dotProductF_VectorAPI_reduction_after_loop(a, b); + } + + @Test + public int hashCodeB_loop(byte[] a) { + return VectorAlgorithmsImpl.hashCodeB_loop(a); + } + + @Test + public int hashCodeB_Arrays(byte[] a) { + return VectorAlgorithmsImpl.hashCodeB_Arrays(a); + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE_8, "> 0", + IRNode.VECTOR_CAST_B2I, IRNode.VECTOR_SIZE_8, "> 0", + IRNode.MUL_VI, IRNode.VECTOR_SIZE_8, "> 0", + IRNode.ADD_VI, IRNode.VECTOR_SIZE_8, "> 0", + IRNode.ADD_REDUCTION_VI, "> 0"}, + applyIfCPUFeature = {"avx2", "true"}) + public int hashCodeB_VectorAPI_v1(byte[] a) { + return VectorAlgorithmsImpl.hashCodeB_VectorAPI_v1(a); + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", + IRNode.MUL_VI, "> 0", + IRNode.ADD_VI, "> 0", + IRNode.ADD_REDUCTION_VI, "> 0"}, + applyIfCPUFeature = {"avx2", "true"}) + public int hashCodeB_VectorAPI_v2(byte[] a) { + return VectorAlgorithmsImpl.hashCodeB_VectorAPI_v2(a); + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", + IRNode.ADD_REDUCTION_VI, "> 0", + IRNode.ADD_VI, "> 0"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) + public int reduceAddI_VectorAPI_reduction_after_loop(int[] a) { + return VectorAlgorithmsImpl.reduceAddI_VectorAPI_reduction_after_loop(a); + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_I, "= 0", + IRNode.STORE_VECTOR, "= 0"}) + // Currently does not vectorize, but might in the future. + public Object scanAddI_loop(int[] a, int[] r) { + return VectorAlgorithmsImpl.scanAddI_loop(a, r); + } + + @Test + public Object scanAddI_loop_reassociate(int[] a, int[] r) { + return VectorAlgorithmsImpl.scanAddI_loop_reassociate(a, r); + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", + IRNode.REARRANGE_VI, "> 0", + IRNode.AND_VI, "> 0", + IRNode.ADD_VI, "> 0", + IRNode.STORE_VECTOR, "> 0"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}, + applyIf = {"MaxVectorSize", ">=64"}) + public Object scanAddI_VectorAPI_permute_add(int[] a, int[] r) { + return VectorAlgorithmsImpl.scanAddI_VectorAPI_permute_add(a, r); + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_I, "= 0"}) + // Currently does not vectorize, but might in the future. + public int findMinIndexI_loop(int[] a) { + return VectorAlgorithmsImpl.findMinIndexI_loop(a); + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", + IRNode.VECTOR_MASK_CMP, "> 0", + IRNode.VECTOR_BLEND_I, "> 0", + IRNode.MIN_REDUCTION_V, "> 0", + IRNode.ADD_VI, "> 0"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + public int findMinIndexI_VectorAPI(int[] a) { + return VectorAlgorithmsImpl.findMinIndexI_VectorAPI(a); + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_I, "= 0"}) + // Currently does not vectorize, but might in the future. + public int findI_loop(int[] a, int e) { + return VectorAlgorithmsImpl.findI_loop(a, e); + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", + IRNode.VECTOR_MASK_CMP, "> 0", + IRNode.VECTOR_TEST, "> 0"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + public int findI_VectorAPI(int[] a, int e) { + return VectorAlgorithmsImpl.findI_VectorAPI(a, e); + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_I, "= 0", + IRNode.STORE_VECTOR, "= 0"}) + // Currently does not vectorize, but might in the future. + public Object reverseI_loop(int[] a, int[] r) { + return VectorAlgorithmsImpl.reverseI_loop(a, r); + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", + IRNode.REARRANGE_VI, "> 0", + IRNode.AND_VI, "> 0", + IRNode.STORE_VECTOR, "> 0"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) + public Object reverseI_VectorAPI(int[] a, int[] r) { + return VectorAlgorithmsImpl.reverseI_VectorAPI(a, r); + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_I, "= 0", + IRNode.STORE_VECTOR, "= 0"}) + public Object filterI_loop(int[] a, int[] r, int threshold) { + return VectorAlgorithmsImpl.filterI_loop(a, r, threshold); + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", + IRNode.VECTOR_MASK_CMP, "> 0", + IRNode.VECTOR_TEST, "> 0", + IRNode.COMPRESS_VI, "> 0", + IRNode.STORE_VECTOR_MASKED, "> 0"}, + applyIfCPUFeature = {"avx2", "true"}) + public Object filterI_VectorAPI(int[] a, int[] r, int threshold) { + return VectorAlgorithmsImpl.filterI_VectorAPI(a, r, threshold); + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_I, "= 0"}) + // Currently does not vectorize, but might in the future. + public int reduceAddIFieldsX4_loop(int[] oops, int[] mem) { + return VectorAlgorithmsImpl.reduceAddIFieldsX4_loop(oops, mem); + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", + IRNode.VECTOR_MASK_CMP, "> 0", + IRNode.VECTOR_TEST, "> 0", + IRNode.LOAD_VECTOR_GATHER_MASKED, "> 0", + IRNode.OR_V_MASK, "> 0", + IRNode.ADD_VI, "> 0", + IRNode.ADD_REDUCTION_VI, "> 0"}, + applyIfCPUFeatureOr = {"avx512", "true", "sve", "true"}) + public int reduceAddIFieldsX4_VectorAPI(int[] oops, int[] mem) { + return VectorAlgorithmsImpl.reduceAddIFieldsX4_VectorAPI(oops, mem); + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_B, "= 0"}) + // Currently does not vectorize, but might in the future. + public Object lowerCaseB_loop(byte[] a, byte[] r) { + return VectorAlgorithmsImpl.lowerCaseB_loop(a, r); + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", + IRNode.ADD_VB, "> 0"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) + public Object lowerCaseB_VectorAPI_v1(byte[] a, byte[] r) { + return VectorAlgorithmsImpl.lowerCaseB_VectorAPI_v1(a, r); + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", + IRNode.ADD_VB, "> 0"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) + public Object lowerCaseB_VectorAPI_v2(byte[] a, byte[] r) { + return VectorAlgorithmsImpl.lowerCaseB_VectorAPI_v2(a, r); + } +} diff --git a/test/hotspot/jtreg/compiler/vectorization/VectorAlgorithmsImpl.java b/test/hotspot/jtreg/compiler/vectorization/VectorAlgorithmsImpl.java new file mode 100644 index 00000000000..2dfac704069 --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorization/VectorAlgorithmsImpl.java @@ -0,0 +1,774 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package compiler.vectorization; + +import java.util.Arrays; +import java.util.Random; +import jdk.incubator.vector.*; + +/** + * The code below is supposed to be an exact copy of: + * micro/org/openjdk/bench/vm/compiler/VectorAlgorithmsImpl.java + */ +public class VectorAlgorithmsImpl { + private static final VectorSpecies SPECIES_I = IntVector.SPECIES_PREFERRED; + private static final VectorSpecies SPECIES_I512 = IntVector.SPECIES_512; + private static final VectorSpecies SPECIES_I256 = IntVector.SPECIES_256; + private static final VectorSpecies SPECIES_B = ByteVector.SPECIES_PREFERRED; + private static final VectorSpecies SPECIES_B64 = ByteVector.SPECIES_64; + private static final VectorSpecies SPECIES_F = FloatVector.SPECIES_PREFERRED; + + // This class stores the input and output arrays. + // The constructor sets up all the data. + // + // IMPORTANT: + // If you want to use some array but do NOT modify it: just use it. + // If you want to use it and DO want to modify it: clone it. This + // ensures that each test gets a separate copy, and that when we + // capture the modified arrays they are different for every method + // and run. + // An alternative to cloning is to use different return arrays for + // different implementations of the same group, e.g. rI1, rI2, ... + // + public static class Data { + public int[] aI; + public int[] rI1; + public int[] rI2; + public int[] rI3; + public int[] rI4; + public int[] eI; + // The test has to use the same index into eI for all implementations. But in the + // benchmark, we'd like to use random indices, so we use the index to advance through + // the array. + public int eI_idx = 0; + + public float[] aF; + public float[] bF; + + public byte[] aB; + public byte[] strB; + public byte[] rB1; + public byte[] rB2; + public byte[] rB3; + + public int[] oopsX4; + public int[] memX4; + + public Data(int size, int seed, int numX4Objects) { + Random random = new Random(seed); + + // int: one input array and multiple output arrays so different implementations can + // store their results to different arrays. + aI = new int[size]; + rI1 = new int[size]; + rI2 = new int[size]; + rI3 = new int[size]; + rI4 = new int[size]; + Arrays.setAll(aI, i -> random.nextInt()); + + // Populate with some random values from aI, and some totally random values. + eI = new int[0x10000]; + for (int i = 0; i < eI.length; i++) { + eI[i] = (random.nextInt(10) == 0) ? random.nextInt() : aI[random.nextInt(size)]; + } + + // X4 oop setup. + // oopsX4 holds "addresses" (i.e. indices), that point to the 16-byte objects in memX4. + oopsX4 = new int[size]; + memX4 = new int[numX4Objects * 4]; + for (int i = 0; i < size; i++) { + // assign either a zero=null, or assign a random oop. + oopsX4[i] = (random.nextInt(10) == 0) ? 0 : random.nextInt(numX4Objects) * 4; + } + // Just fill the whole array with random values. + // The relevant field is only at every "4 * i + 3" though. + memX4 = new int[4 * numX4Objects]; + for (int i = 0; i < memX4.length; i++) { + memX4[i] = random.nextInt(); + } + + // float inputs. To avoid rounding issues, only use small integers. + aF = new float[size]; + bF = new float[size]; + for (int i = 0; i < size; i++) { + aF[i] = random.nextInt(32) - 16; + bF[i] = random.nextInt(32) - 16; + } + + // byte: just random data. + aB = new byte[size]; + strB = new byte[size]; + rB1 = new byte[size]; + rB2 = new byte[size]; + rB3 = new byte[size]; + random.nextBytes(aB); + random.nextBytes(strB); // TODO: special data! + } + } + + public static Object fillI_loop(int[] r) { + for (int i = 0; i < r.length; i++) { + r[i] = 42; + } + return r; + } + + public static Object fillI_Arrays(int[] r) { + Arrays.fill(r, 42); + return r; + } + + public static Object fillI_VectorAPI(int[] r) { + var v = IntVector.broadcast(SPECIES_I, 42); + int i = 0; + for (; i < SPECIES_I.loopBound(r.length); i += SPECIES_I.length()) { + v.intoArray(r, i); + } + for (; i < r.length; i++) { + r[i] = 42; + } + return r; + } + + public static Object iotaI_loop(int[] r) { + for (int i = 0; i < r.length; i++) { + r[i] = i; + } + return r; + } + + public static Object iotaI_VectorAPI(int[] r) { + var iota = IntVector.broadcast(SPECIES_I, 0).addIndex(1); + int i = 0; + for (; i < SPECIES_I.loopBound(r.length); i += SPECIES_I.length()) { + iota.intoArray(r, i); + iota = iota.add(SPECIES_I.length()); + } + for (; i < r.length; i++) { + r[i] = i; + } + return r; + } + + public static Object copyI_loop(int[] a, int[] r) { + for (int i = 0; i < a.length; i++) { + r[i] = a[i]; + } + return r; + } + + public static Object copyI_System_arraycopy(int[] a, int[] r) { + System.arraycopy(a, 0, r, 0, a.length); + return r; + } + + public static Object copyI_VectorAPI(int[] a, int[] r) { + int i = 0; + for (; i < SPECIES_I.loopBound(r.length); i += SPECIES_I.length()) { + IntVector v = IntVector.fromArray(SPECIES_I, a, i); + v.intoArray(r, i); + } + for (; i < r.length; i++) { + r[i] = a[i]; + } + return r; + } + + public static Object mapI_loop(int[] a, int[] r) { + for (int i = 0; i < a.length; i++) { + r[i] = a[i] * 42; + } + return r; + } + + public static Object mapI_VectorAPI(int[] a, int[] r) { + int i = 0; + for (; i < SPECIES_I.loopBound(r.length); i += SPECIES_I.length()) { + IntVector v = IntVector.fromArray(SPECIES_I, a, i); + v = v.mul(42); + v.intoArray(r, i); + } + for (; i < r.length; i++) { + r[i] = a[i] * 42; + } + return r; + } + + public static int reduceAddI_loop(int[] a) { + int sum = 0; + for (int i = 0; i < a.length; i++) { + // Relying on simple reduction loop should vectorize since JDK26. + sum += a[i]; + } + return sum; + } + + public static int reduceAddI_reassociate(int[] a) { + int sum = 0; + int i; + for (i = 0; i < a.length - 3; i += 4) { + // Unroll 4x, reassociate inside. + sum += a[i] + a[i + 1] + a[i + 2] + a[i + 3]; + } + for (; i < a.length; i++) { + // Tail + sum += a[i]; + } + return sum; + } + + public static int reduceAddI_VectorAPI_naive(int[] a) { + var sum = 0; + int i; + for (i = 0; i < SPECIES_I.loopBound(a.length); i += SPECIES_I.length()) { + IntVector v = IntVector.fromArray(SPECIES_I, a, i); + // reduceLanes in loop is better than scalar performance, but still + // relatively slow. + sum += v.reduceLanes(VectorOperators.ADD); + } + for (; i < a.length; i++) { + sum += a[i]; + } + return sum; + } + + public static int reduceAddI_VectorAPI_reduction_after_loop(int[] a) { + var acc = IntVector.broadcast(SPECIES_I, 0); + int i; + for (i = 0; i < SPECIES_I.loopBound(a.length); i += SPECIES_I.length()) { + IntVector v = IntVector.fromArray(SPECIES_I, a, i); + // Element-wide addition into a vector of partial sums is much faster. + // Now, we only need to do a reduceLanes after the loop. + // This works because int-addition is associative and commutative. + acc = acc.add(v); + } + int sum = acc.reduceLanes(VectorOperators.ADD); + for (; i < a.length; i++) { + sum += a[i]; + } + return sum; + } + + public static float dotProductF_loop(float[] a, float[] b) { + float sum = 0; + for (int i = 0; i < a.length; i++) { + sum += a[i] * b[i]; + } + return sum; + } + + public static float dotProductF_VectorAPI_naive(float[] a, float[] b) { + float sum = 0; + int i; + for (i = 0; i < SPECIES_F.loopBound(a.length); i += SPECIES_F.length()) { + var va = FloatVector.fromArray(SPECIES_F, a, i); + var vb = FloatVector.fromArray(SPECIES_F, b, i); + sum += va.mul(vb).reduceLanes(VectorOperators.ADD); + } + for (; i < a.length; i++) { + sum += a[i] * b[i]; + } + return sum; + } + + public static float dotProductF_VectorAPI_reduction_after_loop(float[] a, float[] b) { + var sums = FloatVector.broadcast(SPECIES_F, 0.0f); + int i; + for (i = 0; i < SPECIES_F.loopBound(a.length); i += SPECIES_F.length()) { + var va = FloatVector.fromArray(SPECIES_F, a, i); + var vb = FloatVector.fromArray(SPECIES_F, b, i); + sums = sums.add(va.mul(vb)); + } + float sum = sums.reduceLanes(VectorOperators.ADD); + for (; i < a.length; i++) { + sum += a[i] * b[i]; + } + return sum; + } + + public static int hashCodeB_loop(byte[] a) { + int h = 1; + for (int i = 0; i < a.length; i++) { + h = 31 * h + a[i]; + } + return h; + } + + public static int hashCodeB_Arrays(byte[] a) { + return Arrays.hashCode(a); + } + + // Simplified intrinsic code from C2_MacroAssembler::arrays_hashcode in c2_MacroAssembler_x86.cpp + // + // Ideas that may help understand the code: + // h(i) = 31 * h(i-1) + a[i] + // "unroll" by factor of L=8: + // h(i+8) = h(i) * 31^8 + a[i+1] * 31^7 + a[i+2] * 31^6 + ... + a[i+8] * 1 + // ----------- ------------------------------------------------ + // scalar vector: notice the powers of 31 in reverse + // + // We notice that we can load a[i+1 .. i+8], then element-wise multiply with + // the vector of reversed powers-of-31, and then do reduceLanes(ADD). + // But we can do even better: By looking at multiple such 8-unrolled iterations. + // Instead of applying the "next" factor of "31^8" to the reduced scalar, we can + // already apply it element-wise. That allows us to move the reduction out + // of the loop. + // + // Note: the intrinsic additionally unrolls the loop by a factor of 4, + // but we want to keep thins simple for demonstration purposes. + // + private static int[] REVERSE_POWERS_OF_31 = new int[9]; + static { + int p = 1; + for (int i = REVERSE_POWERS_OF_31.length - 1; i >= 0; i--) { + REVERSE_POWERS_OF_31[i] = p; + p *= 31; + } + } + public static int hashCodeB_VectorAPI_v1(byte[] a) { + int result = 1; // initialValue + var vresult = IntVector.zero(SPECIES_I256); + int next = REVERSE_POWERS_OF_31[0]; // 31^L + var vcoef = IntVector.fromArray(SPECIES_I256, REVERSE_POWERS_OF_31, 1); // powers of 2 in reverse + int i; + for (i = 0; i < SPECIES_B64.loopBound(a.length); i += SPECIES_B64.length()) { + // scalar part: result *= 31^L + result *= next; + // vector part: element-wise apply the next factor and add in the new values. + var vb = ByteVector.fromArray(SPECIES_B64, a, i); + var vi = vb.castShape(SPECIES_I256, 0); + vresult = vresult.mul(next).add(vi); + } + // reduce the partial hashes in the elements, using the reverse list of powers of 2. + result += vresult.mul(vcoef).reduceLanes(VectorOperators.ADD); + for (; i < a.length; i++) { + result = 31 * result + a[i]; + } + return result; + } + + // This second approach follows the idea from this blog post by Otmar Ertl: + // https://www.dynatrace.com/news/blog/java-arrays-hashcode-byte-efficiency-techniques/ + // + // I simplified the algorithm a little, so that it is a bit closer + // to the solution "v1" above. + // + // The major issue with "v1" is that we cannot load a full vector of bytes, + // because of the cast to ints. So we can only fill 1/4 of the maximal + // vector size. The trick here is to do an unrolling of factor 4, from: + // h(i) = 31 * h(i-1) + a[i] + // to: + // h(i+4) = h(i) * 31^4 + a[i + 1] * 31^3 + // + a[i + 2] * 31^2 + // + a[i + 3] * 31^1 + // + a[i + 4] * 31^0 + // The goal is now to compute this value for 4 bytes within a 4 byte + // lane of the vector. One concern is that we start with byte values, + // but need to do int-multiplication with powers of 31. If we instead + // did a byte-multiplication, we could get overflows that we would not + // have had in the int-multiplication. + // One trick that helps with chaning the size of the lanes from byte + // to short to int is doing all operations with unsigned integers. That + // way, we can zero-extend instead of sign-bit extend. The first step + // is thus to convert the bytes into unsigned values. Since byte is in + // range [-128..128), doing "a[i+j] + 128" makes it a positive value, + // allowing for unsigned multiplication. + // h(i+4) = h(i) * 31^4 + a[i + 1] * 31^3 + // + a[i + 2] * 31^2 + // + a[i + 3] * 31^1 + // + a[i + 4] * 31^0 + // = h(i) * 31^4 + (a[i + 1] + 128 - 128) * 31^3 + // + (a[i + 2] + 128 - 128) * 31^2 + // + (a[i + 3] + 128 - 128) * 31^1 + // + (a[i + 4] + 128 - 128) * 31^0 + // = h(i) * 31^4 + (a[i + 1] + 128 ) * 31^3 + // + (a[i + 2] + 128 ) * 31^2 + // + (a[i + 3] + 128 ) * 31^1 + // + (a[i + 4] + 128 ) * 31^0 + // + -128 * (31^3 + 31^2 + 31^1 + 1) + // = h(i) * 31^4 + ((a[i + 1] + 128) * 31 + // + (a[i + 2] + 128 ) * 31^2 + // + ((a[i + 3] + 128) * 31 + // + (a[i + 4] + 128 ) + // + -128 * (31^3 + 31^2 + 31^1 + 1) + // + // Getting from the signed a[i] value to unsigned with +128, we can + // just xor with 0x80=128. Any numbers there in range [-128..0) are + // now in range [0..128). And any numbers that were in range [0..128) + // are now in unsigned range [128..255). What a neat trick! + // + // We then apply a byte->short transition where we crunch 2 bytes + // into one short, applying a multiplication with 31 to one of the + // two bytes. This multiplication cannot overflow in a short. + // then we apply a short->int transition where we crunch 2 shorts + // into one int, applying a multiplication with 31^2 to one of the + // two shorts. This multiplication cannot overflow in an int. + // + public static int hashCodeB_VectorAPI_v2(byte[] a) { + return HashCodeB_VectorAPI_V2.compute(a); + } + + private static class HashCodeB_VectorAPI_V2 { + private static final int L = Math.min(ByteVector.SPECIES_PREFERRED.length(), + IntVector.SPECIES_PREFERRED.length() * 4); + private static final VectorShape SHAPE = VectorShape.forBitSize(8 * L); + private static final VectorSpecies SPECIES_B = SHAPE.withLanes(byte.class); + private static final VectorSpecies SPECIES_I = SHAPE.withLanes(int.class); + + private static int[] REVERSE_POWERS_OF_31_STEP_4 = new int[L / 4 + 1]; + static { + int p = 1; + int step = 31 * 31 * 31 * 31; // step by 4 + for (int i = REVERSE_POWERS_OF_31_STEP_4.length - 1; i >= 0; i--) { + REVERSE_POWERS_OF_31_STEP_4[i] = p; + p *= step; + } + } + + public static int compute(byte[] a) { + int result = 1; // initialValue + int next = REVERSE_POWERS_OF_31_STEP_4[0]; // 31^L + var vcoef = IntVector.fromArray(SPECIES_I, REVERSE_POWERS_OF_31_STEP_4, 1); // W + var vresult = IntVector.zero(SPECIES_I); + int i; + for (i = 0; i < SPECIES_B.loopBound(a.length); i += SPECIES_B.length()) { + var vb = ByteVector.fromArray(SPECIES_B, a, i); + // Add 128 to each byte. + var vs = vb.lanewise(VectorOperators.XOR, (byte)0x80) + .reinterpretAsShorts(); + // Each short lane contains 2 bytes, crunch them. + var vi = vs.and((short)0xff) // lower byte + .mul((short)31) + .add(vs.lanewise(VectorOperators.LSHR, 8)) // upper byte + .reinterpretAsInts(); + // Each int contains 2 shorts, crunch them. + var v = vi.and(0xffff) // lower short + .mul(31 * 31) + .add(vi.lanewise(VectorOperators.LSHR, 16)); // upper short + // Add the correction for the 128 additions above. + v = v.add(-128 * (31*31*31 + 31*31 + 31 + 1)); + // Every element of v now contains a crunched int-package of 4 bytes. + result *= next; + vresult = vresult.mul(next).add(v); + } + result += vresult.mul(vcoef).reduceLanes(VectorOperators.ADD); + for (; i < a.length; i++) { + result = 31 * result + a[i]; + } + return result; + } + } + + public static Object scanAddI_loop(int[] a, int[] r) { + int sum = 0; + for (int i = 0; i < a.length; i++) { + sum += a[i]; + r[i] = sum; + } + return r; + } + + public static Object scanAddI_loop_reassociate(int[] a, int[] r) { + int sum = 0; + int i = 0; + for (; i < a.length - 3; i += 4) { + // We cut the latency by a factor of 4, but increase the number of additions. + int old_sum = sum; + int v0 = a[i + 0]; + int v1 = a[i + 1]; + int v2 = a[i + 2]; + int v3 = a[i + 3]; + int v01 = v0 + v1; + int v23 = v2 + v3; + int v0123 = v01 + v23; + sum += v0123; + r[i + 0] = old_sum + v0; + r[i + 1] = old_sum + v01; + r[i + 2] = old_sum + v01 + v2; + r[i + 3] = old_sum + v0123; + } + for (; i < a.length; i++) { + sum += a[i]; + r[i] = sum; + } + return r; + } + + public static Object scanAddI_VectorAPI_permute_add(int[] a, int[] r) { + // Using Naive Parallel Algorithm: Hills and Steele + int sum = 0; + int xx = 0; // masked later anyway + var shf1 = VectorShuffle.fromArray(SPECIES_I512, new int[]{xx, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 0); + var shf2 = VectorShuffle.fromArray(SPECIES_I512, new int[]{xx, xx, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 0); + var shf3 = VectorShuffle.fromArray(SPECIES_I512, new int[]{xx, xx, xx, xx, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 0); + var shf4 = VectorShuffle.fromArray(SPECIES_I512, new int[]{xx, xx, xx, xx, xx, xx, xx, xx, 0, 1, 2, 3, 4, 5, 6, 7}, 0); + var mask1 = VectorMask.fromLong(SPECIES_I512, 0b1111111111111110); + var mask2 = VectorMask.fromLong(SPECIES_I512, 0b1111111111111100); + var mask3 = VectorMask.fromLong(SPECIES_I512, 0b1111111111110000); + var mask4 = VectorMask.fromLong(SPECIES_I512, 0b1111111100000000); + int i = 0; + for (; i < SPECIES_I512.loopBound(a.length); i += SPECIES_I512.length()) { + IntVector v = IntVector.fromArray(SPECIES_I512, a, i); + v = v.add(v.rearrange(shf1), mask1); + v = v.add(v.rearrange(shf2), mask2); + v = v.add(v.rearrange(shf3), mask3); + v = v.add(v.rearrange(shf4), mask4); + v = v.add(sum); + v.intoArray(r, i); + sum = v.lane(SPECIES_I512.length() - 1); + } + for (; i < a.length; i++) { + sum += a[i]; + r[i] = sum; + } + return r; + } + + public static int findMinIndexI_loop(int[] a) { + int min = a[0]; + int index = 0; + for (int i = 1; i < a.length; i++) { + int ai = a[i]; + if (ai < min) { + min = ai; + index = i; + } + } + return index; + } + + public static int findMinIndexI_VectorAPI(int[] a) { + // Main approach: have partial results in mins and idxs. + var mins = IntVector.broadcast(SPECIES_I, a[0]); + var idxs = IntVector.broadcast(SPECIES_I, 0); + var iota = IntVector.broadcast(SPECIES_I, 0).addIndex(1); + int i = 0; + for (; i < SPECIES_I.loopBound(a.length); i += SPECIES_I.length()) { + IntVector v = IntVector.fromArray(SPECIES_I, a, i); + var mask = v.compare(VectorOperators.LT, mins); + mins = mins.blend(v, mask); + idxs = idxs.blend(iota, mask); + iota = iota.add(SPECIES_I.length()); + } + // Reduce the vectors down + int min = mins.reduceLanes(VectorOperators.MIN); + var not_min_mask = mins.compare(VectorOperators.NE, min); + int index = idxs.blend(a.length, not_min_mask).reduceLanes(VectorOperators.MIN); + // Tail loop + for (; i < a.length; i++) { + int ai = a[i]; + if (ai < min) { + min = ai; + index = i; + } + } + return index; + } + + public static int findI_loop(int[] a, int e) { + for (int i = 0; i < a.length; i++) { + int ai = a[i]; + if (ai == e) { + return i; + } + } + return -1; + } + + public static int findI_VectorAPI(int[] a, int e) { + var es = IntVector.broadcast(SPECIES_I, e); + int i = 0; + for (; i < SPECIES_I.loopBound(a.length); i += SPECIES_I.length()) { + IntVector v = IntVector.fromArray(SPECIES_I, a, i); + var mask = v.compare(VectorOperators.EQ, es); + if (mask.anyTrue()) { + return i + mask.firstTrue(); + } + } + for (; i < a.length; i++) { + int ai = a[i]; + if (ai == e) { + return i; + } + } + return -1; + } + + public static Object reverseI_loop(int[] a, int[] r) { + for (int i = 0; i < a.length; i++) { + r[a.length - i - 1] = a[i]; + } + return r; + } + + private static final VectorShuffle REVERSE_SHUFFLE_I = SPECIES_I.iotaShuffle(SPECIES_I.length()-1, -1, true); + + public static Object reverseI_VectorAPI(int[] a, int[] r) { + int i = 0; + for (; i < SPECIES_I.loopBound(a.length); i += SPECIES_I.length()) { + IntVector v = IntVector.fromArray(SPECIES_I, a, i); + v = v.rearrange(REVERSE_SHUFFLE_I); + v.intoArray(r, r.length - SPECIES_I.length() - i); + } + for (; i < a.length; i++) { + r[a.length - i - 1] = a[i]; + } + return r; + } + + public static Object filterI_loop(int[] a, int[] r, int threshold) { + int j = 0; + for (int i = 0; i < a.length; i++) { + int ai = a[i]; + if (ai >= threshold) { + r[j++] = ai; + } + } + // Just force the resulting length onto the same array. + r[r.length - 1] = j; + return r; + } + + public static Object filterI_VectorAPI(int[] a, int[] r, int threshold) { + var thresholds = IntVector.broadcast(SPECIES_I, threshold); + int j = 0; + int i = 0; + for (; i < SPECIES_I.loopBound(a.length); i += SPECIES_I.length()) { + IntVector v = IntVector.fromArray(SPECIES_I, a, i); + var mask = v.compare(VectorOperators.GE, thresholds); + v = v.compress(mask); + int trueCount = mask.trueCount(); + var prefixMask = mask.compress(); + v.intoArray(r, j, prefixMask); + j += trueCount; + } + + for (; i < a.length; i++) { + int ai = a[i]; + if (ai >= threshold) { + r[j++] = ai; + } + } + // Just force the resulting length onto the same array. + r[r.length - 1] = j; + return r; + } + + // X4: ints simulate 4-byte oops. + // oops: if non-zero (= non-null), every entry simulates a 4-byte oop, pointing into mem. + // mem: an int array that simulates the memory. + // + // Task: Find all non-null oops, and dereference them, get the relevant field. + // Objects have 16 bytes, and the relevant field is at bytes 12-16. + // That maps to 4 ints, and the relevant field is the 4th element of 4. + // Sum up all the field values. + public static int reduceAddIFieldsX4_loop(int[] oops, int[] mem) { + int sum = 0; + for (int i = 0; i < oops.length; i++) { + int oop = oops[i]; + if (oop != 0) { + int fieldValue = mem[oop + 3]; // oop+12 + sum += fieldValue; + } + } + return sum; + } + + public static int reduceAddIFieldsX4_VectorAPI(int[] oops, int[] mem) { + var acc = IntVector.broadcast(SPECIES_I, 0); + int i = 0; + for (; i < SPECIES_I.loopBound(oops.length); i += SPECIES_I.length()) { + var oopv = IntVector.fromArray(SPECIES_I, oops, i); + var mask = oopv.compare(VectorOperators.NE, /* null */0); + // We are lucky today: we need to access mem[oop + 3] + var fieldValues = IntVector.fromArray(SPECIES_I, mem, 3, oops, i, mask); + acc = acc.add(fieldValues); + } + int sum = acc.reduceLanes(VectorOperators.ADD); + for (; i < oops.length; i++) { + int oop = oops[i]; + if (oop != 0) { + int fieldValue = mem[oop + 3]; // oop+12 + sum += fieldValue; + } + } + return sum; + } + + // The lowerCase example demonstrates a lane-wise control-flow diamond. + public static Object lowerCaseB_loop(byte[] a, byte[] r) { + for (int i = 0; i < a.length; i++) { + byte c = a[i]; + if (c >= 'A' && c <= 'Z') { + c += ('a' - 'A'); // c += 32 + } + r[i] = c; + } + return r; + } + + // Control-flow diamonds can easily be simulated by "if-conversion", i.e. + // by using masked operations. An alternative would be to use blend. + public static Object lowerCaseB_VectorAPI_v1(byte[] a, byte[] r) { + int i; + for (i = 0; i < SPECIES_B.loopBound(a.length); i += SPECIES_B.length()) { + var vc = ByteVector.fromArray(SPECIES_B, a, i); + var maskA = vc.compare(VectorOperators.GE, (byte)'A'); + var maskZ = vc.compare(VectorOperators.LE, (byte)'Z'); + var mask = maskA.and(maskZ); + vc = vc.add((byte)32, mask); + vc.intoArray(r, i); + } + for (; i < a.length; i++) { + byte c = a[i]; + if (c >= 'A' && c <= 'Z') { + c += ('a' - 'A'); + } + r[i] = c; + } + return r; + } + + public static Object lowerCaseB_VectorAPI_v2(byte[] a, byte[] r) { + int i; + for (i = 0; i < SPECIES_B.loopBound(a.length); i += SPECIES_B.length()) { + var vc = ByteVector.fromArray(SPECIES_B, a, i); + // We can convert the range 65..90 (represents ascii A..Z) into a range 0..25. + // This allows us to only use a single unsigned comparison. + var vt = vc.add((byte)-'A'); + var mask = vt.compare(VectorOperators.ULE, (byte)25); + vc = vc.add((byte)32, mask); + vc.intoArray(r, i); + } + for (; i < a.length; i++) { + byte c = a[i]; + if (c >= 'A' && c <= 'Z') { + c += ('a' - 'A'); + } + r[i] = c; + } + return r; + } +} diff --git a/test/hotspot/jtreg/containers/docker/TestJcmd.java b/test/hotspot/jtreg/containers/docker/TestJcmd.java index 3cfe2945e92..fcd5c665f2b 100644 --- a/test/hotspot/jtreg/containers/docker/TestJcmd.java +++ b/test/hotspot/jtreg/containers/docker/TestJcmd.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -143,6 +143,7 @@ public class TestJcmd { sb.append(String.format("FROM %s:%s\n", DockerfileConfig.getBaseImageName(), DockerfileConfig.getBaseImageVersion())); sb.append("COPY /jdk /jdk\n"); + sb.append("ENV LANG=C.UTF-8\n"); sb.append("ENV JAVA_HOME=/jdk\n"); if (!IS_PODMAN) { // only needed for docker diff --git a/test/hotspot/jtreg/runtime/NMT/NMTPrintMallocSiteOfCorruptedMemory.java b/test/hotspot/jtreg/runtime/NMT/NMTPrintMallocSiteOfCorruptedMemory.java index 7f0f1be929b..f1d4964d6cf 100644 --- a/test/hotspot/jtreg/runtime/NMT/NMTPrintMallocSiteOfCorruptedMemory.java +++ b/test/hotspot/jtreg/runtime/NMT/NMTPrintMallocSiteOfCorruptedMemory.java @@ -24,6 +24,8 @@ /* * @test * @summary Check the allocation-site stack trace of a corrupted memory at free() time + * @comment Under ASAN build, memory corruption is reported by ASAN runtime and not JVM. + * @requires !vm.asan * @modules java.base/jdk.internal.misc * @library /test/lib * @build jdk.test.whitebox.WhiteBox diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTMapTest.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTMapTest.java index 6cbfcbbd3c3..209eb064945 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTMapTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTMapTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -136,6 +136,7 @@ public class AOTMapTest { } class AOTMapTestApp { + static URLClassLoader loader; // keep Hello class alive public static void main(String[] args) throws Exception { System.out.println("Hello AOTMapTestApp"); testCustomLoader(); @@ -144,7 +145,7 @@ class AOTMapTestApp { static void testCustomLoader() throws Exception { File custJar = new File("cust.jar"); URL[] urls = new URL[] {custJar.toURI().toURL()}; - URLClassLoader loader = new URLClassLoader(urls, AOTMapTestApp.class.getClassLoader()); + loader = new URLClassLoader(urls, AOTMapTestApp.class.getClassLoader()); Class c = loader.loadClass("Hello"); System.out.println(c); } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/sharedStrings/SharedStringsStress.java b/test/hotspot/jtreg/runtime/cds/appcds/sharedStrings/SharedStringsStress.java index 4d176c949c6..dc677756ffa 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/sharedStrings/SharedStringsStress.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/sharedStrings/SharedStringsStress.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -80,8 +80,6 @@ public class SharedStringsStress { "-Xlog:gc+region+cds", "-Xlog:gc+region=trace")); TestCommon.checkDump(dumpOutput); - dumpOutput.shouldContain("string table array (primary)"); - dumpOutput.shouldContain("string table array (secondary)"); // We could create up to 26MB of archived heap objects. Run with enough Xms to ensure // SerialGC can accommodate the archived objects during VM start up. diff --git a/test/hotspot/jtreg/runtime/os/TestWXHealing.java b/test/hotspot/jtreg/runtime/os/TestWXHealing.java new file mode 100644 index 00000000000..46875848a89 --- /dev/null +++ b/test/hotspot/jtreg/runtime/os/TestWXHealing.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2025 IBM Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @requires os.family == "mac" + * @requires os.arch == "aarch64" + * @summary Run shell with -XX:+StressWXHealing. This tests most of + * the triggers for WX mode. + * @library /test/lib + * @compile WXHealing.java + * @run main TestWXHealing + */ + +import java.util.regex.*; +import jdk.test.lib.process.*; + +import static java.nio.charset.StandardCharsets.*; + +public class TestWXHealing { + + public static void main(String[] args) throws Throwable { + String[] opts = {"-XX:+UnlockDiagnosticVMOptions", + "-XX:+TraceWXHealing", "-XX:+StressWXHealing", "WXHealing"}; + var process = ProcessTools.createTestJavaProcessBuilder(opts).start(); + String output = new String(process.getInputStream().readAllBytes(), UTF_8); + System.out.println(output); + if (output.contains("MAP_JIT write protection does not work on this system")) { + System.out.println("Test was not run because MAP_JIT write protection does not work on this system"); + } else { + var pattern = Pattern.compile("Healing WXMode WXArmedForWrite at 0x[0-9a-f]* to WXWrite "); + var matches = pattern.matcher(output).results().count(); + if (matches < 10) { + throw new RuntimeException("Only " + matches + " healings in\n" + output); + } + } + } +} diff --git a/test/hotspot/jtreg/runtime/os/WXHealing.java b/test/hotspot/jtreg/runtime/os/WXHealing.java new file mode 100644 index 00000000000..ba790db2c59 --- /dev/null +++ b/test/hotspot/jtreg/runtime/os/WXHealing.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2025 IBM Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.*; +import jdk.jshell.tool.*; + +public class WXHealing { + + // There's nothing special about jshell here: we just need an + // application that does a lot of compilation and class loading. + public static void main(String[] args) throws Throwable { + JavaShellToolBuilder + .builder() + .in(new ByteArrayInputStream + (""" + void main() { + System.out.println("Hello, World!"); + } + main() + 2+2 + Math.sqrt(2) + 4 * Math.atan(1) + Math.exp(1) + """ + .getBytes()), null) + .start(); + } +} diff --git a/test/hotspot/jtreg/serviceability/jvmti/SuspendWithObjectMonitorWait/SuspendWithObjectMonitorWait.java b/test/hotspot/jtreg/serviceability/jvmti/SuspendWithObjectMonitorWait/SuspendWithObjectMonitorWait.java deleted file mode 100644 index 3a747a3e86b..00000000000 --- a/test/hotspot/jtreg/serviceability/jvmti/SuspendWithObjectMonitorWait/SuspendWithObjectMonitorWait.java +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 4413752 8262881 - * @summary Test SuspendThread with ObjectMonitor wait. - * @requires vm.jvmti - * @library /test/lib - * @compile SuspendWithObjectMonitorWait.java - * @run main/othervm/native -agentlib:SuspendWithObjectMonitorWait SuspendWithObjectMonitorWait - */ - -import java.io.PrintStream; - -// -// main waiter resumer -// ================= ================== =================== -// launch waiter -// waiter running -// launch resumer enter threadLock -// threadLock.wait() resumer running -// enter threadLock : wait for notify -// threadLock.notify wait finishes : -// : reenter blocks : -// suspend waiter : -// exit threadLock : : -// : : -// : : : -// notify resumer : wait finishes -// join resumer : enter threadLock -// : resume waiter -// : : exit threadLock -// : reenter threadLock : -// : resumer exits -// join waiter : -// waiter exits -// - -public class SuspendWithObjectMonitorWait { - private static final String AGENT_LIB = "SuspendWithObjectMonitorWait"; - private static final int exit_delta = 95; - - private static final int DEF_TIME_MAX = 60; // default max # secs to test - private static final int JOIN_MAX = 30; // max # secs to wait for join - - public static final int TS_INIT = 1; // initial testState - public static final int TS_WAITER_RUNNING = 2; // waiter is running - public static final int TS_RESUMER_RUNNING = 3; // resumer is running - public static final int TS_READY_TO_NOTIFY = 4; // ready to notify threadLock - public static final int TS_CALL_SUSPEND = 5; // call suspend on contender - public static final int TS_READY_TO_RESUME = 6; // ready to resume waiter - public static final int TS_CALL_RESUME = 7; // call resume on waiter - public static final int TS_WAITER_DONE = 8; // waiter has run; done - - public static Object barrierLaunch = new Object(); // controls thread launch - public static Object barrierResumer = new Object(); // controls resumer - public static Object threadLock = new Object(); // testing object - - public static long count = 0; - public static boolean printDebug = false; - public volatile static int testState; - - private static void log(String msg) { System.out.println(msg); } - - native static int suspendThread(SuspendWithObjectMonitorWaitWorker thr); - native static int wait4ContendedEnter(SuspendWithObjectMonitorWaitWorker thr); - - public static void main(String[] args) throws Exception { - try { - System.loadLibrary(AGENT_LIB); - log("Loaded library: " + AGENT_LIB); - } catch (UnsatisfiedLinkError ule) { - log("Failed to load library: " + AGENT_LIB); - log("java.library.path: " + System.getProperty("java.library.path")); - throw ule; - } - - int timeMax = 0; - if (args.length == 0) { - timeMax = DEF_TIME_MAX; - } else { - int argIndex = 0; - int argsLeft = args.length; - if (args[0].equals("-p")) { - printDebug = true; - argIndex = 1; - argsLeft--; - } - if (argsLeft == 0) { - timeMax = DEF_TIME_MAX; - } else if (argsLeft == 1) { - try { - timeMax = Integer.parseUnsignedInt(args[argIndex]); - } catch (NumberFormatException nfe) { - System.err.println("'" + args[argIndex] + - "': invalid timeMax value."); - usage(); - } - } else { - usage(); - } - } - - System.exit(run(timeMax, System.out) + exit_delta); - } - - public static void logDebug(String mesg) { - if (printDebug) { - System.err.println(Thread.currentThread().getName() + ": " + mesg); - } - } - - public static void usage() { - System.err.println("Usage: " + AGENT_LIB + " [-p][time_max]"); - System.err.println("where:"); - System.err.println(" -p ::= print debug info"); - System.err.println(" time_max ::= max looping time in seconds"); - System.err.println(" (default is " + DEF_TIME_MAX + - " seconds)"); - System.exit(1); - } - - public static int run(int timeMax, PrintStream out) { - return (new SuspendWithObjectMonitorWait()).doWork(timeMax, out); - } - - public static void checkTestState(int exp) { - if (testState != exp) { - System.err.println("Failure at " + count + " loops."); - throw new InternalError("Unexpected test state value: " - + "expected=" + exp + " actual=" + testState); - } - } - - public int doWork(int timeMax, PrintStream out) { - SuspendWithObjectMonitorWaitWorker waiter; // waiter thread - SuspendWithObjectMonitorWaitWorker resumer; // resumer thread - - System.out.println("About to execute for " + timeMax + " seconds."); - - long start_time = System.currentTimeMillis(); - while (System.currentTimeMillis() < start_time + (timeMax * 1000)) { - count++; - testState = TS_INIT; // starting the test loop - - // launch the waiter thread - synchronized (barrierLaunch) { - waiter = new SuspendWithObjectMonitorWaitWorker("waiter"); - waiter.start(); - - while (testState != TS_WAITER_RUNNING) { - try { - barrierLaunch.wait(0); // wait until it is running - } catch (InterruptedException ex) { - } - } - } - - // launch the resumer thread - synchronized (barrierLaunch) { - resumer = new SuspendWithObjectMonitorWaitWorker("resumer", waiter); - resumer.start(); - - while (testState != TS_RESUMER_RUNNING) { - try { - barrierLaunch.wait(0); // wait until it is running - } catch (InterruptedException ex) { - } - } - } - - checkTestState(TS_RESUMER_RUNNING); - - // The waiter thread was synchronized on threadLock before it - // set TS_WAITER_RUNNING and notified barrierLaunch above so - // we cannot enter threadLock until the waiter thread calls - // threadLock.wait(). - synchronized (threadLock) { - // notify waiter thread so it can try to reenter threadLock - testState = TS_READY_TO_NOTIFY; - threadLock.notify(); - - // wait for the waiter thread to block - logDebug("before contended enter wait"); - int retCode = wait4ContendedEnter(waiter); - if (retCode != 0) { - throw new RuntimeException("error in JVMTI GetThreadState: " - + "retCode=" + retCode); - } - logDebug("done contended enter wait"); - - checkTestState(TS_READY_TO_NOTIFY); - testState = TS_CALL_SUSPEND; - logDebug("before suspend thread"); - retCode = suspendThread(waiter); - if (retCode != 0) { - throw new RuntimeException("error in JVMTI SuspendThread: " - + "retCode=" + retCode); - } - logDebug("suspended thread"); - } - - // - // At this point, all of the child threads are running - // and we can get to meat of the test: - // - // - suspended threadLock waiter (trying to reenter) - // - a threadLock enter in the resumer thread - // - resumption of the waiter thread - // - a threadLock enter in the freshly resumed waiter thread - // - - synchronized (barrierResumer) { - checkTestState(TS_CALL_SUSPEND); - - // tell resumer thread to resume waiter thread - testState = TS_READY_TO_RESUME; - barrierResumer.notify(); - - // Can't call checkTestState() here because the - // resumer thread may have already resumed the - // waiter thread. - } - - try { - resumer.join(JOIN_MAX * 1000); - if (resumer.isAlive()) { - System.err.println("Failure at " + count + " loops."); - throw new InternalError("resumer thread is stuck"); - } - waiter.join(JOIN_MAX * 1000); - if (waiter.isAlive()) { - System.err.println("Failure at " + count + " loops."); - throw new InternalError("waiter thread is stuck"); - } - } catch (InterruptedException ex) { - } - - checkTestState(TS_WAITER_DONE); - } - - System.out.println("Executed " + count + " loops in " + timeMax + - " seconds."); - - return 0; - } -} - -class SuspendWithObjectMonitorWaitWorker extends Thread { - private SuspendWithObjectMonitorWaitWorker target; // target for resume operation - - public SuspendWithObjectMonitorWaitWorker(String name) { - super(name); - } - - public SuspendWithObjectMonitorWaitWorker(String name, SuspendWithObjectMonitorWaitWorker target) { - super(name); - this.target = target; - } - - native static int resumeThread(SuspendWithObjectMonitorWaitWorker thr); - - public void run() { - SuspendWithObjectMonitorWait.logDebug("thread running"); - - // - // Launch the waiter thread: - // - grab the threadLock - // - threadLock.wait() - // - releases threadLock - // - if (getName().equals("waiter")) { - // grab threadLock before we tell main we are running - SuspendWithObjectMonitorWait.logDebug("before enter threadLock"); - synchronized(SuspendWithObjectMonitorWait.threadLock) { - SuspendWithObjectMonitorWait.logDebug("enter threadLock"); - - SuspendWithObjectMonitorWait.checkTestState(SuspendWithObjectMonitorWait.TS_INIT); - - synchronized(SuspendWithObjectMonitorWait.barrierLaunch) { - // tell main we are running - SuspendWithObjectMonitorWait.testState = SuspendWithObjectMonitorWait.TS_WAITER_RUNNING; - SuspendWithObjectMonitorWait.barrierLaunch.notify(); - } - - SuspendWithObjectMonitorWait.logDebug("before wait"); - - // TS_READY_TO_NOTIFY is set after the main thread has - // entered threadLock so a spurious wakeup can't get the - // waiter thread out of this threadLock.wait(0) call: - while (SuspendWithObjectMonitorWait.testState <= SuspendWithObjectMonitorWait.TS_READY_TO_NOTIFY) { - try { - SuspendWithObjectMonitorWait.threadLock.wait(0); - } catch (InterruptedException ex) { - } - } - - SuspendWithObjectMonitorWait.logDebug("after wait"); - - SuspendWithObjectMonitorWait.checkTestState(SuspendWithObjectMonitorWait.TS_CALL_RESUME); - SuspendWithObjectMonitorWait.testState = SuspendWithObjectMonitorWait.TS_WAITER_DONE; - - SuspendWithObjectMonitorWait.logDebug("exit threadLock"); - } - } - // - // Launch the resumer thread: - // - tries to grab the threadLock (should not block!) - // - grabs threadLock - // - resumes the waiter thread - // - releases threadLock - // - else if (getName().equals("resumer")) { - synchronized(SuspendWithObjectMonitorWait.barrierResumer) { - synchronized(SuspendWithObjectMonitorWait.barrierLaunch) { - // tell main we are running - SuspendWithObjectMonitorWait.testState = SuspendWithObjectMonitorWait.TS_RESUMER_RUNNING; - SuspendWithObjectMonitorWait.barrierLaunch.notify(); - } - SuspendWithObjectMonitorWait.logDebug("thread waiting"); - while (SuspendWithObjectMonitorWait.testState != SuspendWithObjectMonitorWait.TS_READY_TO_RESUME) { - try { - // wait for main to tell us when to continue - SuspendWithObjectMonitorWait.barrierResumer.wait(0); - } catch (InterruptedException ex) { - } - } - } - - SuspendWithObjectMonitorWait.logDebug("before enter threadLock"); - synchronized(SuspendWithObjectMonitorWait.threadLock) { - SuspendWithObjectMonitorWait.logDebug("enter threadLock"); - - SuspendWithObjectMonitorWait.checkTestState(SuspendWithObjectMonitorWait.TS_READY_TO_RESUME); - SuspendWithObjectMonitorWait.testState = SuspendWithObjectMonitorWait.TS_CALL_RESUME; - - // resume the waiter thread so waiter.join() can work - SuspendWithObjectMonitorWait.logDebug("before resume thread"); - int retCode = resumeThread(target); - if (retCode != 0) { - throw new RuntimeException("error in JVMTI ResumeThread: " + - "retCode=" + retCode); - } - SuspendWithObjectMonitorWait.logDebug("resumed thread"); - - SuspendWithObjectMonitorWait.logDebug("exit threadLock"); - } - } - } -} diff --git a/test/hotspot/jtreg/serviceability/jvmti/SuspendWithObjectMonitorWait/SuspendWithObjectMonitorWaitBase.java b/test/hotspot/jtreg/serviceability/jvmti/SuspendWithObjectMonitorWait/SuspendWithObjectMonitorWaitBase.java new file mode 100644 index 00000000000..5443e4005fe --- /dev/null +++ b/test/hotspot/jtreg/serviceability/jvmti/SuspendWithObjectMonitorWait/SuspendWithObjectMonitorWaitBase.java @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2001, 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.PrintStream; + +public class SuspendWithObjectMonitorWaitBase { + protected static final String AGENT_LIB = "SuspendWithObjectMonitorWait"; + protected static final int exit_delta = 95; + + protected static final int DEF_TIME_MAX = 60; // default max # secs to test + protected static final int JOIN_MAX = 30; // max # secs to wait for join + + public static final int TS_INIT = 1; // initial testState + public static final int TS_WAITER_RUNNING = 2; // waiter is running + public static final int TS_RESUMER_RUNNING = 3; // resumer is running + public static final int TS_READY_TO_NOTIFY = 4; // ready to notify threadLock + public static final int TS_CALL_SUSPEND = 5; // call suspend on contender + public static final int TS_READY_TO_RESUME = 6; // ready to resume waiter + public static final int TS_CALL_RESUME = 7; // call resume on waiter + public static final int TS_WAITER_DONE = 8; // waiter has run; done + + public static Object barrierLaunch = new Object(); // controls thread launch + public static Object barrierResumer = new Object(); // controls resumer + public static Object threadLock = new Object(); // testing object + + public static long count = 0; + public static boolean printDebug = false; + public volatile static int testState; + + protected static void log(String msg) { System.out.println(msg); } + + native static int suspendThread(SuspendWithObjectMonitorWaitWorker thr); + native static int wait4ContendedEnter(SuspendWithObjectMonitorWaitWorker thr); + + public static void logDebug(String mesg) { + if (printDebug) { + System.err.println(Thread.currentThread().getName() + ": " + mesg); + } + } + + public static void usage() { + System.err.println("Usage: " + AGENT_LIB + " test_case [-p] [time_max]"); + System.err.println("where:"); + System.err.println(" test_case ::= 1 | 2 | 3"); + System.err.println(" -p ::= print debug info"); + System.err.println(" time_max ::= max looping time in seconds"); + System.err.println(" (default is " + DEF_TIME_MAX + + " seconds)"); + System.exit(1); + } + + public static void checkTestState(int exp) { + if (testState != exp) { + System.err.println("Failure at " + count + " loops."); + throw new InternalError("Unexpected test state value: " + + "expected=" + exp + " actual=" + testState); + } + } + + public SuspendWithObjectMonitorWaitWorker launchWaiter(long waitTimeout) { + SuspendWithObjectMonitorWaitWorker waiter; + // launch the waiter thread + synchronized (barrierLaunch) { + waiter = new SuspendWithObjectMonitorWaitWorker("waiter", waitTimeout); + waiter.start(); + + while (testState != TS_WAITER_RUNNING) { + try { + barrierLaunch.wait(0); // wait until it is running + } catch (InterruptedException ex) { + } + } + } + return waiter; + } + + public SuspendWithObjectMonitorWaitWorker launchResumer(SuspendWithObjectMonitorWaitWorker waiter) { + SuspendWithObjectMonitorWaitWorker resumer; + synchronized (barrierLaunch) { + resumer = new SuspendWithObjectMonitorWaitWorker("resumer", waiter); + resumer.start(); + + while (testState != TS_RESUMER_RUNNING) { + try { + barrierLaunch.wait(0); // wait until it is running + } catch (InterruptedException ex) { + } + } + } + return resumer; + } + + public void barrierResumerNotify() { + synchronized (barrierResumer) { + checkTestState(TS_CALL_SUSPEND); + + // tell resumer thread to resume waiter thread + testState = TS_READY_TO_RESUME; + barrierResumer.notify(); + + // Can't call checkTestState() here because the + // resumer thread may have already resumed the + // waiter thread. + } + } + + public void shutDown(SuspendWithObjectMonitorWaitWorker resumer, SuspendWithObjectMonitorWaitWorker waiter) { + try { + resumer.join(JOIN_MAX * 1000); + if (resumer.isAlive()) { + System.err.println("Failure at " + count + " loops."); + throw new InternalError("resumer thread is stuck"); + } + waiter.join(JOIN_MAX * 1000); + if (waiter.isAlive()) { + System.err.println("Failure at " + count + " loops."); + throw new InternalError("waiter thread is stuck"); + } + } catch (InterruptedException ex) { + } + } + + public int run(int timeMax, PrintStream out) { + return 0; + } + + public static void main(String[] args) throws Exception { + if (args.length == 0) { + System.err.println("Invalid number of arguments, there should be at least a test_case given."); + usage(); + } + + if (args.length > 3) { + System.err.println("Invalid number of arguments, there are too many arguments."); + usage(); + } + + try { + System.loadLibrary(AGENT_LIB); + log("Loaded library: " + AGENT_LIB); + } catch (UnsatisfiedLinkError ule) { + log("Failed to load library: " + AGENT_LIB); + log("java.library.path: " + System.getProperty("java.library.path")); + throw ule; + } + + int testCase = 0; + int timeMax = 0; + for (int argIndex = 0; argIndex < args.length; argIndex++) { + if (args[argIndex].equals("-p")) { + // Handle optional -p arg regardless of position. + printDebug = true; + continue; + } + + if (testCase == 0) { + try { + // testCase must be the first non-optional arg. + testCase = Integer.parseUnsignedInt(args[argIndex]); + log("testCase = " + testCase); + } catch (NumberFormatException nfe) { + System.err.println("'" + args[argIndex] + + "': invalid test_case value."); + usage(); + } + if (testCase < 1 || testCase > 3) { + System.err.println("Invalid test_case value: '" + testCase + "'"); + usage(); + } + continue; + } + + if (argIndex < args.length) { + // timeMax is an optional arg. + try { + timeMax = Integer.parseUnsignedInt(args[argIndex]); + } catch (NumberFormatException nfe) { + System.err.println("'" + args[argIndex] + + "': invalid time_max value."); + usage(); + } + } else { + timeMax = DEF_TIME_MAX; + } + } + + if (timeMax == 0) { + timeMax = DEF_TIME_MAX; + } + log("timeMax = " + timeMax); + + if (testCase == 0) { + // Just -p was given. + System.err.println("Invalid number of arguments, no test_case given."); + usage(); + } + + SuspendWithObjectMonitorWaitBase test = null; + switch (testCase) { + case 1: + test = new SuspendWithObjectMonitorWaitDefault(); + break; + case 2: + test = new SuspendWithObjectMonitorWaitReentryPartFirst(); + break; + case 3: + test = new SuspendWithObjectMonitorWaitReentryPartSecond(); + break; + default: + // Impossible + break; + } + int result = test.run(timeMax, System.out); + System.exit(result + exit_delta); + } +} diff --git a/test/hotspot/jtreg/serviceability/jvmti/SuspendWithObjectMonitorWait/SuspendWithObjectMonitorWaitDefault.java b/test/hotspot/jtreg/serviceability/jvmti/SuspendWithObjectMonitorWait/SuspendWithObjectMonitorWaitDefault.java new file mode 100644 index 00000000000..b2c1f108de5 --- /dev/null +++ b/test/hotspot/jtreg/serviceability/jvmti/SuspendWithObjectMonitorWait/SuspendWithObjectMonitorWaitDefault.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2001, 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4413752 8262881 + * @summary Test SuspendThread with ObjectMonitor wait. + * @requires vm.jvmti + * @library /test/lib + * @compile SuspendWithObjectMonitorWaitDefault.java + * @run main/othervm/native -agentlib:SuspendWithObjectMonitorWait SuspendWithObjectMonitorWaitDefault 1 + */ + +import java.io.PrintStream; + +// +// SuspendWithObjectMonitorWaitDefault algorithm: +// +// main waiter resumer +// ================= ================== =================== +// launch waiter +// waiter running +// launch resumer enter threadLock +// threadLock.wait() resumer running +// enter threadLock : wait for notify +// threadLock.notify wait finishes : +// : reenter blocks : +// suspend waiter : +// exit threadLock : : +// : : +// : : : +// notify resumer : wait finishes +// join resumer : enter threadLock +// : resume waiter +// : : exit threadLock +// : reenter threadLock : +// : resumer exits +// join waiter : +// waiter exits +// + +public class SuspendWithObjectMonitorWaitDefault extends SuspendWithObjectMonitorWaitBase { + + @Override + public int run(int timeMax, PrintStream out) { + return doWork1(timeMax, out); + } + + // Default scenario, the resumer thread is always able to grab the threadLock once notified by the main thread. + public int doWork1(int timeMax, PrintStream out) { + SuspendWithObjectMonitorWaitWorker waiter; // waiter thread + SuspendWithObjectMonitorWaitWorker resumer; // resumer thread + + System.out.println("Test 1: About to execute for " + timeMax + " seconds."); + + long start_time = System.currentTimeMillis(); + while (System.currentTimeMillis() < start_time + (timeMax * 1000)) { + count++; + testState = TS_INIT; // starting the test loop + + // launch the waiter thread + waiter = launchWaiter(0); + + // launch the resumer thread + resumer = launchResumer(waiter); + + checkTestState(TS_RESUMER_RUNNING); + + // The waiter thread was synchronized on threadLock before it + // set TS_WAITER_RUNNING and notified barrierLaunch above so + // we cannot enter threadLock until the waiter thread calls + // threadLock.wait(). + synchronized (threadLock) { + // notify waiter thread so it can try to reenter threadLock + testState = TS_READY_TO_NOTIFY; + threadLock.notify(); + + // wait for the waiter thread to block + logDebug("before contended enter wait"); + int retCode = wait4ContendedEnter(waiter); + if (retCode != 0) { + throw new RuntimeException("error in JVMTI GetThreadState: " + + "retCode=" + retCode); + } + logDebug("done contended enter wait"); + + checkTestState(TS_READY_TO_NOTIFY); + testState = TS_CALL_SUSPEND; + logDebug("before suspend thread"); + retCode = suspendThread(waiter); + if (retCode != 0) { + throw new RuntimeException("error in JVMTI SuspendThread: " + + "retCode=" + retCode); + } + logDebug("suspended thread"); + } + + // + // At this point, all of the child threads are running + // and we can get to meat of the test: + // + // - suspended threadLock waiter (trying to reenter) + // - a threadLock enter in the resumer thread + // - resumption of the waiter thread + // - a threadLock enter in the freshly resumed waiter thread + // + barrierResumerNotify(); + + shutDown(waiter ,resumer); + checkTestState(TS_WAITER_DONE); + } + + System.out.println("Executed " + count + " loops in " + timeMax + + " seconds."); + + return 0; + } +} diff --git a/test/hotspot/jtreg/serviceability/jvmti/SuspendWithObjectMonitorWait/SuspendWithObjectMonitorWaitReentryPartFirst.java b/test/hotspot/jtreg/serviceability/jvmti/SuspendWithObjectMonitorWait/SuspendWithObjectMonitorWaitReentryPartFirst.java new file mode 100644 index 00000000000..b331b338f47 --- /dev/null +++ b/test/hotspot/jtreg/serviceability/jvmti/SuspendWithObjectMonitorWait/SuspendWithObjectMonitorWaitReentryPartFirst.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2001, 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4413752 8262881 + * @summary Test SuspendThread with ObjectMonitor wait. + * @requires vm.jvmti + * @library /test/lib + * @compile SuspendWithObjectMonitorWaitReentryPartFirst.java + * @run main/othervm/native -agentlib:SuspendWithObjectMonitorWait SuspendWithObjectMonitorWaitReentryPartFirst 2 + */ + +import java.io.PrintStream; + +// +// SuspendWithObjectMonitorWaitReentryPartFirst algorithm: +// +// main waiter resumer +// ================= ================== =================== +// launch waiter +// waiter running +// launch resumer enter threadLock +// threadLock.wait() resumer running +// enter threadLock : wait for notify +// threadLock.notify wait finishes : +// : reenter blocks : +// suspend waiter : +// : : +// : : : +// notify resumer : wait finishes +// delay 1-second : : +// exit threadLock : : +// join resumer : enter threadLock +// : resume waiter +// : : exit threadLock +// : reenter threadLock : +// : resumer exits +// join waiter : +// waiter exits +// +// Note: The sleep(1-second) in main along with the delayed exit +// of threadLock in main forces the resumer thread to reach +// "enter threadLock" and block. This difference from the default scenario +// forces the resumer thread to be contending for threadLock +// while the waiter thread is in threadLock.wait() increasing +// stress on the monitor sub-system. +// + +public class SuspendWithObjectMonitorWaitReentryPartFirst extends SuspendWithObjectMonitorWaitBase { + + @Override + public int run(int timeMax, PrintStream out) { + return doWork2(timeMax, out); + } + + // Notify the resumer while holding the threadLock. + public int doWork2(int timeMax, PrintStream out) { + SuspendWithObjectMonitorWaitWorker waiter; // waiter thread + SuspendWithObjectMonitorWaitWorker resumer; // resumer thread + + System.out.println("Test 2: About to execute for " + timeMax + " seconds."); + + long start_time = System.currentTimeMillis(); + while (System.currentTimeMillis() < start_time + (timeMax * 1000)) { + count++; + testState = TS_INIT; // starting the test loop + + // launch the waiter thread + waiter = launchWaiter(0); + + // launch the resumer thread + resumer = launchResumer(waiter); + + checkTestState(TS_RESUMER_RUNNING); + + // The waiter thread was synchronized on threadLock before it + // set TS_WAITER_RUNNING and notified barrierLaunch above so + // we cannot enter threadLock until the waiter thread calls + // threadLock.wait(). + synchronized (threadLock) { + // notify waiter thread so it can try to reenter threadLock + testState = TS_READY_TO_NOTIFY; + threadLock.notify(); + + // wait for the waiter thread to block + logDebug("before contended enter wait"); + int retCode = wait4ContendedEnter(waiter); + if (retCode != 0) { + throw new RuntimeException("error in JVMTI GetThreadState: " + + "retCode=" + retCode); + } + logDebug("done contended enter wait"); + + checkTestState(TS_READY_TO_NOTIFY); + testState = TS_CALL_SUSPEND; + logDebug("before suspend thread"); + retCode = suspendThread(waiter); + if (retCode != 0) { + throw new RuntimeException("error in JVMTI SuspendThread: " + + "retCode=" + retCode); + } + logDebug("suspended thread"); + + // + // At this point, all of the child threads are running + // and we can get to meat of the test: + // + // - suspended threadLock waiter (trying to reenter) + // - a blocked threadLock enter in the resumer thread while the + // threadLock is held by the main thread. + // - resumption of the waiter thread + // - a threadLock enter in the freshly resumed waiter thread + // + barrierResumerNotify(); + try { + // Delay for 1-second while holding the threadLock to force the + // resumer thread to block on entering the threadLock. + Thread.sleep(1000); + } catch (Exception e) {} + } + + shutDown(waiter ,resumer); + checkTestState(TS_WAITER_DONE); + } + + System.out.println("Executed " + count + " loops in " + timeMax + + " seconds."); + + return 0; + } +} diff --git a/test/hotspot/jtreg/serviceability/jvmti/SuspendWithObjectMonitorWait/SuspendWithObjectMonitorWaitReentryPartSecond.java b/test/hotspot/jtreg/serviceability/jvmti/SuspendWithObjectMonitorWait/SuspendWithObjectMonitorWaitReentryPartSecond.java new file mode 100644 index 00000000000..92ab5a88eb6 --- /dev/null +++ b/test/hotspot/jtreg/serviceability/jvmti/SuspendWithObjectMonitorWait/SuspendWithObjectMonitorWaitReentryPartSecond.java @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2001, 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4413752 8262881 + * @summary Test SuspendThread with ObjectMonitor wait. + * @requires vm.jvmti + * @library /test/lib + * @compile SuspendWithObjectMonitorWaitReentryPartSecond.java + * @run main/othervm/native -agentlib:SuspendWithObjectMonitorWait SuspendWithObjectMonitorWaitReentryPartSecond 3 + */ + +import java.io.PrintStream; + +// +// SuspendWithObjectMonitorWaitReentryPartSecond algorithm: +// +// main waiter resumer +// =================== ====================== =================== +// launch waiter +// waiter running +// launch resumer enter threadLock +// while !READY_TO_NOTIFY resumer running +// : threadLock.wait(1) wait for notify +// enter threadLock : : +// set READY_TO_NOTIFY : +// threadLock.notify wait finishes : +// : delay 200ms reenter blocks : +// suspend waiter : +// : : +// : : : +// notify resumer : wait finishes +// delay 1-second : : +// exit threadLock : : +// join resumer : enter threadLock +// : resume waiter +// : : exit threadLock +// : reenter threadLock : +// : resumer exits +// join waiter : +// waiter exits +// +// Note: The sleep(1-second) in main along with the delayed exit +// of threadLock in main forces the resumer thread to reach +// "enter threadLock" and block. This difference from the default scenario +// forces the resumer thread to be contending for threadLock +// while the waiter thread is in the threadLock.wait(1) tight +// loop increasing stress on the monitor sub-system. +// +// Note: sleep(200ms) here while holding the threadLock to allow the +// waiter thread's timed wait to finish before we attempt to +// suspend the waiter thread. +// + +public class SuspendWithObjectMonitorWaitReentryPartSecond extends SuspendWithObjectMonitorWaitBase { + + @Override + public int run(int timeMax, PrintStream out) { + return doWork3(timeMax, out); + } + + // Suspend on the re-entry path of wait. + public int doWork3(int timeMax, PrintStream out) { + SuspendWithObjectMonitorWaitWorker waiter; // waiter thread + SuspendWithObjectMonitorWaitWorker resumer; // resumer thread + + System.out.println("Test 3: About to execute for " + timeMax + " seconds."); + + long start_time = System.currentTimeMillis(); + while (System.currentTimeMillis() < start_time + (timeMax * 1000)) { + count++; + testState = TS_INIT; // starting the test loop + + // launch the waiter thread + waiter = launchWaiter(100); + + // launch the resumer thread + resumer = launchResumer(waiter); + + checkTestState(TS_RESUMER_RUNNING); + + // The waiter thread was synchronized on threadLock before it + // set TS_WAITER_RUNNING and notified barrierLaunch above so + // we cannot enter threadLock until the waiter thread calls + // threadLock.wait(). + synchronized (threadLock) { + // notify waiter thread so it can try to reenter threadLock + testState = TS_READY_TO_NOTIFY; + threadLock.notify(); + + try { + Thread.sleep(200); + } catch (Exception e) {} + + // wait for the waiter thread to block + logDebug("before contended enter wait"); + int retCode = wait4ContendedEnter(waiter); + if (retCode != 0) { + throw new RuntimeException("error in JVMTI GetThreadState: " + + "retCode=" + retCode); + } + logDebug("done contended enter wait"); + + checkTestState(TS_READY_TO_NOTIFY); + testState = TS_CALL_SUSPEND; + logDebug("before suspend thread"); + retCode = suspendThread(waiter); + if (retCode != 0) { + throw new RuntimeException("error in JVMTI SuspendThread: " + + "retCode=" + retCode); + } + logDebug("suspended thread"); + + // + // At this point, all of the child threads are running + // and we can get to meat of the test: + // + // - suspended threadLock waiter (trying to reenter) + // - a blocked threadLock enter in the resumer thread while the + // threadLock is held by the main thread. + // - resumption of the waiter thread + // - a threadLock enter in the freshly resumed waiter thread + // + barrierResumerNotify(); + try { + // Delay for 1-second while holding the threadLock to force the + // resumer thread to block on entering the threadLock. + Thread.sleep(1000); + } catch (Exception e) {} + } + + shutDown(waiter ,resumer); + checkTestState(TS_WAITER_DONE); + } + + System.out.println("Executed " + count + " loops in " + timeMax + + " seconds."); + + return 0; + } +} diff --git a/test/hotspot/jtreg/serviceability/jvmti/SuspendWithObjectMonitorWait/SuspendWithObjectMonitorWaitWorker.java b/test/hotspot/jtreg/serviceability/jvmti/SuspendWithObjectMonitorWait/SuspendWithObjectMonitorWaitWorker.java new file mode 100644 index 00000000000..2bf41168d5a --- /dev/null +++ b/test/hotspot/jtreg/serviceability/jvmti/SuspendWithObjectMonitorWait/SuspendWithObjectMonitorWaitWorker.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2001, 2026, Oracle and/or its affiliates. All rights reserved. + * 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. + */ + +public class SuspendWithObjectMonitorWaitWorker extends Thread { + private SuspendWithObjectMonitorWaitWorker target; // target for resume operation + private final long waitTimeout; + + public SuspendWithObjectMonitorWaitWorker(String name, long waitTimeout) { + super(name); + this.waitTimeout = waitTimeout; + } + + public SuspendWithObjectMonitorWaitWorker(String name, SuspendWithObjectMonitorWaitWorker target) { + super(name); + this.target = target; + this.waitTimeout = 0; + } + + native static int resumeThread(SuspendWithObjectMonitorWaitWorker thr); + + public void run() { + SuspendWithObjectMonitorWaitBase.logDebug("thread running"); + + // + // Launch the waiter thread: + // - grab the threadLock + // - threadLock.wait() + // - releases threadLock + // + if (getName().equals("waiter")) { + // grab threadLock before we tell main we are running + SuspendWithObjectMonitorWaitBase.logDebug("before enter threadLock"); + synchronized(SuspendWithObjectMonitorWaitBase.threadLock) { + SuspendWithObjectMonitorWaitBase.logDebug("enter threadLock"); + + SuspendWithObjectMonitorWaitBase.checkTestState(SuspendWithObjectMonitorWaitBase.TS_INIT); + + synchronized(SuspendWithObjectMonitorWaitBase.barrierLaunch) { + // tell main we are running + SuspendWithObjectMonitorWaitBase.testState = SuspendWithObjectMonitorWaitBase.TS_WAITER_RUNNING; + SuspendWithObjectMonitorWaitBase.barrierLaunch.notify(); + } + + SuspendWithObjectMonitorWaitBase.logDebug("before wait"); + + // TS_READY_TO_NOTIFY is set after the main thread has + // entered threadLock so a spurious wakeup can't get the + // waiter thread out of this threadLock.wait(0) call: + while (SuspendWithObjectMonitorWaitBase.testState <= SuspendWithObjectMonitorWaitBase.TS_READY_TO_NOTIFY) { + try { + SuspendWithObjectMonitorWaitBase.threadLock.wait(waitTimeout); + } catch (InterruptedException ex) { + } + } + + SuspendWithObjectMonitorWaitBase.logDebug("after wait"); + + SuspendWithObjectMonitorWaitBase.checkTestState(SuspendWithObjectMonitorWaitBase.TS_CALL_RESUME); + SuspendWithObjectMonitorWaitBase.testState = SuspendWithObjectMonitorWaitBase.TS_WAITER_DONE; + + SuspendWithObjectMonitorWaitBase.logDebug("exit threadLock"); + } + } + // + // Launch the resumer thread: + // - tries to grab the threadLock (should not block with doWork1!) + // - grabs threadLock + // - resumes the waiter thread + // - releases threadLock + // + else if (getName().equals("resumer")) { + synchronized(SuspendWithObjectMonitorWaitBase.barrierResumer) { + synchronized(SuspendWithObjectMonitorWaitBase.barrierLaunch) { + // tell main we are running + SuspendWithObjectMonitorWaitBase.testState = SuspendWithObjectMonitorWaitBase.TS_RESUMER_RUNNING; + SuspendWithObjectMonitorWaitBase.barrierLaunch.notify(); + } + SuspendWithObjectMonitorWaitBase.logDebug("thread waiting"); + while (SuspendWithObjectMonitorWaitBase.testState != SuspendWithObjectMonitorWaitBase.TS_READY_TO_RESUME) { + try { + // wait for main to tell us when to continue + SuspendWithObjectMonitorWaitBase.barrierResumer.wait(0); + } catch (InterruptedException ex) { + } + } + } + + SuspendWithObjectMonitorWaitBase.logDebug("before enter threadLock"); + synchronized(SuspendWithObjectMonitorWaitBase.threadLock) { + SuspendWithObjectMonitorWaitBase.logDebug("enter threadLock"); + + SuspendWithObjectMonitorWaitBase.checkTestState(SuspendWithObjectMonitorWaitBase.TS_READY_TO_RESUME); + SuspendWithObjectMonitorWaitBase.testState = SuspendWithObjectMonitorWaitBase.TS_CALL_RESUME; + + // resume the waiter thread so waiter.join() can work + SuspendWithObjectMonitorWaitBase.logDebug("before resume thread"); + int retCode = resumeThread(target); + if (retCode != 0) { + throw new RuntimeException("error in JVMTI ResumeThread: " + + "retCode=" + retCode); + } + SuspendWithObjectMonitorWaitBase.logDebug("resumed thread"); + + SuspendWithObjectMonitorWaitBase.logDebug("exit threadLock"); + } + } + } +} diff --git a/test/hotspot/jtreg/serviceability/jvmti/SuspendWithObjectMonitorWait/libSuspendWithObjectMonitorWait.cpp b/test/hotspot/jtreg/serviceability/jvmti/SuspendWithObjectMonitorWait/libSuspendWithObjectMonitorWait.cpp index 3706cba76dc..bea70c4925f 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/SuspendWithObjectMonitorWait/libSuspendWithObjectMonitorWait.cpp +++ b/test/hotspot/jtreg/serviceability/jvmti/SuspendWithObjectMonitorWait/libSuspendWithObjectMonitorWait.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 +36,7 @@ static jvmtiEnv* jvmti = nullptr; } while (0) JNIEXPORT int JNICALL -Java_SuspendWithObjectMonitorWait_suspendThread(JNIEnv *jni, jclass cls, jthread thr) { +Java_SuspendWithObjectMonitorWaitBase_suspendThread(JNIEnv *jni, jclass cls, jthread thr) { return jvmti->SuspendThread(thr); } @@ -46,7 +46,7 @@ Java_SuspendWithObjectMonitorWaitWorker_resumeThread(JNIEnv *jni, jclass cls, jt } JNIEXPORT jint JNICALL -Java_SuspendWithObjectMonitorWait_wait4ContendedEnter(JNIEnv *jni, jclass cls, jthread thr) { +Java_SuspendWithObjectMonitorWaitBase_wait4ContendedEnter(JNIEnv *jni, jclass cls, jthread thr) { jvmtiError err; jint thread_state; do { diff --git a/test/hotspot/jtreg/serviceability/sa/ClhsdbInspect.java b/test/hotspot/jtreg/serviceability/sa/ClhsdbInspect.java index e7531226d2d..553706e502d 100644 --- a/test/hotspot/jtreg/serviceability/sa/ClhsdbInspect.java +++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbInspect.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,7 @@ public class ClhsdbInspect { System.out.println("Started LingeredApp with pid " + theApp.getPid()); // Run the 'jstack -v' command to get the address of a Method*, - // the oop address of a java.lang.ref.ReferenceQueue$Lock + // the oop address of a LingeredAppWithLock$NestedLock // and the oop address of a java.lang.Class object List cmds = List.of("jstack -v"); @@ -63,8 +63,8 @@ public class ClhsdbInspect { tokensMap.put("(a java.lang.Class for LingeredAppWithLock)", "instance of Oop for java/lang/Class"); tokensMap.put("Method*=", "Type is Method"); - tokensMap.put("(a java.lang.ref.ReferenceQueue$Lock)", - "instance of Oop for java/lang/ref/ReferenceQueue\\$Lock"); + tokensMap.put("(a LingeredAppWithLock$NestedLock)", + "instance of Oop for LingeredAppWithLock\\$NestedLock"); String[] lines = jstackOutput.split("\\R"); diff --git a/test/hotspot/jtreg/serviceability/sa/LingeredAppWithLock.java b/test/hotspot/jtreg/serviceability/sa/LingeredAppWithLock.java index 4319d576590..9a51aef75ce 100644 --- a/test/hotspot/jtreg/serviceability/sa/LingeredAppWithLock.java +++ b/test/hotspot/jtreg/serviceability/sa/LingeredAppWithLock.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * 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,8 @@ import jdk.test.lib.apps.LingeredApp; public class LingeredAppWithLock extends LingeredApp { private static Object lockObj = new Object(); + private static class NestedLock {} + public static void lockMethod(Object lock) { synchronized (lock) { try { @@ -50,12 +52,14 @@ public class LingeredAppWithLock extends LingeredApp { public static void main(String args[]) { Thread classLock1 = new Thread(() -> lockMethod(LingeredAppWithLock.class)); Thread classLock2 = new Thread(() -> lockMethod(LingeredAppWithLock.class)); + Thread nestedClassLock = new Thread(() -> lockMethod(new NestedLock())); Thread objectLock = new Thread(() -> lockMethod(classLock1)); Thread primitiveLock = new Thread(() -> lockMethod(int.class)); Thread objectWait = new Thread(() -> waitMethod()); classLock1.start(); classLock2.start(); + nestedClassLock.start(); objectLock.start(); primitiveLock.start(); objectWait.start(); @@ -65,6 +69,8 @@ public class LingeredAppWithLock extends LingeredApp { classLock1.getState() != Thread.State.TIMED_WAITING) || (classLock2.getState() != Thread.State.BLOCKED && classLock2.getState() != Thread.State.TIMED_WAITING) || + (nestedClassLock.getState() != Thread.State.BLOCKED && + nestedClassLock.getState() != Thread.State.TIMED_WAITING) || (objectLock.getState() != Thread.State.TIMED_WAITING) || (primitiveLock.getState() != Thread.State.TIMED_WAITING) || (objectWait.getState() != Thread.State.TIMED_WAITING)) { diff --git a/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackMixedCore.java b/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackMixedCore.java new file mode 100644 index 00000000000..d781e8c5c09 --- /dev/null +++ b/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackMixedCore.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2026, NTT DATA + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import jtreg.SkippedException; + +import jdk.test.lib.JDKToolFinder; +import jdk.test.lib.JDKToolLauncher; +import jdk.test.lib.Platform; +import jdk.test.lib.SA.SATestUtils; +import jdk.test.lib.Utils; +import jdk.test.lib.apps.LingeredApp; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.util.CoreUtils; + +import jtreg.SkippedException; + +/** + * @test + * @bug 8374482 8376264 8376284 + * @requires (os.family == "linux") & (vm.hasSA) + * @requires os.arch == "amd64" + * @library /test/lib + * @run driver TestJhsdbJstackMixedCore + */ +public class TestJhsdbJstackMixedCore { + + private static void runJstackMixed(String coreFileName) throws Exception { + JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jhsdb"); + launcher.addVMArgs(Utils.getTestJavaOpts()); + launcher.addToolArg("jstack"); + launcher.addToolArg("--mixed"); + launcher.addToolArg("--exe"); + launcher.addToolArg(JDKToolFinder.getTestJDKTool("java")); + launcher.addToolArg("--core"); + launcher.addToolArg(coreFileName); + + ProcessBuilder pb = SATestUtils.createProcessBuilder(launcher); + Process jhsdb = pb.start(); + OutputAnalyzer out = new OutputAnalyzer(jhsdb); + + jhsdb.waitFor(); + + System.out.println(out.getStdout()); + System.err.println(out.getStderr()); + + out.shouldContain("__restore_rt "); + out.shouldContain("Java_jdk_test_lib_apps_LingeredApp_crash"); + out.shouldContain("* jdk.test.lib.apps.LingeredApp.crash()"); + } + + public static void main(String... args) throws Throwable { + if (Platform.isMusl()) { + throw new SkippedException("This test does not work on musl libc."); + } + + // Check whether the symbol of signal trampoline is available. + var libc = SATestUtils.getLibCPath(); + + // SA distinguishes the frame is signal trampoline if the function + // is named "__restore_rt". + // SA cannot unwind problematic frame from it if the symbol not found. + if (!SATestUtils.isSymbolAvailable(libc, "__restore_rt")) { + throw new SkippedException("Signal trampoline (__restore_rt) not found in libc."); + } + + LingeredApp app = new LingeredApp(); + app.setForceCrash(true); + LingeredApp.startApp(app, CoreUtils.getAlwaysPretouchArg(true)); + app.waitAppTerminate(); + + String crashOutput = app.getOutput().getStdout(); + String coreFileName = CoreUtils.getCoreFileLocation(crashOutput, app.getPid()); + runJstackMixed(coreFileName); + } +} diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestBadFormat.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestBadFormat.java index 200866375af..da8fd6489b8 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestBadFormat.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestBadFormat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -276,9 +276,10 @@ class BadArgumentsAnnotation { } } +// Since all the methods are failing, the class doesn't specify any @Test methods, which is another failure. +@ClassFail class BadOverloadedMethod { - @FailCount(0) // Combined with both sameName() below @Test public void sameName() {} diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestBasics.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestBasics.java index b5006290047..8efdcb4f021 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestBasics.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestBasics.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,8 @@ import compiler.lib.ir_framework.test.TestVM; import java.lang.reflect.Method; import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; import java.util.stream.Stream; /* @@ -44,7 +46,7 @@ import java.util.stream.Stream; public class TestBasics { private static boolean wasExecuted = false; private boolean lastToggleBoolean = true; - private final static int[] executed = new int[100]; + private final static HashMap executed = HashMap.newHashMap(100); private final static int[] executedOnce = new int[5]; private long[] nonFloatingRandomNumbers = new long[10]; private double[] floatingRandomNumbers = new double[10]; @@ -60,12 +62,12 @@ public class TestBasics { if (wasExecuted) { throw new RuntimeException("Executed non @Test method or a method that was not intended to be run"); } - for (int i = 0; i < executed.length; i++) { - int value = executed[i]; + for (Map.Entry entry : executed.entrySet()) { + int value = entry.getValue(); if (value != TestVM.WARMUP_ITERATIONS + 1) { // Warmups + 1 C2 compiled invocation - throw new RuntimeException("Test " + i + " was executed " + value + " times instead stead of " - + (TestVM.WARMUP_ITERATIONS + 1) + " times." ); + throw new RuntimeException("Test " + entry.getKey() + " was executed " + value + " times instead stead of " + + (TestVM.WARMUP_ITERATIONS + 1) + " times." ); } } @@ -88,12 +90,6 @@ public class TestBasics { randomBooleans = new Boolean[64]; } - // Base test, no arguments, directly invoked. - @Test - public void test() { - executed[0]++; - } - // Not a test public void noTest() { wasExecuted = true; @@ -109,24 +105,19 @@ public class TestBasics { wasExecuted = true; } - // Can overload a @Test if it is not a @Test itself. - public static void test(double i) { - wasExecuted = true; - } - @Test public static void staticTest() { - executed[1]++; + executed.merge("staticTest", 1, Integer::sum); } @Test public final void finalTest() { - executed[2]++; + executed.merge("finalTest", 1, Integer::sum); } @Test public int returnValueTest() { - executed[3]++; + executed.merge("returnValueTest", 1, Integer::sum); return 4; } @@ -135,7 +126,7 @@ public class TestBasics { @Test @Arguments(values = Argument.DEFAULT) public void byteDefaultArgument(byte x) { - executed[4]++; + executed.merge("byteDefaultArgument", 1, Integer::sum); if (x != 0) { throw new RuntimeException("Must be 0"); } @@ -144,7 +135,7 @@ public class TestBasics { @Test @Arguments(values = Argument.DEFAULT) public void shortDefaultArgument(short x) { - executed[5]++; + executed.merge("shortDefaultArgument", 1, Integer::sum); if (x != 0) { throw new RuntimeException("Must be 0"); } @@ -153,7 +144,7 @@ public class TestBasics { @Test @Arguments(values = Argument.DEFAULT) public void intDefaultArgument(int x) { - executed[6]++; + executed.merge("intDefaultArgument", 1, Integer::sum); if (x != 0) { throw new RuntimeException("Must be 0"); } @@ -162,7 +153,7 @@ public class TestBasics { @Test @Arguments(values = Argument.DEFAULT) public void longDefaultArgument(long x) { - executed[7]++; + executed.merge("longDefaultArgument", 1, Integer::sum); if (x != 0L) { throw new RuntimeException("Must be 0"); } @@ -171,7 +162,7 @@ public class TestBasics { @Test @Arguments(values = Argument.DEFAULT) public void floatDefaultArgument(float x) { - executed[8]++; + executed.merge("floatDefaultArgument", 1, Integer::sum); if (x != 0.0f) { throw new RuntimeException("Must be 0.0"); } @@ -180,7 +171,7 @@ public class TestBasics { @Test @Arguments(values = Argument.DEFAULT) public void doubleDefaultArgument(double x) { - executed[9]++; + executed.merge("doubleDefaultArgument", 1, Integer::sum); if (x != 0.0f) { throw new RuntimeException("Must be 0.0"); } @@ -189,7 +180,7 @@ public class TestBasics { @Test @Arguments(values = Argument.DEFAULT) public void charDefaultArgument(char x) { - executed[10]++; + executed.merge("charDefaultArgument", 1, Integer::sum); if (x != '\u0000') { throw new RuntimeException("Must be \u0000"); } @@ -198,7 +189,7 @@ public class TestBasics { @Test @Arguments(values = Argument.DEFAULT) public void booleanDefaultArgument(boolean x) { - executed[11]++; + executed.merge("booleanDefaultArgument", 1, Integer::sum); if (x) { throw new RuntimeException("Must be false"); } @@ -207,7 +198,7 @@ public class TestBasics { @Test @Arguments(values = Argument.DEFAULT) public void stringObjectDefaultArgument(String x) { - executed[12]++; + executed.merge("stringObjectDefaultArgument", 1, Integer::sum); if (x == null || x.length() != 0) { throw new RuntimeException("Default string object must be non-null and having a length of zero"); } @@ -216,7 +207,7 @@ public class TestBasics { @Test @Arguments(values = Argument.DEFAULT) public void defaultObjectDefaultArgument(DefaultObject x) { - executed[13]++; + executed.merge("defaultObjectDefaultArgument", 1, Integer::sum); if (x == null || x.i != 4) { throw new RuntimeException("Default object must not be null and its i field must be 4"); } @@ -225,7 +216,7 @@ public class TestBasics { @Test @Arguments(values = Argument.NUMBER_42) public void byte42(byte x) { - executed[14]++; + executed.merge("byte42", 1, Integer::sum); if (x != 42) { throw new RuntimeException("Must be 42"); } @@ -234,7 +225,7 @@ public class TestBasics { @Test @Arguments(values = Argument.NUMBER_42) public void short42(short x) { - executed[15]++; + executed.merge("short42", 1, Integer::sum); if (x != 42) { throw new RuntimeException("Must be 42"); } @@ -243,7 +234,7 @@ public class TestBasics { @Test @Arguments(values = Argument.NUMBER_42) public void int42(int x) { - executed[16]++; + executed.merge("int42", 1, Integer::sum); if (x != 42) { throw new RuntimeException("Must be 42"); } @@ -252,7 +243,7 @@ public class TestBasics { @Test @Arguments(values = Argument.NUMBER_42) public void long42(long x) { - executed[17]++; + executed.merge("long42", 1, Integer::sum); if (x != 42) { throw new RuntimeException("Must be 42"); } @@ -261,7 +252,7 @@ public class TestBasics { @Test @Arguments(values = Argument.NUMBER_42) public void float42(float x) { - executed[18]++; + executed.merge("float42", 1, Integer::sum); if (x != 42.0) { throw new RuntimeException("Must be 42"); } @@ -270,7 +261,7 @@ public class TestBasics { @Test @Arguments(values = Argument.NUMBER_42) public void double42(double x) { - executed[19]++; + executed.merge("double42", 1, Integer::sum); if (x != 42.0) { throw new RuntimeException("Must be 42"); } @@ -279,7 +270,7 @@ public class TestBasics { @Test @Arguments(values = Argument.FALSE) public void booleanFalse(boolean x) { - executed[20]++; + executed.merge("booleanFalse", 1, Integer::sum); if (x) { throw new RuntimeException("Must be false"); } @@ -288,7 +279,7 @@ public class TestBasics { @Test @Arguments(values = Argument.TRUE) public void booleanTrue(boolean x) { - executed[21]++; + executed.merge("booleanTrue", 1, Integer::sum); if (!x) { throw new RuntimeException("Must be true"); } @@ -297,37 +288,37 @@ public class TestBasics { @Test @Arguments(values = Argument.RANDOM_ONCE) public void randomByte(byte x) { - executed[22]++; + executed.merge("randomByte", 1, Integer::sum); } @Test @Arguments(values = Argument.RANDOM_ONCE) public void randomShort(short x) { - executed[23]++; + executed.merge("randomShort", 1, Integer::sum); } @Test @Arguments(values = Argument.RANDOM_ONCE) public void randomInt(int x) { - executed[24]++; + executed.merge("randomInt", 1, Integer::sum); } @Test @Arguments(values = Argument.RANDOM_ONCE) public void randomLong(long x) { - executed[25]++; + executed.merge("randomLong", 1, Integer::sum); } @Test @Arguments(values = Argument.RANDOM_ONCE) public void randomFloat(float x) { - executed[26]++; + executed.merge("randomFloat", 1, Integer::sum); } @Test @Arguments(values = Argument.RANDOM_ONCE) public void randomDouble(double x) { - executed[27]++; + executed.merge("randomDouble", 1, Integer::sum); } // Not executed @@ -338,13 +329,13 @@ public class TestBasics { @Test @Arguments(values = Argument.RANDOM_ONCE) public void randomBoolean(boolean x) { - executed[28]++; + executed.merge("randomBoolean", 1, Integer::sum); } @Test @Arguments(values = Argument.BOOLEAN_TOGGLE_FIRST_FALSE) public void booleanToggleFirstFalse(boolean x) { - if (executed[29] == 0) { + if (!executed.containsKey("booleanToggleFirstFalse")) { // First invocation if (x) { throw new RuntimeException("BOOLEAN_TOGGLE_FIRST_FALSE must be false on first invocation"); @@ -353,63 +344,63 @@ public class TestBasics { throw new RuntimeException("BOOLEAN_TOGGLE_FIRST_FALSE did not toggle"); } lastToggleBoolean = x; - executed[29]++; + executed.merge("booleanToggleFirstFalse", 1, Integer::sum); } @Test @Arguments(values = Argument.RANDOM_EACH) public void randomEachByte(byte x) { - checkNonFloatingRandomNumber(x, executed[30]); - executed[30]++; + checkNonFloatingRandomNumber(x, executed.getOrDefault("randomEachByte", 0)); + executed.merge("randomEachByte", 1, Integer::sum); } @Test @Arguments(values = Argument.RANDOM_EACH) public void randomEachShort(short x) { - checkNonFloatingRandomNumber(x, executed[31]); - executed[31]++; + checkNonFloatingRandomNumber(x, executed.getOrDefault("randomEachShort", 0)); + executed.merge("randomEachShort", 1, Integer::sum); } @Test @Arguments(values = Argument.RANDOM_EACH) public void randomEachInt(int x) { - checkNonFloatingRandomNumber(x, executed[32]); - executed[32]++; + checkNonFloatingRandomNumber(x, executed.getOrDefault("randomEachInt", 0)); + executed.merge("randomEachInt", 1, Integer::sum); } @Test @Arguments(values = Argument.RANDOM_EACH) public void randomEachLong(long x) { - checkNonFloatingRandomNumber(x, executed[33]); - executed[33]++; + checkNonFloatingRandomNumber(x, executed.getOrDefault("randomEachLong", 0)); + executed.merge("randomEachLong", 1, Integer::sum); } @Test @Arguments(values = Argument.RANDOM_EACH) public void randomEachChar(char x) { - checkNonFloatingRandomNumber(x, executed[34]); - executed[34]++; + checkNonFloatingRandomNumber(x, executed.getOrDefault("randomEachChar", 0)); + executed.merge("randomEachChar", 1, Integer::sum); } @Test @Arguments(values = Argument.RANDOM_EACH) public void randomEachFloat(float x) { - checkFloatingRandomNumber(x, executed[35]); - executed[35]++; + checkFloatingRandomNumber(x, executed.getOrDefault("randomEachFloat", 0)); + executed.merge("randomEachFloat", 1, Integer::sum); } @Test @Arguments(values = Argument.RANDOM_EACH) public void randomEachDouble(double x) { - checkFloatingRandomNumber(x, executed[36]); - executed[36]++; + checkFloatingRandomNumber(x, executed.getOrDefault("randomEachDouble", 0)); + executed.merge("randomEachDouble", 1, Integer::sum); } @Test @Arguments(values = Argument.RANDOM_EACH) public void randomEachBoolean(boolean x) { - checkRandomBoolean(x, executed[37]); - executed[37]++; + checkRandomBoolean(x, executed.getOrDefault("randomEachBoolean", 0)); + executed.merge("randomEachBoolean", 1, Integer::sum); } private void checkNonFloatingRandomNumber(long x, int invocationCount) { @@ -461,7 +452,7 @@ public class TestBasics { @Test @Arguments(values = Argument.NUMBER_MINUS_42) public void byteMinus42(byte x) { - executed[38]++; + executed.merge("byteMinus42", 1, Integer::sum); if (x != -42) { throw new RuntimeException("Must be -42"); } @@ -470,7 +461,7 @@ public class TestBasics { @Test @Arguments(values = Argument.NUMBER_MINUS_42) public void shortMinus42(short x) { - executed[39]++; + executed.merge("shortMinus42", 1, Integer::sum); if (x != -42) { throw new RuntimeException("Must be -42"); } @@ -479,7 +470,7 @@ public class TestBasics { @Test @Arguments(values = Argument.NUMBER_MINUS_42) public void intMinus42(int x) { - executed[40]++; + executed.merge("intMinus42", 1, Integer::sum); if (x != -42) { throw new RuntimeException("Must be -42"); } @@ -488,7 +479,7 @@ public class TestBasics { @Test @Arguments(values = Argument.NUMBER_MINUS_42) public void longMinus42(long x) { - executed[41]++; + executed.merge("longMinus42", 1, Integer::sum); if (x != -42) { throw new RuntimeException("Must be -42"); } @@ -497,7 +488,7 @@ public class TestBasics { @Test @Arguments(values = Argument.NUMBER_MINUS_42) public void floatMinus42(float x) { - executed[42]++; + executed.merge("floatMinus42", 1, Integer::sum); if (x != -42.0) { throw new RuntimeException("Must be -42"); } @@ -506,7 +497,7 @@ public class TestBasics { @Test @Arguments(values = Argument.NUMBER_MINUS_42) public void doubleMinus42(double x) { - executed[43]++; + executed.merge("doubleMinus42", 1, Integer::sum); if (x != -42.0) { throw new RuntimeException("Must be -42"); } @@ -515,7 +506,7 @@ public class TestBasics { @Test @Arguments(values = Argument.MIN) public void byteMin(byte x) { - executed[79]++; + executed.merge("byteMin", 1, Integer::sum); if (x != Byte.MIN_VALUE) { throw new RuntimeException("Must be MIN_VALUE"); } @@ -524,7 +515,7 @@ public class TestBasics { @Test @Arguments(values = Argument.MIN) public void charMin(char x) { - executed[80]++; + executed.merge("charMin", 1, Integer::sum); if (x != Character.MIN_VALUE) { throw new RuntimeException("Must be MIN_VALUE"); } @@ -533,7 +524,7 @@ public class TestBasics { @Test @Arguments(values = Argument.MIN) public void shortMin(short x) { - executed[81]++; + executed.merge("shortMin", 1, Integer::sum); if (x != Short.MIN_VALUE) { throw new RuntimeException("Must be MIN_VALUE"); } @@ -542,7 +533,7 @@ public class TestBasics { @Test @Arguments(values = Argument.MIN) public void intMin(int x) { - executed[82]++; + executed.merge("intMin", 1, Integer::sum); if (x != Integer.MIN_VALUE) { throw new RuntimeException("Must be MIN_VALUE"); } @@ -551,7 +542,7 @@ public class TestBasics { @Test @Arguments(values = Argument.MIN) public void longMin(long x) { - executed[83]++; + executed.merge("longMin", 1, Integer::sum); if (x != Long.MIN_VALUE) { throw new RuntimeException("Must be MIN_VALUE"); } @@ -560,7 +551,7 @@ public class TestBasics { @Test @Arguments(values = Argument.MIN) public void floatMin(float x) { - executed[84]++; + executed.merge("floatMin", 1, Integer::sum); if (x != Float.MIN_VALUE) { throw new RuntimeException("Must be MIN_VALUE"); } @@ -569,7 +560,7 @@ public class TestBasics { @Test @Arguments(values = Argument.MIN) public void doubleMin(double x) { - executed[85]++; + executed.merge("doubleMin", 1, Integer::sum); if (x != Double.MIN_VALUE) { throw new RuntimeException("Must be MIN_VALUE"); } @@ -578,7 +569,7 @@ public class TestBasics { @Test @Arguments(values = Argument.MAX) public void byteMax(byte x) { - executed[86]++; + executed.merge("byteMax", 1, Integer::sum); if (x != Byte.MAX_VALUE) { throw new RuntimeException("Must be MAX_VALUE"); } @@ -587,7 +578,7 @@ public class TestBasics { @Test @Arguments(values = Argument.MAX) public void charMax(char x) { - executed[87]++; + executed.merge("charMax", 1, Integer::sum); if (x != Character.MAX_VALUE) { throw new RuntimeException("Must be MAX_VALUE"); } @@ -596,7 +587,7 @@ public class TestBasics { @Test @Arguments(values = Argument.MAX) public void shortMax(short x) { - executed[88]++; + executed.merge("shortMax", 1, Integer::sum); if (x != Short.MAX_VALUE) { throw new RuntimeException("Must be MAX_VALUE"); } @@ -605,7 +596,7 @@ public class TestBasics { @Test @Arguments(values = Argument.MAX) public void intMax(int x) { - executed[89]++; + executed.merge("intMax", 1, Integer::sum); if (x != Integer.MAX_VALUE) { throw new RuntimeException("Must be MAX_VALUE"); } @@ -614,7 +605,7 @@ public class TestBasics { @Test @Arguments(values = Argument.MAX) public void longMax(long x) { - executed[90]++; + executed.merge("longMax", 1, Integer::sum); if (x != Long.MAX_VALUE) { throw new RuntimeException("Must be MAX_VALUE"); } @@ -623,7 +614,7 @@ public class TestBasics { @Test @Arguments(values = Argument.MAX) public void floatMax(float x) { - executed[91]++; + executed.merge("floatMax", 1, Integer::sum); if (x != Float.MAX_VALUE) { throw new RuntimeException("Must be MAX_VALUE"); } @@ -632,7 +623,7 @@ public class TestBasics { @Test @Arguments(values = Argument.MAX) public void doubleMax(double x) { - executed[78]++; + executed.merge("doubleMax", 1, Integer::sum); if (x != Double.MAX_VALUE) { throw new RuntimeException("Must be MAX_VALUE"); } @@ -641,7 +632,7 @@ public class TestBasics { @Test @Arguments(values = {Argument.DEFAULT, Argument.DEFAULT}) public void twoArgsDefault1(byte x, short y) { - executed[44]++; + executed.merge("twoArgsDefault1", 1, Integer::sum); if (x != 0 || y != 0) { throw new RuntimeException("Both must be 0"); } @@ -650,7 +641,7 @@ public class TestBasics { @Test @Arguments(values = {Argument.DEFAULT, Argument.DEFAULT}) public void twoArgsDefault2(int x, short y) { - executed[45]++; + executed.merge("twoArgsDefault2", 1, Integer::sum); if (x != 0 || y != 0) { throw new RuntimeException("Both must be 0"); } @@ -659,7 +650,7 @@ public class TestBasics { @Test @Arguments(values = {Argument.DEFAULT, Argument.DEFAULT}) public void twoArgsDefault3(short x, long y) { - executed[46]++; + executed.merge("twoArgsDefault3", 1, Integer::sum); if (x != 0 || y != 0) { throw new RuntimeException("Both must be 0"); } @@ -668,7 +659,7 @@ public class TestBasics { @Test @Arguments(values = {Argument.DEFAULT, Argument.DEFAULT}) public void twoArgsDefault4(float x, boolean y) { - executed[47]++; + executed.merge("twoArgsDefault4", 1, Integer::sum); if (x != 0.0 || y) { throw new RuntimeException("Must be 0 and false"); } @@ -677,7 +668,7 @@ public class TestBasics { @Test @Arguments(values = {Argument.DEFAULT, Argument.DEFAULT}) public void twoArgsDefault5(boolean x, char y) { - executed[48]++; + executed.merge("twoArgsDefault5", 1, Integer::sum); if (x || y != '\u0000') { throw new RuntimeException("Must be false and \u0000"); } @@ -686,7 +677,7 @@ public class TestBasics { @Test @Arguments(values = {Argument.DEFAULT, Argument.DEFAULT}) public void twoArgsDefault6(char x, byte y) { - executed[49]++; + executed.merge("twoArgsDefault6", 1, Integer::sum); if (x != '\u0000' || y != 0) { throw new RuntimeException("Must be\u0000 and 0"); } @@ -695,7 +686,7 @@ public class TestBasics { @Test @Arguments(values = {Argument.RANDOM_ONCE, Argument.RANDOM_ONCE}) public void twoArgsRandomOnce(char x, byte y) { - executed[50]++; + executed.merge("twoArgsRandomOnce", 1, Integer::sum); } @Test @@ -707,7 +698,7 @@ public class TestBasics { if (Stream.of(a, b, c, d, e, f, g, h).allMatch(i -> i == a)) { throw new RuntimeException("RANDOM_ONCE does not produce random values for different arguments"); } - executed[51]++; + executed.merge("checkRandomOnceDifferentArgs", 1, Integer::sum); } @Test @@ -716,7 +707,7 @@ public class TestBasics { Argument.RANDOM_ONCE, Argument.RANDOM_ONCE, Argument.RANDOM_ONCE, Argument.RANDOM_ONCE}) public void checkMixedRandoms1(byte a, short b, int c, long d, char e, boolean f, float g, double h) { - executed[52]++; + executed.merge("checkMixedRandoms1", 1, Integer::sum); } @Test @@ -725,7 +716,7 @@ public class TestBasics { Argument.RANDOM_EACH, Argument.RANDOM_EACH, Argument.RANDOM_EACH, Argument.RANDOM_EACH}) public void checkMixedRandoms2(byte a, short b, int c, long d, char e, boolean f, float g, double h) { - executed[53]++; + executed.merge("checkMixedRandoms2", 1, Integer::sum); } @Test @@ -734,7 +725,7 @@ public class TestBasics { Argument.RANDOM_ONCE, Argument.RANDOM_EACH, Argument.RANDOM_EACH, Argument.RANDOM_ONCE}) public void checkMixedRandoms3(byte a, short b, int c, long d, char e, boolean f, float g, double h) { - executed[54]++; + executed.merge("checkMixedRandoms3", 1, Integer::sum); } @Test @@ -745,7 +736,7 @@ public class TestBasics { if (a != 42 || b != 42 || c != 42 || d != 42 || e != 42.0 || f != 42.0) { throw new RuntimeException("Must all be 42"); } - executed[55]++; + executed.merge("check42Mix1", 1, Integer::sum); } @Test @@ -756,7 +747,7 @@ public class TestBasics { if (a != -42 || b != -42 || c != -42 || d != -42 || e != -42.0 || f != -42.0) { throw new RuntimeException("Must all be -42"); } - executed[56]++; + executed.merge("check42Mix2", 1, Integer::sum); } @Test @@ -767,14 +758,14 @@ public class TestBasics { if (a != -42 || b != 42 || c != -42 || d != -42 || e != 42.0 || f != -42.0) { throw new RuntimeException("Do not match the right 42 version"); } - executed[57]++; + executed.merge("check42Mix3", 1, Integer::sum); } @Test @Arguments(values = Argument.BOOLEAN_TOGGLE_FIRST_TRUE) public void booleanToggleFirstTrue(boolean x) { - if (executed[58] == 0) { + if (executed.getOrDefault("booleanToggleFirstTrue", 0) == 0) { // First invocation if (!x) { throw new RuntimeException("BOOLEAN_TOGGLE_FIRST_FALSE must be false on first invocation"); @@ -783,13 +774,13 @@ public class TestBasics { throw new RuntimeException("BOOLEAN_TOGGLE_FIRST_FALSE did not toggle"); } lastToggleBoolean = x; - executed[58]++; + executed.merge("booleanToggleFirstTrue", 1, Integer::sum); } @Test @Arguments(values = {Argument.BOOLEAN_TOGGLE_FIRST_FALSE, Argument.BOOLEAN_TOGGLE_FIRST_TRUE}) public void checkTwoToggles(boolean b1, boolean b2) { - if (executed[59] == 0) { + if (executed.getOrDefault("checkTwoToggles", 0) == 0) { // First invocation if (b1 || !b2) { throw new RuntimeException("BOOLEAN_TOGGLES have wrong initial value"); @@ -800,14 +791,14 @@ public class TestBasics { throw new RuntimeException("Booleans did not toggle"); } lastToggleBoolean = b1; - executed[59]++; + executed.merge("checkTwoToggles", 1, Integer::sum); } @Test @Arguments(values = {Argument.BOOLEAN_TOGGLE_FIRST_FALSE, Argument.FALSE, Argument.TRUE, Argument.BOOLEAN_TOGGLE_FIRST_TRUE}) public void booleanMix(boolean b1, boolean b2, boolean b3, boolean b4) { - if (executed[60] == 0) { + if (executed.getOrDefault("booleanMix", 0) == 0) { // First invocation if (b1 || b2 || !b3 || !b4) { throw new RuntimeException("BOOLEAN_TOGGLES have wrong initial value"); @@ -818,7 +809,7 @@ public class TestBasics { throw new RuntimeException("Booleans did not toggle"); } lastToggleBoolean = b1; - executed[60]++; + executed.merge("booleanMix", 1, Integer::sum); } /* @@ -827,19 +818,19 @@ public class TestBasics { @Test public int testCheck() { - executed[63]++; + executed.merge("testCheck", 1, Integer::sum); return 1; } // Checked test. Check invoked after invoking "testCheck". Perform some more things after invocation. @Check(test = "testCheck") public void checkTestCheck() { - executed[64]++; // Executed on each invocation + executed.merge("checkTestCheck", 1, Integer::sum); // Executed on each invocation } @Test public int testCheckReturn() { - executed[65]++; + executed.merge("testCheckReturn", 1, Integer::sum); return 2; } @@ -849,13 +840,13 @@ public class TestBasics { if (returnValue != 2) { throw new RuntimeException("Must be 2"); } - executed[66]++; // Executed on each invocation + executed.merge("checkTestCheckReturn", 1, Integer::sum); // Executed on each invocation } @Test @Arguments(values = Argument.NUMBER_42) public short testCheckWithArgs(short x) { - executed[94]++; + executed.merge("testCheckWithArgs", 1, Integer::sum); return x; } @@ -864,25 +855,25 @@ public class TestBasics { if (returnValue != 42) { throw new RuntimeException("Must be 42"); } - executed[95]++; // Executed on each invocation + executed.merge("checkTestCheckWithArgs", 1, Integer::sum); // Executed on each invocation } @Test public int testCheckTestInfo() { - executed[67]++; + executed.merge("testCheckTestInfo", 1, Integer::sum); return 3; } // Checked test with info object about test. @Check(test = "testCheckTestInfo") public void checkTestCheckTestInfo(TestInfo testInfo) { - executed[68]++; // Executed on each invocation + executed.merge("checkTestCheckTestInfo(TestInfo)", 1, Integer::sum); // Executed on each invocation } @Test public int testCheckBoth() { - executed[69]++; + executed.merge("testCheckBoth", 1, Integer::sum); return 4; } @@ -892,12 +883,12 @@ public class TestBasics { if (returnValue != 4) { throw new RuntimeException("Must be 4"); } - executed[70]++; // Executed on each invocation + executed.merge("checkTestCheckTestInfo(int, TestInfo)", 1, Integer::sum); // Executed on each invocation } @Test public int testCheckOnce() { - executed[71]++; + executed.merge("testCheckOnce", 1, Integer::sum); return 1; } @@ -909,7 +900,7 @@ public class TestBasics { @Test public int testCheckReturnOnce() { - executed[72]++; + executed.merge("testCheckReturnOnce", 1, Integer::sum); return 2; } @@ -923,7 +914,7 @@ public class TestBasics { @Test public int testCheckTestInfoOnce() { - executed[73]++; + executed.merge("testCheckTestInfoOnce", 1, Integer::sum); return 3; } @@ -934,7 +925,7 @@ public class TestBasics { @Test public int testCheckBothOnce() { - executed[74]++; + executed.merge("testCheckBothOnce", 1, Integer::sum); return 4; } @@ -946,42 +937,9 @@ public class TestBasics { executedOnce[3]++; // Executed once } - @Test - public void sameName() { - executed[76]++; - } - - // Allowed to overload test method if not test method itself - public void sameName(boolean a) { - wasExecuted = true; - } - - // Allowed to overload test method if not test method itself - @Check(test = "sameName") - public void sameName(TestInfo info) { - executed[77]++; - } - - - /* - * Custom run tests. - */ - - @Test - public void sameName2() { - executed[92]++; - } - - // Allowed to overload test method if not test method itself - @Run(test = "sameName2") - public void sameName2(RunInfo info) { - executed[93]++; - sameName2(); - } - @Test public void testRun() { - executed[61]++; + executed.merge("testRun", 1, Integer::sum); } // Custom run test. This method is invoked each time instead of @Test method. This method responsible for calling @@ -993,7 +951,7 @@ public class TestBasics { @Test public void testRunNoTestInfo(int i) { // Argument allowed when run by @Run - executed[62]++; + executed.merge("testRunNoTestInfo", 1, Integer::sum); } @Run(test = "testRunNoTestInfo") @@ -1025,7 +983,7 @@ public class TestBasics { @Test public void testRunOnce2() { - executed[75]++; + executed.merge("testRunOnce2", 1, Integer::sum); } @Run(test = "testRunOnce2", mode = RunMode.STANDALONE) @@ -1037,12 +995,12 @@ public class TestBasics { @Test public void testRunMultiple() { - executed[96]++; + executed.merge("testRunMultiple", 1, Integer::sum); } @Test public void testRunMultiple2() { - executed[97]++; + executed.merge("testRunMultiple2", 1, Integer::sum); } @Test @@ -1059,12 +1017,12 @@ public class TestBasics { @Test public void testRunMultiple3() { - executed[98]++; + executed.merge("testRunMultiple3", 1, Integer::sum); } @Test public void testRunMultiple4() { - executed[99]++; + executed.merge("testRunMultiple4", 1, Integer::sum); } @Test diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestCheckedTests.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestCheckedTests.java index 5b7cd3c38a8..d4c12de3e4b 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestCheckedTests.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestCheckedTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -180,6 +180,12 @@ class BadIRAndRuntimeCheckedTests { throw new BadCheckedTestException("expected"); } } + + static class BadCheckedTestException extends RuntimeException { + BadCheckedTestException(String s) { + super(s); + } + } } class BadIRCheckedTests { @@ -224,9 +230,3 @@ class BadIRCheckedTests { } } } - -class BadCheckedTestException extends RuntimeException { - BadCheckedTestException(String s) { - super(s); - } -} diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestCompileThreshold.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestCompileThreshold.java index 7225c7fff07..793ef1ebe34 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestCompileThreshold.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestCompileThreshold.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,7 @@ public class TestCompileThreshold { "-DPreferCommandLineFlags=true"); } catch (IRViolationException e) { Asserts.assertTrue(e.getExceptionInfo().contains("Failed IR Rules (1)"), "exactly one rule failed"); - Asserts.assertTrue(e.getExceptionInfo().contains("testWithCompileThreshold()"), + Asserts.assertTrue(e.getExceptionInfo().contains("testWithCompileThreshold"), "testWithCompileThreshold() failed"); } @@ -59,7 +59,7 @@ public class TestCompileThreshold { "-DTest=testWithoutCompileThreshold"); } catch (IRViolationException e) { Asserts.assertTrue(e.getExceptionInfo().contains("Failed IR Rules (1)"), "exactly one rule failed"); - Asserts.assertTrue(e.getExceptionInfo().contains("testWithoutCompileThreshold()"), + Asserts.assertTrue(e.getExceptionInfo().contains("testWithoutCompileThreshold"), "testWithoutCompileThreshold() failed"); } } diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestControls.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestControls.java index 7fa834b3e55..05b7007c9bd 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestControls.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestControls.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,7 @@ import jdk.test.lib.Asserts; import jdk.test.whitebox.WhiteBox; import java.lang.reflect.Method; +import java.util.HashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -46,7 +47,7 @@ import java.util.regex.Pattern; */ public class TestControls { - static int[] executed = new int[15]; + static HashMap executed = HashMap.newHashMap(15); static boolean wasExecuted = false; static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); @@ -56,31 +57,21 @@ public class TestControls { Method runTestsOnSameVM = TestVM.class.getDeclaredMethod("runTestsOnSameVM", Class.class); runTestsOnSameVM.setAccessible(true); runTestsOnSameVM.invoke(null, new Object[]{ null }); - final int defaultIterations = TestVM.WARMUP_ITERATIONS + 1; - Asserts.assertEQ(executed[0], 1001); - Asserts.assertEQ(executed[1], 101); - Asserts.assertEQ(executed[2], 10000); - Asserts.assertEQ(executed[3], 10000); - Asserts.assertEQ(executed[4], defaultIterations); - Asserts.assertEQ(executed[5], defaultIterations); - Asserts.assertEQ(executed[6], 5001); - Asserts.assertEQ(executed[7], 5001); - Asserts.assertEQ(executed[8], 1); - Asserts.assertEQ(executed[9], 5000); - Asserts.assertEQ(executed[10], 1); - Asserts.assertEQ(executed[11], 2); - Asserts.assertEQ(executed[12], 1); - Asserts.assertEQ(executed[13], 1); + Asserts.assertEQ(executed.get("test1"), 1001); + Asserts.assertEQ(executed.get("test2"), 101); + Asserts.assertEQ(executed.get("testDontCompile"), 10000); + Asserts.assertEQ(executed.get("dontCompile"), 10000); + Asserts.assertEQ(executed.get("testCompileAtLevel1"), 5001); + Asserts.assertEQ(executed.get("dontCompile2"), 5001); + Asserts.assertEQ(executed.get("runTestDontCompile2A"), 1); + Asserts.assertEQ(executed.get("runTestDontCompile2B"), 5000); + Asserts.assertEQ(executed.get("noWarmup"), 1); + Asserts.assertEQ(executed.get("noWarmup2"), 2); + Asserts.assertEQ(executed.get("runNoWarmup2"), 1); + Asserts.assertEQ(executed.get("runTestCompilation"), 1); Asserts.assertFalse(wasExecuted); final long started = System.currentTimeMillis(); long elapsed = 0; - Method overloadDouble = TestControls.class.getDeclaredMethod("overload", double.class); - Method overloadInt = TestControls.class.getDeclaredMethod("overload", int.class); - while (!(TestFramework.isC2Compiled(overloadInt) && TestFramework.isCompiledAtLevel(overloadDouble, CompLevel.C1_LIMITED_PROFILE)) && elapsed < 5000) { - elapsed = System.currentTimeMillis() - started; - } - TestFramework.assertCompiledAtLevel(TestControls.class.getDeclaredMethod("overload", double.class), CompLevel.C1_LIMITED_PROFILE); - TestFramework.assertCompiledByC2(TestControls.class.getDeclaredMethod("overload", int.class)); TestFramework framework = new TestFramework(ClassInitializerTest.class); framework.addFlags("-XX:+PrintCompilation").addHelperClasses(ClassInitializerHelper.class).start(); @@ -99,15 +90,15 @@ public class TestControls { @Test @Warmup(1000) public void test1() { - executed[0]++; + executed.merge("test1", 1, Integer::sum); } @Check(test = "test1") public void check1(TestInfo info) { - if (executed[0] <= 1000) { + if (executed.getOrDefault("test1", 0) <= 1000) { Asserts.assertTrue(info.isWarmUp()); } else { - Asserts.assertTrue(!info.isWarmUp() && executed[0] == 1001); + Asserts.assertTrue(!info.isWarmUp() && executed.getOrDefault("test1", 0) == 1001); TestFramework.assertCompiledByC2(info.getTest()); } } @@ -115,45 +106,23 @@ public class TestControls { @Test @Warmup(100) public void test2() { - executed[1]++; + executed.merge("test2", 1, Integer::sum); } @Check(test = "test2", when = CheckAt.COMPILED) public void check2(TestInfo info) { - Asserts.assertTrue(!info.isWarmUp() && executed[1] == 101); + Asserts.assertTrue(!info.isWarmUp() && executed.getOrDefault("test2", 0) == 101); TestFramework.assertCompiledByC2(info.getTest()); } - @Test - public void overload() { - executed[4]++; - } - - @ForceCompile - @DontInline - public static void overload(int i) { - wasExecuted = true; - } - - @ForceCompile(CompLevel.C1_LIMITED_PROFILE) - @ForceInline - public static void overload(double i) { - wasExecuted = true; - } - - @Check(test = "overload") - public void checkOverload() { - executed[5]++; - } - @Test public void testDontCompile() { - executed[2]++; + executed.merge("testDontCompile", 1, Integer::sum); } @DontCompile public static void dontCompile() { - executed[3]++; + executed.merge("dontCompile", 1, Integer::sum); } @Run(test = "testDontCompile", mode = RunMode.STANDALONE) @@ -167,12 +136,12 @@ public class TestControls { @Test public void testCompileAtLevel1() { - executed[6]++; + executed.merge("testCompileAtLevel1", 1, Integer::sum); } @DontCompile(Compiler.ANY) public static void dontCompile2() { - executed[7]++; + executed.merge("dontCompile2", 1, Integer::sum); } @Run(test = "testCompileAtLevel1") @@ -181,23 +150,23 @@ public class TestControls { dontCompile2(); testCompileAtLevel1(); if (!info.isWarmUp()) { - executed[8]++; + executed.merge("runTestDontCompile2A", 1, Integer::sum); int compLevel = WHITE_BOX.getMethodCompilationLevel(TestControls.class.getDeclaredMethod("dontCompile2"), false); Asserts.assertLessThan(compLevel, CompLevel.C1_LIMITED_PROFILE.getValue()); } else { - executed[9]++; + executed.merge("runTestDontCompile2B", 1, Integer::sum); } } @Test @Warmup(0) public void noWarmup() { - executed[10]++; + executed.merge("noWarmup", 1, Integer::sum); } @Test public void noWarmup2() { - executed[11]++; + executed.merge("noWarmup2", 1, Integer::sum); } @Run(test = "noWarmup2") @@ -206,7 +175,7 @@ public class TestControls { noWarmup2(); noWarmup2(); Asserts.assertTrue(!info.isWarmUp()); - executed[12]++; + executed.merge("runNoWarmup2", 1, Integer::sum); } @Test @@ -301,7 +270,7 @@ public class TestControls { TestFramework.assertCompiledAtLevel(info.getTestClassMethod("forceC1DontC2"), CompLevel.C1_SIMPLE); TestFramework.assertCompiledAtLevel(info.getTestClassMethod("forceC2DontC1"), CompLevel.C2); - executed[13]++; + executed.merge("runTestCompilation", 1, Integer::sum); } } diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestIRMatching.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestIRMatching.java index 07a6a03f2a6..b6881fede75 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestIRMatching.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestIRMatching.java @@ -34,6 +34,7 @@ import java.io.PrintStream; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; /* * @test @@ -72,180 +73,180 @@ public class TestIRMatching { runWithArguments(GoodCount.class, "-XX:TLABRefillWasteFraction=50"); runWithArguments(MultipleFailOnGood.class, "-XX:TLABRefillWasteFraction=50"); - runCheck(new String[] {"-XX:TLABRefillWasteFraction=50", "-XX:+UsePerfData", "-XX:+UseTLAB"}, BadFailOnConstraint.create(AndOr1.class, "test1(int)", 1, "CallStaticJava")); - runCheck(new String[] {"-XX:TLABRefillWasteFraction=50", "-XX:-UsePerfData", "-XX:+UseTLAB"}, BadFailOnConstraint.create(AndOr1.class, "test2()", 1, "CallStaticJava")); + runCheck(new String[] {"-XX:TLABRefillWasteFraction=50", "-XX:+UsePerfData", "-XX:+UseTLAB"}, BadFailOnConstraint.create(AndOr1.class, "test1", 1, "CallStaticJava")); + runCheck(new String[] {"-XX:TLABRefillWasteFraction=50", "-XX:-UsePerfData", "-XX:+UseTLAB"}, BadFailOnConstraint.create(AndOr1.class, "test2", 1, "CallStaticJava")); - runCheck(BadFailOnConstraint.create(MultipleFailOnBad.class, "fail1()", 1, 1, "Store"), - BadFailOnConstraint.create(MultipleFailOnBad.class, "fail1()", 1, 3, "Store"), - GoodFailOnRegexConstraint.create(MultipleFailOnBad.class, "fail1()", 1, 2, 4), - GoodFailOnRegexConstraint.create(MultipleFailOnBad.class, "fail2()", 1, 1), - BadFailOnConstraint.create(MultipleFailOnBad.class, "fail2()", 1, 2, "CallStaticJava"), - BadFailOnConstraint.create(MultipleFailOnBad.class, "fail3()", 1, 2, "Store"), - GoodFailOnRegexConstraint.create(MultipleFailOnBad.class, "fail3()", 1, 1, 3), - BadFailOnConstraint.create(MultipleFailOnBad.class, "fail4()", 1, 1, "Store"), - GoodFailOnRegexConstraint.create(MultipleFailOnBad.class, "fail4()", 1, 2, 3), - BadFailOnConstraint.create(MultipleFailOnBad.class, "fail5()", 1, 1, "Store"), - GoodFailOnRegexConstraint.create(MultipleFailOnBad.class, "fail5()", 1, 2, 3), - GoodFailOnRegexConstraint.create(MultipleFailOnBad.class, "fail6()", 1, 1), - BadFailOnConstraint.create(MultipleFailOnBad.class, "fail6()", 1, 2, "MyClass"), - BadFailOnConstraint.create(MultipleFailOnBad.class, "fail6()", 1, 3, "CallStaticJava"), - GoodFailOnRegexConstraint.create(MultipleFailOnBad.class, "fail7()", 1, 1), - BadFailOnConstraint.create(MultipleFailOnBad.class, "fail7()", 1, 2, "MyClass"), - GoodFailOnRegexConstraint.create(MultipleFailOnBad.class, "fail8()", 1, 1), - BadFailOnConstraint.create(MultipleFailOnBad.class, "fail8()", 1, 2, "MyClass"), - BadFailOnConstraint.create(MultipleFailOnBad.class, "fail9()", 1, 1, "Store"), - BadFailOnConstraint.create(MultipleFailOnBad.class, "fail9()", 1, 2, "CallStaticJava"), - BadFailOnConstraint.create(MultipleFailOnBad.class, "fail10()", 1, 1, "Store", "iFld"), - GoodFailOnRegexConstraint.create(MultipleFailOnBad.class, "fail10()", 1, 2, 3) + runCheck(BadFailOnConstraint.create(MultipleFailOnBad.class, "fail1", 1, 1, "Store"), + BadFailOnConstraint.create(MultipleFailOnBad.class, "fail1", 1, 3, "Store"), + GoodFailOnRegexConstraint.create(MultipleFailOnBad.class, "fail1", 1, 2, 4), + GoodFailOnRegexConstraint.create(MultipleFailOnBad.class, "fail2", 1, 1), + BadFailOnConstraint.create(MultipleFailOnBad.class, "fail2", 1, 2, "CallStaticJava"), + BadFailOnConstraint.create(MultipleFailOnBad.class, "fail3", 1, 2, "Store"), + GoodFailOnRegexConstraint.create(MultipleFailOnBad.class, "fail3", 1, 1, 3), + BadFailOnConstraint.create(MultipleFailOnBad.class, "fail4", 1, 1, "Store"), + GoodFailOnRegexConstraint.create(MultipleFailOnBad.class, "fail4", 1, 2, 3), + BadFailOnConstraint.create(MultipleFailOnBad.class, "fail5", 1, 1, "Store"), + GoodFailOnRegexConstraint.create(MultipleFailOnBad.class, "fail5", 1, 2, 3), + GoodFailOnRegexConstraint.create(MultipleFailOnBad.class, "fail6", 1, 1), + BadFailOnConstraint.create(MultipleFailOnBad.class, "fail6", 1, 2, "MyClass"), + BadFailOnConstraint.create(MultipleFailOnBad.class, "fail6", 1, 3, "CallStaticJava"), + GoodFailOnRegexConstraint.create(MultipleFailOnBad.class, "fail7", 1, 1), + BadFailOnConstraint.create(MultipleFailOnBad.class, "fail7", 1, 2, "MyClass"), + GoodFailOnRegexConstraint.create(MultipleFailOnBad.class, "fail8", 1, 1), + BadFailOnConstraint.create(MultipleFailOnBad.class, "fail8", 1, 2, "MyClass"), + BadFailOnConstraint.create(MultipleFailOnBad.class, "fail9", 1, 1, "Store"), + BadFailOnConstraint.create(MultipleFailOnBad.class, "fail9", 1, 2, "CallStaticJava"), + BadFailOnConstraint.create(MultipleFailOnBad.class, "fail10", 1, 1, "Store", "iFld"), + GoodFailOnRegexConstraint.create(MultipleFailOnBad.class, "fail10", 1, 2, 3) ); - runCheck(BadCountsConstraint.create(BadCount.class, "bad1()", 1, 2, "Load"), - GoodCountsConstraint.create(BadCount.class, "bad1()", 2), - GoodCountsConstraint.create(BadCount.class, "bad2()", 1), - BadCountsConstraint.create(BadCount.class, "bad2()", 2, 2, "Store"), - BadCountsConstraint.create(BadCount.class, "bad3()", 1, 2, "Load"), - BadCountsConstraint.create(BadCount.class, "bad3()", 2, 2, "Store") + runCheck(BadCountsConstraint.create(BadCount.class, "bad1", 1, 2, "Load"), + GoodCountsConstraint.create(BadCount.class, "bad1", 2), + GoodCountsConstraint.create(BadCount.class, "bad2", 1), + BadCountsConstraint.create(BadCount.class, "bad2", 2, 2,"Store"), + BadCountsConstraint.create(BadCount.class, "bad3", 1, 2,"Load"), + BadCountsConstraint.create(BadCount.class, "bad3", 2, 2,"Store") ); - runCheck(GoodRuleConstraint.create(Calls.class, "calls()", 1), - BadFailOnConstraint.create(Calls.class, "calls()", 2, 1, "CallStaticJava", "dontInline"), - BadFailOnConstraint.create(Calls.class, "calls()", 2, 2, "CallStaticJava", "dontInline"), - GoodRuleConstraint.create(Calls.class, "calls()", 3) + runCheck(GoodRuleConstraint.create(Calls.class, "calls", 1), + BadFailOnConstraint.create(Calls.class, "calls", 2, 1, "CallStaticJava", "dontInline"), + BadFailOnConstraint.create(Calls.class, "calls", 2, 2, "CallStaticJava", "dontInline"), + GoodRuleConstraint.create(Calls.class, "calls", 3) ); - runCheck(BadFailOnConstraint.create(AllocInstance.class, "allocInstance()", 1), - BadFailOnConstraint.create(AllocInstance.class, "allocInstance()", 2), - GoodFailOnConstraint.create(AllocInstance.class, "allocInstance()", 3), - GoodFailOnConstraint.create(AllocInstance.class, "allocInstance()", 4), - GoodFailOnConstraint.create(AllocInstance.class, "allocInstance()", 5), - BadFailOnConstraint.create(AllocInstance.class, "allocInstance()", 6), - BadFailOnConstraint.create(AllocInstance.class, "allocInstance()", 7), - GoodFailOnConstraint.create(AllocInstance.class, "allocInstance()", 8), - GoodFailOnConstraint.create(AllocInstance.class, "allocInstance()", 9), - GoodFailOnConstraint.create(AllocInstance.class, "allocInstance()", 10) + runCheck(BadFailOnConstraint.create(AllocInstance.class, "allocInstance", 1), + BadFailOnConstraint.create(AllocInstance.class, "allocInstance", 2), + GoodFailOnConstraint.create(AllocInstance.class, "allocInstance", 3), + GoodFailOnConstraint.create(AllocInstance.class, "allocInstance", 4), + GoodFailOnConstraint.create(AllocInstance.class, "allocInstance", 5), + BadFailOnConstraint.create(AllocInstance.class, "allocInstance", 6), + BadFailOnConstraint.create(AllocInstance.class, "allocInstance", 7), + GoodFailOnConstraint.create(AllocInstance.class, "allocInstance", 8), + GoodFailOnConstraint.create(AllocInstance.class, "allocInstance", 9), + GoodFailOnConstraint.create(AllocInstance.class, "allocInstance", 10) ); runCheck( - BadFailOnConstraint.create(AllocInstance.class, "allocNested()", 1), - BadFailOnConstraint.create(AllocInstance.class, "allocNested()", 2), - BadFailOnConstraint.create(AllocInstance.class, "allocNested()", 3) + BadFailOnConstraint.create(AllocInstance.class, "allocNested", 1), + BadFailOnConstraint.create(AllocInstance.class, "allocNested", 2), + BadFailOnConstraint.create(AllocInstance.class, "allocNested", 3) ); - runCheck(BadFailOnConstraint.create(AllocArray.class, "allocArray()", 1), - BadFailOnConstraint.create(AllocArray.class, "allocArray()", 2), - GoodFailOnConstraint.create(AllocArray.class, "allocArray()", 3), - GoodFailOnConstraint.create(AllocArray.class, "allocArray()", 4), - GoodFailOnConstraint.create(AllocArray.class, "allocArray()", 5), - BadFailOnConstraint.create(AllocArray.class, "allocArray()", 6), - BadFailOnConstraint.create(AllocArray.class, "allocArray()", 7), - GoodFailOnConstraint.create(AllocArray.class, "allocArray()", 8), - GoodFailOnConstraint.create(AllocArray.class, "allocArray()", 9), - GoodFailOnConstraint.create(AllocArray.class, "allocArray()", 10) + runCheck(BadFailOnConstraint.create(AllocArray.class, "allocArray", 1), + BadFailOnConstraint.create(AllocArray.class, "allocArray", 2), + GoodFailOnConstraint.create(AllocArray.class, "allocArray", 3), + GoodFailOnConstraint.create(AllocArray.class, "allocArray", 4), + GoodFailOnConstraint.create(AllocArray.class, "allocArray", 5), + BadFailOnConstraint.create(AllocArray.class, "allocArray", 6), + BadFailOnConstraint.create(AllocArray.class, "allocArray", 7), + GoodFailOnConstraint.create(AllocArray.class, "allocArray", 8), + GoodFailOnConstraint.create(AllocArray.class, "allocArray", 9), + GoodFailOnConstraint.create(AllocArray.class, "allocArray", 10) ); - runCheck(BadFailOnConstraint.create(AllocArray.class, "allocMultiArray()", 1), - BadFailOnConstraint.create(AllocArray.class, "allocMultiArray()", 2), - GoodFailOnConstraint.create(AllocArray.class, "allocMultiArray()", 3), - GoodFailOnConstraint.create(AllocArray.class, "allocMultiArray()", 4), - GoodFailOnConstraint.create(AllocArray.class, "allocMultiArray()", 5), - BadFailOnConstraint.create(AllocArray.class, "allocMultiArray()", 6), - BadFailOnConstraint.create(AllocArray.class, "allocMultiArray()", 7), - GoodFailOnConstraint.create(AllocArray.class, "allocMultiArray()", 8), - GoodFailOnConstraint.create(AllocArray.class, "allocMultiArray()", 9), - GoodFailOnConstraint.create(AllocArray.class, "allocMultiArray()", 10) + runCheck(BadFailOnConstraint.create(AllocArray.class, "allocMultiArray", 1), + BadFailOnConstraint.create(AllocArray.class, "allocMultiArray", 2), + GoodFailOnConstraint.create(AllocArray.class, "allocMultiArray", 3), + GoodFailOnConstraint.create(AllocArray.class, "allocMultiArray", 4), + GoodFailOnConstraint.create(AllocArray.class, "allocMultiArray", 5), + BadFailOnConstraint.create(AllocArray.class, "allocMultiArray", 6), + BadFailOnConstraint.create(AllocArray.class, "allocMultiArray", 7), + GoodFailOnConstraint.create(AllocArray.class, "allocMultiArray", 8), + GoodFailOnConstraint.create(AllocArray.class, "allocMultiArray", 9), + GoodFailOnConstraint.create(AllocArray.class, "allocMultiArray", 10) ); - runCheck(GoodRuleConstraint.create(RunTests.class, "good1()", 1), - GoodRuleConstraint.create(RunTests.class, "good1()", 2), - GoodRuleConstraint.create(RunTests.class, "good2()", 1), - GoodRuleConstraint.create(RunTests.class, "good2()", 2), - GoodRuleConstraint.create(RunTests.class, "good3(int)", 1), - BadCountsConstraint.create(RunTests.class, "bad1(int)", 1, 0), - BadFailOnConstraint.create(RunTests.class, "bad1(int)", 2, "Load") + runCheck(GoodRuleConstraint.create(RunTests.class, "good1", 1), + GoodRuleConstraint.create(RunTests.class, "good1", 2), + GoodRuleConstraint.create(RunTests.class, "good2", 1), + GoodRuleConstraint.create(RunTests.class, "good2", 2), + GoodRuleConstraint.create(RunTests.class, "good3", 1), + BadCountsConstraint.create(RunTests.class, "bad1", 1, 0), + BadFailOnConstraint.create(RunTests.class, "bad1", 2, "Load") ); runCheck(new String[] {"-XX:+IgnoreUnrecognizedVMOptions", "-XX:-UseCompressedClassPointers"}, - BadFailOnConstraint.create(Loads.class, "load()", 1, 1, "Load"), - BadFailOnConstraint.create(Loads.class, "load()", 1, 3, "LoadI"), - BadCountsConstraint.create(Loads.class, "load()", 1, 1, 0), - BadCountsConstraint.create(Loads.class, "load()", 1, 2, 1,"Load"), - GoodRuleConstraint.create(Loads.class, "load()", 2), - GoodFailOnConstraint.create(Loads.class, "load()", 3), - BadCountsConstraint.create(Loads.class, "load()", 3, 2, 2,"Store"), - BadFailOnConstraint.create(Loads.class, "load()", 4, 2, "Store"), - BadFailOnConstraint.create(Loads.class, "load()", 5, "Load"), - BadFailOnConstraint.create(Loads.class, "load()", 6, "Load"), - BadFailOnConstraint.create(Loads.class, "load()", 7, "Load"), - GoodRuleConstraint.create(Loads.class, "load()", 8), - GoodRuleConstraint.create(Loads.class, "load()", 9), - GoodRuleConstraint.create(Loads.class, "load()", 10), - BadFailOnConstraint.create(Loads.class, "loadKlass()", 1), - BadCountsConstraint.create(Loads.class, "loadKlass()", 2, 2,"Field") + BadFailOnConstraint.create(Loads.class, "load", 1, 1, "Load"), + BadFailOnConstraint.create(Loads.class, "load", 1, 3, "LoadI"), + BadCountsConstraint.create(Loads.class, "load", 1, 1, 0), + BadCountsConstraint.create(Loads.class, "load", 1, 2, 1,"Load"), + GoodRuleConstraint.create(Loads.class, "load", 2), + GoodFailOnConstraint.create(Loads.class, "load", 3), + BadCountsConstraint.create(Loads.class, "load", 3, 2, 2,"Store"), + BadFailOnConstraint.create(Loads.class, "load", 4, 2, "Store"), + BadFailOnConstraint.create(Loads.class, "load", 5, "Load"), + BadFailOnConstraint.create(Loads.class, "load", 6, "Load"), + BadFailOnConstraint.create(Loads.class, "load", 7, "Load"), + GoodRuleConstraint.create(Loads.class, "load", 8), + GoodRuleConstraint.create(Loads.class, "load", 9), + GoodRuleConstraint.create(Loads.class, "load", 10), + BadFailOnConstraint.create(Loads.class, "loadKlass", 1), + BadCountsConstraint.create(Loads.class, "loadKlass", 2, 2,"Field") ); // Loops - runCheck(BadFailOnConstraint.create(Loops.class, "loop()", 1, "Loop"), - GoodRuleConstraint.create(Loops.class, "loop()", 2), - GoodRuleConstraint.create(Loops.class, "loop()", 3), - GoodRuleConstraint.create(Loops.class, "countedLoop()", 1), - BadFailOnConstraint.create(Loops.class, "countedLoop()", 2, "CountedLoop"), - GoodRuleConstraint.create(Loops.class, "countedLoop()", 3), - BadFailOnConstraint.create(Loops.class, "loopAndCountedLoop()", 1, "Loop"), - BadFailOnConstraint.create(Loops.class, "loopAndCountedLoop()", 2, "CountedLoop"), - GoodRuleConstraint.create(Loops.class, "loopAndCountedLoop()", 3), - GoodRuleConstraint.create(Loops.class, "countedLoopMain()", 1), - BadFailOnConstraint.create(Loops.class, "countedLoopMain()", 2, "CountedLoop"), - BadFailOnConstraint.create(Loops.class, "countedLoopMain()", 3, "CountedLoop", "main"), - GoodRuleConstraint.create(Loops.class, "countedLoopUnrolled()", 1), - GoodRuleConstraint.create(Loops.class, "countedLoopUnrolled()", 2), - GoodRuleConstraint.create(Loops.class, "countedLoopUnrolled()", 3) + runCheck(BadFailOnConstraint.create(Loops.class, "loop", 1, "Loop"), + GoodRuleConstraint.create(Loops.class, "loop", 2), + GoodRuleConstraint.create(Loops.class, "loop", 3), + GoodRuleConstraint.create(Loops.class, "countedLoop", 1), + BadFailOnConstraint.create(Loops.class, "countedLoop", 2, "CountedLoop"), + GoodRuleConstraint.create(Loops.class, "countedLoop", 3), + BadFailOnConstraint.create(Loops.class, "loopAndCountedLoop", 1, "Loop"), + BadFailOnConstraint.create(Loops.class, "loopAndCountedLoop", 2, "CountedLoop"), + GoodRuleConstraint.create(Loops.class, "loopAndCountedLoop", 3), + GoodRuleConstraint.create(Loops.class, "countedLoopMain", 1), + BadFailOnConstraint.create(Loops.class, "countedLoopMain", 2, "CountedLoop"), + BadFailOnConstraint.create(Loops.class, "countedLoopMain", 3, "CountedLoop", "main"), + GoodRuleConstraint.create(Loops.class, "countedLoopUnrolled", 1), + GoodRuleConstraint.create(Loops.class, "countedLoopUnrolled", 2), + GoodRuleConstraint.create(Loops.class, "countedLoopUnrolled", 3) ); // Traps - runCheck(GoodRuleConstraint.create(Traps.class, "noTraps()", 1), - BadFailOnConstraint.create(Traps.class, "noTraps()", 2, "Store", "iFld"), - GoodRuleConstraint.create(Traps.class, "noTraps()", 3), - BadFailOnConstraint.create(Traps.class, "predicateTrap()", 1, "CallStaticJava", "uncommon_trap"), - BadFailOnConstraint.create(Traps.class, "predicateTrap()", 2, "CallStaticJava", "uncommon_trap", "predicate"), - GoodRuleConstraint.create(Traps.class, "predicateTrap()", 3), - GoodRuleConstraint.create(Traps.class, "predicateTrap()", 4), - BadFailOnConstraint.create(Traps.class, "nullCheck()", 1, "CallStaticJava", "uncommon_trap"), - BadFailOnConstraint.create(Traps.class, "nullCheck()", 2, "CallStaticJava", "uncommon_trap", "null_check"), - BadFailOnConstraint.create(Traps.class, "nullCheck()", 3, "uncommon_trap", "class_check"), - GoodRuleConstraint.create(Traps.class, "nullCheck()", 4), - BadFailOnConstraint.create(Traps.class, "nullAssert()", 1, "CallStaticJava", "uncommon_trap"), - BadFailOnConstraint.create(Traps.class, "nullAssert()", 2, "CallStaticJava", "uncommon_trap", "null_assert"), - BadFailOnConstraint.create(Traps.class, "nullAssert()", 3, "CallStaticJava", "uncommon_trap", "null_check"), - GoodRuleConstraint.create(Traps.class, "nullAssert()", 4), - BadFailOnConstraint.create(Traps.class, "unstableIf(boolean)", 1, "CallStaticJava", "uncommon_trap"), - BadFailOnConstraint.create(Traps.class, "unstableIf(boolean)", 2, "CallStaticJava", "uncommon_trap", "unstable_if"), - GoodRuleConstraint.create(Traps.class, "unstableIf(boolean)", 3), - BadFailOnConstraint.create(Traps.class, "classCheck()", 1, "CallStaticJava", "uncommon_trap"), - BadFailOnConstraint.create(Traps.class, "classCheck()", 2, "CallStaticJava", "uncommon_trap", "class_check"), - BadFailOnConstraint.create(Traps.class, "classCheck()", 3, "CallStaticJava", "uncommon_trap", "null_check"), - GoodRuleConstraint.create(Traps.class, "classCheck()", 4), - BadFailOnConstraint.create(Traps.class, "rangeCheck()", 1, "CallStaticJava", "uncommon_trap"), - BadFailOnConstraint.create(Traps.class, "rangeCheck()", 2, "CallStaticJava", "uncommon_trap", "range_check"), - BadFailOnConstraint.create(Traps.class, "rangeCheck()", 3, "CallStaticJava", "uncommon_trap", "null_check"), - GoodRuleConstraint.create(Traps.class, "rangeCheck()", 4), - BadFailOnConstraint.create(Traps.class, "instrinsicOrTypeCheckedInlining()", 1, "CallStaticJava", "uncommon_trap"), + runCheck(GoodRuleConstraint.create(Traps.class, "noTraps", 1), + BadFailOnConstraint.create(Traps.class, "noTraps", 2, "Store", "iFld"), + GoodRuleConstraint.create(Traps.class, "noTraps", 3), + BadFailOnConstraint.create(Traps.class, "predicateTrap", 1, "CallStaticJava", "uncommon_trap"), + BadFailOnConstraint.create(Traps.class, "predicateTrap", 2, "CallStaticJava", "uncommon_trap", "predicate"), + GoodRuleConstraint.create(Traps.class, "predicateTrap", 3), + GoodRuleConstraint.create(Traps.class, "predicateTrap", 4), + BadFailOnConstraint.create(Traps.class, "nullCheck", 1, "CallStaticJava", "uncommon_trap"), + BadFailOnConstraint.create(Traps.class, "nullCheck", 2, "CallStaticJava", "uncommon_trap", "null_check"), + BadFailOnConstraint.create(Traps.class, "nullCheck", 3, "uncommon_trap", "class_check"), + GoodRuleConstraint.create(Traps.class, "nullCheck", 4), + BadFailOnConstraint.create(Traps.class, "nullAssert", 1, "CallStaticJava", "uncommon_trap"), + BadFailOnConstraint.create(Traps.class, "nullAssert", 2, "CallStaticJava", "uncommon_trap", "null_assert"), + BadFailOnConstraint.create(Traps.class, "nullAssert", 3, "CallStaticJava", "uncommon_trap", "null_check"), + GoodRuleConstraint.create(Traps.class, "nullAssert", 4), + BadFailOnConstraint.create(Traps.class, "unstableIf", 1, "CallStaticJava", "uncommon_trap"), + BadFailOnConstraint.create(Traps.class, "unstableIf", 2, "CallStaticJava", "uncommon_trap", "unstable_if"), + GoodRuleConstraint.create(Traps.class, "unstableIf", 3), + BadFailOnConstraint.create(Traps.class, "classCheck", 1, "CallStaticJava", "uncommon_trap"), + BadFailOnConstraint.create(Traps.class, "classCheck", 2, "CallStaticJava", "uncommon_trap", "class_check"), + BadFailOnConstraint.create(Traps.class, "classCheck", 3, "CallStaticJava", "uncommon_trap", "null_check"), + GoodRuleConstraint.create(Traps.class, "classCheck", 4), + BadFailOnConstraint.create(Traps.class, "rangeCheck", 1, "CallStaticJava", "uncommon_trap"), + BadFailOnConstraint.create(Traps.class, "rangeCheck", 2, "CallStaticJava", "uncommon_trap", "range_check"), + BadFailOnConstraint.create(Traps.class, "rangeCheck", 3, "CallStaticJava", "uncommon_trap", "null_check"), + GoodRuleConstraint.create(Traps.class, "rangeCheck", 4), + BadFailOnConstraint.create(Traps.class, "instrinsicOrTypeCheckedInlining", 1, "CallStaticJava", "uncommon_trap"), WhiteBox.getWhiteBox().isJVMCISupportedByGC() ? - BadFailOnConstraint.create(Traps.class, "instrinsicOrTypeCheckedInlining()", 2, "CallStaticJava", "uncommon_trap", "intrinsic_or_type_checked_inlining") - : GoodRuleConstraint.create(Traps.class, "instrinsicOrTypeCheckedInlining()", 2), - BadFailOnConstraint.create(Traps.class, "instrinsicOrTypeCheckedInlining()", 3, "CallStaticJava", "uncommon_trap", "intrinsic"), - BadFailOnConstraint.create(Traps.class, "instrinsicOrTypeCheckedInlining()", 4, "CallStaticJava", "uncommon_trap", "null_check"), - GoodRuleConstraint.create(Traps.class, "instrinsicOrTypeCheckedInlining()", 5) + BadFailOnConstraint.create(Traps.class, "instrinsicOrTypeCheckedInlining", 2, "CallStaticJava", "uncommon_trap", "intrinsic_or_type_checked_inlining") + : GoodRuleConstraint.create(Traps.class, "instrinsicOrTypeCheckedInlining", 2), + BadFailOnConstraint.create(Traps.class, "instrinsicOrTypeCheckedInlining", 3, "CallStaticJava", "uncommon_trap", "intrinsic"), + BadFailOnConstraint.create(Traps.class, "instrinsicOrTypeCheckedInlining", 4, "CallStaticJava", "uncommon_trap", "null_check"), + GoodRuleConstraint.create(Traps.class, "instrinsicOrTypeCheckedInlining", 5) ); runCheck(new String[] {"-XX:+BailoutToInterpreterForThrows"}, - BadFailOnConstraint.create(UnhandledTrap.class, "unhandled()", 1, "CallStaticJava", "uncommon_trap"), - BadFailOnConstraint.create(UnhandledTrap.class, "unhandled()", 2, "CallStaticJava", "uncommon_trap", "unhandled"), - GoodRuleConstraint.create(UnhandledTrap.class, "unhandled()", 3) + BadFailOnConstraint.create(UnhandledTrap.class, "unhandled", 1, "CallStaticJava", "uncommon_trap"), + BadFailOnConstraint.create(UnhandledTrap.class, "unhandled", 2, "CallStaticJava", "uncommon_trap", "unhandled"), + GoodRuleConstraint.create(UnhandledTrap.class, "unhandled", 3) ); - runCheck(BadFailOnConstraint.create(ScopeObj.class, "scopeObject()", 1, "ScObj")); - runCheck(BadFailOnConstraint.create(Membar.class, "membar()", 1, "MemBar")); + runCheck(BadFailOnConstraint.create(ScopeObj.class, "scopeObject", 1, "ScObj")); + runCheck(BadFailOnConstraint.create(Membar.class, "membar", 1, "MemBar")); String cmp; if (Platform.isPPC() || Platform.isX86()) { @@ -255,13 +256,13 @@ public class TestIRMatching { } else { cmp = "cmp"; } - runCheck(BadFailOnConstraint.create(CheckCastArray.class, "array(java.lang.Object[])", 1, cmp, "Constant"), - BadFailOnConstraint.create(CheckCastArray.class, "array(java.lang.Object[])", 2, 1,cmp, "Constant", "MyClass"), - BadFailOnConstraint.create(CheckCastArray.class, "array(java.lang.Object[])", 2, 2,cmp, "Constant", "ir_framework/tests/MyClass"), - GoodFailOnConstraint.create(CheckCastArray.class, "array(java.lang.Object[])", 3), + runCheck(BadFailOnConstraint.create(CheckCastArray.class, "array", 1, cmp, "Constant"), + BadFailOnConstraint.create(CheckCastArray.class, "array", 2, 1,cmp, "Constant", "MyClass"), + BadFailOnConstraint.create(CheckCastArray.class, "array", 2, 2,cmp, "Constant", "ir_framework/tests/MyClass"), + GoodFailOnConstraint.create(CheckCastArray.class, "array", 3), Platform.isS390x() ? // There is no checkcast_arraycopy stub for C2 on s390 - GoodFailOnConstraint.create(CheckCastArray.class, "arrayCopy(java.lang.Object[],java.lang.Class)", 1) - : BadFailOnConstraint.create(CheckCastArray.class, "arrayCopy(java.lang.Object[],java.lang.Class)", 1, "checkcast_arraycopy") + GoodFailOnConstraint.create(CheckCastArray.class, "arrayCopy", 1) + : BadFailOnConstraint.create(CheckCastArray.class, "arrayCopy", 1, "checkcast_arraycopy") ); try { @@ -1555,28 +1556,15 @@ abstract class Constraint { private final Class klass; protected final int ruleIdx; private final Pattern methodPattern; - private final String classAndMethod; - protected final Pattern irPattern; private final String methodName; protected boolean matched; - Constraint(Class klass, String methodName, int ruleIdx, Pattern irPattern) { - this.klass = klass; - classAndMethod = klass.getSimpleName() + "." + methodName; - this.ruleIdx = ruleIdx; - this.methodPattern = Pattern.compile(Pattern.quote(classAndMethod)); - this.irPattern = irPattern; - this.methodName = methodName; - this.matched = false; - } - // For good constraints only Constraint(Class klass, String methodName, int ruleIdx) { this.klass = klass; - classAndMethod = klass.getSimpleName() + "." + methodName; + String classAndMethod = klass.getSimpleName() + "::" + methodName; this.ruleIdx = ruleIdx; - this.methodPattern = Pattern.compile(Pattern.quote(classAndMethod)); - this.irPattern = null; + this.methodPattern = Pattern.compile("\\b" + Pattern.quote(classAndMethod) + "\\b"); this.methodName = methodName; this.matched = false; } @@ -1677,7 +1665,7 @@ abstract class RegexConstraint extends Constraint { final List matches; RegexConstraint(Class klass, String methodName, String category, boolean isGood, List matches, int ruleIdx, int... regexIndexes) { - super(klass, methodName, ruleIdx, initIRPattern(category, ruleIdx)); + super(klass, methodName, ruleIdx); this.category = category; this.regexIndexes = regexIndexes; if (category.equals("failOn")) { @@ -1706,16 +1694,6 @@ abstract class RegexConstraint extends Constraint { return super.errorPrefix() + " with \"" + category + "\""; } - private static Pattern initIRPattern(String category, int ruleIdx) { - if (category.equals("failOn")) { - return Pattern.compile("rule " + ruleIdx + ":.*\\R.*- failOn: Graph contains forbidden nodes.*\\R" + - ".*Constraint \\d+:.*\\R.*Matched forbidden node.*"); - } else { - return Pattern.compile("rule " + ruleIdx + ":.*\\R.*- counts: Graph contains wrong number of nodes:\\R" + - ".*Constraint \\d+:.*\\R.*Expected.*"); - } - } - @Override protected void checkIRRule(String irRule) { int categoryIndex = irRule.indexOf("- " + category); diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestRunTests.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestRunTests.java index f8d64944ff4..39dae4ae3ad 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestRunTests.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestRunTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,7 +54,7 @@ public class TestRunTests { Asserts.fail("Should have thrown exception"); } catch (IRViolationException e) { System.setOut(oldOut); - String[] matches = { "test(int)", "test2(int)", "Failed IR Rules (2)"}; + String[] matches = { "test", "test2", "Failed IR Rules (2)"}; Arrays.stream(matches).forEach(m -> Asserts.assertTrue(e.getExceptionInfo().contains(m))); Asserts.assertEQ(e.getExceptionInfo().split("STANDALONE mode", -1).length - 1, 2); } diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestSetupTests.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestSetupTests.java index 782a773515a..1cdb6c2797a 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestSetupTests.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestSetupTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ package ir_framework.tests; import compiler.lib.ir_framework.*; import compiler.lib.ir_framework.driver.TestVMException; -import compiler.lib.ir_framework.shared.TestRunException; import java.io.ByteArrayOutputStream; import java.io.PrintStream; @@ -360,10 +359,11 @@ class TestSetupTestsWithExpectedExceptions { public void checkThrowInCheck(int x) { throw new BadCheckedTestException("expected check"); } -} -class BadCheckedTestException extends RuntimeException { - BadCheckedTestException(String s) { - super(s); + + static class BadCheckedTestException extends RuntimeException { + BadCheckedTestException(String s) { + super(s); + } } } diff --git a/test/jaxp/ProblemList.txt b/test/jaxp/ProblemList.txt index 23ebb07f5ff..8f7380a43f8 100644 --- a/test/jaxp/ProblemList.txt +++ b/test/jaxp/ProblemList.txt @@ -1,6 +1,6 @@ ########################################################################### # -# Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,3 +23,15 @@ # ########################################################################### +############################################################################# + +# Preview project specific failures go here at the end of the file. +# +# These are NOT failures that occur with the '--enable-preview' option +# specified; those go in the appropriate ProblemList-enable-preview.txt file. +# These are failures that occur WITHOUT the '--enable-preview' option +# specified AND occur because of some issue with preview project code, +# in either implementation or test code. + +############################################################################# + diff --git a/test/jdk/ProblemList-AotJdk.txt b/test/jdk/ProblemList-AotJdk.txt index 20960652dcf..c98bf63b25f 100644 --- a/test/jdk/ProblemList-AotJdk.txt +++ b/test/jdk/ProblemList-AotJdk.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -44,3 +44,15 @@ java/lang/invoke/DumpMethodHandleInternals.java 0000000 generic- # this message will not be printed in the production run. java/util/Locale/UseOldISOCodesTest.java 0000000 generic-all +############################################################################# + +# Preview project specific failures go here at the end of the file. +# +# These are NOT failures that occur with the '--enable-preview' option +# specified; those go in the appropriate ProblemList-enable-preview.txt file. +# These are failures that occur WITHOUT the '--enable-preview' option +# specified AND occur because of some issue with preview project code, +# in either implementation or test code. + +############################################################################# + diff --git a/test/jdk/ProblemList-StaticJdk.txt b/test/jdk/ProblemList-StaticJdk.txt index 70f0438c0c6..700099656e8 100644 --- a/test/jdk/ProblemList-StaticJdk.txt +++ b/test/jdk/ProblemList-StaticJdk.txt @@ -1,6 +1,6 @@ ########################################################################### # -# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. # 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,3 +24,16 @@ ########################################################################### # Currently empty + +############################################################################# + +# Preview project specific failures go here at the end of the file. +# +# These are NOT failures that occur with the '--enable-preview' option +# specified; those go in the appropriate ProblemList-enable-preview.txt file. +# These are failures that occur WITHOUT the '--enable-preview' option +# specified AND occur because of some issue with preview project code, +# in either implementation or test code. + +############################################################################# + diff --git a/test/jdk/ProblemList-Virtual.txt b/test/jdk/ProblemList-Virtual.txt index fc5f31e3ce8..52f187086de 100644 --- a/test/jdk/ProblemList-Virtual.txt +++ b/test/jdk/ProblemList-Virtual.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -34,3 +34,15 @@ java/lang/ScopedValue/StressStackOverflow.java#default 8309646 generic-all java/lang/ScopedValue/StressStackOverflow.java#no-TieredCompilation 8309646 generic-all java/lang/ScopedValue/StressStackOverflow.java#TieredStopAtLevel1 8309646 generic-all +############################################################################# + +# Preview project specific failures go here at the end of the file. +# +# These are NOT failures that occur with the '--enable-preview' option +# specified; those go in the appropriate ProblemList-enable-preview.txt file. +# These are failures that occur WITHOUT the '--enable-preview' option +# specified AND occur because of some issue with preview project code, +# in either implementation or test code. + +############################################################################# + diff --git a/test/jdk/ProblemList-Xcomp.txt b/test/jdk/ProblemList-Xcomp.txt index 5ed171a1fea..44bad411f26 100644 --- a/test/jdk/ProblemList-Xcomp.txt +++ b/test/jdk/ProblemList-Xcomp.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. # 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,3 +29,16 @@ java/lang/invoke/MethodHandles/CatchExceptionTest.java 8146623 generic-all java/lang/reflect/callerCache/ReflectionCallerCacheTest.java 8332028 generic-all + +############################################################################# + +# Preview project specific failures go here at the end of the file. +# +# These are NOT failures that occur with the '--enable-preview' option +# specified; those go in the appropriate ProblemList-enable-preview.txt file. +# These are failures that occur WITHOUT the '--enable-preview' option +# specified AND occur because of some issue with preview project code, +# in either implementation or test code. + +############################################################################# + diff --git a/test/jdk/ProblemList-coh.txt b/test/jdk/ProblemList-coh.txt new file mode 100644 index 00000000000..b3bddb0c9f4 --- /dev/null +++ b/test/jdk/ProblemList-coh.txt @@ -0,0 +1,41 @@ +# +# Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. +# 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. +# + +############################################################################# +# +# List of quarantined tests for testing with -XX:+UseCompactObjectHeaders +# +############################################################################# + +############################################################################# + +# Preview project specific failures go here at the end of the file. +# +# These are NOT failures that occur with the '--enable-preview' option +# specified; those go in the appropriate ProblemList-enable-preview.txt file. +# These are failures that occur WITHOUT the '--enable-preview' option +# specified AND occur because of some issue with preview project code, +# in either implementation or test code. + +############################################################################# + diff --git a/test/jdk/ProblemList-enable-preview.txt b/test/jdk/ProblemList-enable-preview.txt index 31e09d372a8..1a831a0dde3 100644 --- a/test/jdk/ProblemList-enable-preview.txt +++ b/test/jdk/ProblemList-enable-preview.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. # 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,6 +25,8 @@ # # List of quarantined tests for testing with --enable-preview # +# These are failures that ONLY occur with the '--enable-preview' option +# specified. There are separate sub-sections for each preview project. +# ############################################################################# - diff --git a/test/jdk/ProblemList-jvmti-stress-agent.txt b/test/jdk/ProblemList-jvmti-stress-agent.txt index 09be19c3d94..e9019b6014e 100644 --- a/test/jdk/ProblemList-jvmti-stress-agent.txt +++ b/test/jdk/ProblemList-jvmti-stress-agent.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. # 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,3 +29,16 @@ com/sun/jdi/ThreadMemoryLeakTest.java 0000 # weak referenced are not cleared java/lang/WeakPairMap/Driver.java 0000000 generic-all java/lang/ref/ReachabilityFenceTest.java 0000000 generic-all + +############################################################################# + +# Preview project specific failures go here at the end of the file. +# +# These are NOT failures that occur with the '--enable-preview' option +# specified; those go in the appropriate ProblemList-enable-preview.txt file. +# These are failures that occur WITHOUT the '--enable-preview' option +# specified AND occur because of some issue with preview project code, +# in either implementation or test code. + +############################################################################# + diff --git a/test/jdk/ProblemList-shenandoah.txt b/test/jdk/ProblemList-shenandoah.txt index 063795d69e8..522b77cb502 100644 --- a/test/jdk/ProblemList-shenandoah.txt +++ b/test/jdk/ProblemList-shenandoah.txt @@ -58,3 +58,15 @@ jdk/jfr/jcmd/TestJcmdStartPathToGCRoots.java 8342951 generic-all jdk/jfr/jvm/TestWaste.java 8342951 generic-all jdk/jfr/startupargs/TestOldObjectQueueSize.java 8342951 generic-all +############################################################################# + +# Preview project specific failures go here at the end of the file. +# +# These are NOT failures that occur with the '--enable-preview' option +# specified; those go in the appropriate ProblemList-enable-preview.txt file. +# These are failures that occur WITHOUT the '--enable-preview' option +# specified AND occur because of some issue with preview project code, +# in either implementation or test code. + +############################################################################# + diff --git a/test/jdk/ProblemList-zgc.txt b/test/jdk/ProblemList-zgc.txt index ab44c5e47a9..065a52f9a83 100644 --- a/test/jdk/ProblemList-zgc.txt +++ b/test/jdk/ProblemList-zgc.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -38,3 +38,16 @@ sun/tools/jhsdb/heapconfig/JMapHeapConfigTest.java 8307393 generic-all sun/tools/jhsdb/HeapDumpTestWithActiveProcess.java 8307393 generic-all com/sun/jdi/ThreadMemoryLeakTest.java 8307402 generic-all + +############################################################################# + +# Preview project specific failures go here at the end of the file. +# +# These are NOT failures that occur with the '--enable-preview' option +# specified; those go in the appropriate ProblemList-enable-preview.txt file. +# These are failures that occur WITHOUT the '--enable-preview' option +# specified AND occur because of some issue with preview project code, +# in either implementation or test code. + +############################################################################# + diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 291b2163b0d..94015ebc680 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -777,3 +777,16 @@ java/awt/Cursor/CursorDragTest/ListDragCursor.java 7177297 macosx-all # jdk_since_checks tools/sincechecker/modules/jdk.management.jfr/JdkManagementJfrCheckSince.java 8354921 generic-all + +############################################################################# + +# Preview project specific failures go here at the end of the file. +# +# These are NOT failures that occur with the '--enable-preview' option +# specified; those go in the appropriate ProblemList-enable-preview.txt file. +# These are failures that occur WITHOUT the '--enable-preview' option +# specified AND occur because of some issue with preview project code, +# in either implementation or test code. + +############################################################################# + diff --git a/test/jdk/TEST.groups b/test/jdk/TEST.groups index 27f6bb48a63..ccf745700d1 100644 --- a/test/jdk/TEST.groups +++ b/test/jdk/TEST.groups @@ -1,4 +1,4 @@ -# Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2013, 2026, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -664,7 +664,8 @@ jdk_core_manual_interactive = \ jdk_security_manual_interactive = \ sun/security/tools/keytool/i18n.java \ com/sun/security/auth/callback/TextCallbackHandler/Password.java \ - sun/security/krb5/config/native/TestDynamicStore.java + sun/security/krb5/config/native/TestDynamicStore.java \ + sun/security/tools/keytool/EchoPassword.java # Test sets for running inside container environment jdk_containers_extended = \ diff --git a/test/jdk/build/CheckFiles.java b/test/jdk/build/CheckFiles.java index 5a915e881f0..7ef5b803d2d 100644 --- a/test/jdk/build/CheckFiles.java +++ b/test/jdk/build/CheckFiles.java @@ -106,6 +106,8 @@ public class CheckFiles { allowedEndingsLibDir.add("psfont.properties.ja"); allowedEndingsLibDir.add("src.zip"); allowedEndingsLibDir.add("tzdb.dat"); + allowedEndingsLibDir.add("javafx-swt.jar"); + allowedEndingsLibDir.add("javafx.properties"); if (Platform.isWindows()) { allowedEndingsLibDir.add(".lib"); allowedEndingsLibDir.add("tzmappings"); diff --git a/test/jdk/com/sun/jndi/ldap/LdapPoolTimeoutTest.java b/test/jdk/com/sun/jndi/ldap/LdapPoolTimeoutTest.java index b47433ca16f..b139f12da25 100644 --- a/test/jdk/com/sun/jndi/ldap/LdapPoolTimeoutTest.java +++ b/test/jdk/com/sun/jndi/ldap/LdapPoolTimeoutTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -131,6 +131,7 @@ public class LdapPoolTimeoutTest { || msg.contains("No route to host") || msg.contains("Timed out waiting for lock") || msg.contains("Connect timed out") + || msg.contains("Connection timed out") || msg.contains("Timeout exceeded while waiting for a connection"))) { // got the expected exception System.out.println("Received expected NamingException with message: " + msg); diff --git a/test/jdk/java/awt/image/GetSampleSizeTest.java b/test/jdk/java/awt/image/GetSampleSizeTest.java new file mode 100644 index 00000000000..dcf6d1e6ed5 --- /dev/null +++ b/test/jdk/java/awt/image/GetSampleSizeTest.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.image.ComponentSampleModel; +import java.awt.image.DataBuffer; +import java.awt.image.MultiPixelPackedSampleModel; +import java.awt.image.SinglePixelPackedSampleModel; + +/* + * @test + * @bug 8376297 + * @summary Test SampleModel.getSampleSize(int) + */ + +public class GetSampleSizeTest { + + public static void main(String[] args) { + + final int width = 10; + final int height = 10; + int[] bandOffsets = {0, 0}; + int[] bitMask = {0x00ff0000, 0x0000ff00, 0xff, 0x0}; + + { + ComponentSampleModel csm = + new ComponentSampleModel(DataBuffer.TYPE_BYTE, + width, height, 1, width, bandOffsets); + int numBands = csm.getNumBands(); + System.out.println("CSM numBands = " + numBands); + if (numBands != 2) { + throw new RuntimeException("Unexpected numBands"); + } + System.out.println("CSM sample size = " + csm.getSampleSize(numBands)); + } + + { + MultiPixelPackedSampleModel mppsm = + new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, width, height, 4); + int numBands = mppsm.getNumBands(); + System.out.println("MPPSM numBands = " + numBands); + if (numBands != 1) { + throw new RuntimeException("Unexpected numBands"); + } + System.out.println("MPPSM sample size = " + mppsm.getSampleSize(numBands)); + } + + { + SinglePixelPackedSampleModel sppsm = + new SinglePixelPackedSampleModel(DataBuffer.TYPE_BYTE, width, height, bitMask); + int numBands = sppsm.getNumBands(); + System.out.println("SPPSM numBands = " + numBands); + if (numBands != 4) { + throw new RuntimeException("Unexpected numBands"); + } + try { + System.out.println("SPPSM sample size = " + sppsm.getSampleSize(numBands)); + throw new RuntimeException("No expected AIOBE"); + } catch (ArrayIndexOutOfBoundsException e) { + System.out.println("Got expected AIOBE for SPPSM"); + } + } + + } +} + diff --git a/test/jdk/java/awt/image/Raster/CreateRasterExceptionTest.java b/test/jdk/java/awt/image/Raster/CreateRasterExceptionTest.java index d89de44401b..13a88e8c590 100644 --- a/test/jdk/java/awt/image/Raster/CreateRasterExceptionTest.java +++ b/test/jdk/java/awt/image/Raster/CreateRasterExceptionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8255800 8369129 + * @bug 8255800 8369129 8376297 * @summary verify Raster + SampleModel creation vs spec. */ @@ -739,7 +739,7 @@ public class CreateRasterExceptionTest { /* @throws IllegalArgumentException if * {@code scanlineStride} is less than 0 */ - Raster.createBandedRaster(DataBuffer.TYPE_INT, 1, 1, -3, + Raster.createBandedRaster(DataBuffer.TYPE_INT, 10, 10, -1000, bankIndices, bandOffsets, null); noException(); } catch (IllegalArgumentException t) { diff --git a/test/jdk/java/awt/print/PrinterJob/PageRanges.java b/test/jdk/java/awt/print/PrinterJob/PageRanges.java index aea60516f78..691357d5a3c 100644 --- a/test/jdk/java/awt/print/PrinterJob/PageRanges.java +++ b/test/jdk/java/awt/print/PrinterJob/PageRanges.java @@ -23,7 +23,7 @@ /* * @test - * @bug 6575331 8297191 + * @bug 6575331 8297191 8373239 * @key printer * @summary The specified pages should be printed. * @library /java/awt/regtesthelpers diff --git a/test/jdk/java/io/Console/ReadWriteBlockingTest.java b/test/jdk/java/io/Console/ReadWriteBlockingTest.java new file mode 100644 index 00000000000..7c05d5d257b --- /dev/null +++ b/test/jdk/java/io/Console/ReadWriteBlockingTest.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8340830 + * @summary Check if writing to Console is not blocked by other thread's read. + * This test relies on sleep(1000) to ensure that readLine() is + * invoked before printf(), which may not always occur. + * @library /test/lib + * @requires (os.family == "linux" | os.family == "mac") + * @run junit ReadWriteBlockingTest + */ + +import java.nio.file.Files; +import java.nio.file.Path; + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.condition.EnabledOnOs; +import org.junit.jupiter.api.condition.OS; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +public class ReadWriteBlockingTest { + + @ParameterizedTest + @ValueSource(strings = {"java.base", "jdk.internal.le"}) + @EnabledOnOs({OS.LINUX, OS.MAC}) + public void testReadWriteBlocking(String consoleModule) throws Exception { + // check "expect" command availability + var expect = Path.of("/usr/bin/expect"); + if (!Files.exists(expect) || !Files.isExecutable(expect)) { + Assumptions.abort("'" + expect + "' not found"); + } + + // invoking "expect" command + var testSrc = System.getProperty("test.src", "."); + var testClasses = System.getProperty("test.classes", "."); + var jdkDir = System.getProperty("test.jdk"); + OutputAnalyzer output = ProcessTools.executeProcess( + "/usr/bin/expect", + "-n", + testSrc + "/readWriteBlocking.exp", + jdkDir + "/bin/java", + "-classpath", testClasses, + "-Djdk.console=" + consoleModule, + "ReadWriteBlockingTest"); + output.reportDiagnosticSummary(); + output.shouldHaveExitValue(0); + } + + public static void main(String... args) { + var con = System.console(); + Thread.ofVirtual().start(() -> { + try { + // give some time for main thread to invoke readLine() + Thread.sleep(1000); + } catch (InterruptedException _) {} + con.printf("printf() invoked"); + }); + con.readLine(""); + } +} diff --git a/test/jdk/java/io/Console/readWriteBlocking.exp b/test/jdk/java/io/Console/readWriteBlocking.exp new file mode 100644 index 00000000000..202dd42db3f --- /dev/null +++ b/test/jdk/java/io/Console/readWriteBlocking.exp @@ -0,0 +1,41 @@ +# +# Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. +# 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. +# + +set timeout 10 +eval spawn $argv + +expect { + "printf() invoked" { + send -- "\n" + } + timeout { + puts stderr "ERROR: Timed out waiting for the expected text" + exit 1 + } + eof { + puts stderr "ERROR: Process exited before printing the expected text" + exit 1 + } +} + +expect eof diff --git a/test/jdk/java/lang/ProcessBuilder/PipelineLeaksFD.java b/test/jdk/java/lang/ProcessBuilder/PipelineLeaksFD.java index 2b4cdfa9bdd..92cca736503 100644 --- a/test/jdk/java/lang/ProcessBuilder/PipelineLeaksFD.java +++ b/test/jdk/java/lang/ProcessBuilder/PipelineLeaksFD.java @@ -25,6 +25,7 @@ import org.junit.jupiter.api.condition.EnabledIf; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; import static org.junit.jupiter.api.Assertions.*; +import jdk.test.lib.Utils; import java.io.BufferedReader; import java.io.IOException; @@ -32,11 +33,16 @@ import java.io.Writer; import java.lang.ProcessHandle; import java.nio.file.Files; import java.nio.file.Path; +import java.util.concurrent.TimeUnit; +import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; +import java.util.Optional; import java.util.Set; +import java.util.StringJoiner; import java.util.stream.Collectors; /* @@ -44,7 +50,8 @@ import java.util.stream.Collectors; * @bug 8289643 8291760 8291986 * @requires os.family == "mac" | (os.family == "linux" & !vm.musl) * @summary File descriptor leak detection with ProcessBuilder.startPipeline - * @run junit/othervm PipelineLeaksFD + * @library /test/lib + * @run junit/othervm/timeout=240 PipelineLeaksFD */ public class PipelineLeaksFD { @@ -77,7 +84,7 @@ public class PipelineLeaksFD { // Check if lsof is available private static boolean checkForLSOF() { try { - lsofForAll(); + lsofForPids(MY_PID); return true; } catch (IOException ioe) { System.err.println("Skipping: " + ioe); @@ -90,7 +97,7 @@ public class PipelineLeaksFD { @MethodSource("builders") void checkForLeaks(List builders) throws IOException { - List lsofLines = lsofForAll(); + List lsofLines = lsofForPids(MY_PID); Set pipesBefore = pipesFromLSOF(lsofLines, MY_PID); if (pipesBefore.size() < 3) { // Dump all lsof output to aid debugging @@ -126,7 +133,7 @@ public class PipelineLeaksFD { processes.forEach(PipelineLeaksFD::waitForQuiet); - lsofLines = lsofForAll(); + lsofLines = lsofForPids(MY_PID); Set pipesAfter = pipesFromLSOF(lsofLines, MY_PID); if (!pipesBefore.equals(pipesAfter)) { Set missing = new HashSet<>(pipesBefore); @@ -154,22 +161,31 @@ public class PipelineLeaksFD { @EnabledIf("lsofAvailable") @ParameterizedTest() @MethodSource("redirectCases") - void checkRedirectErrorStream(boolean redirectError) throws IOException { + void checkRedirectErrorStream(boolean redirectError) { try (Process p = new ProcessBuilder("cat") .redirectErrorStream(redirectError) .start()) { System.err.printf("Parent PID; %d, Child Pid: %d\n", MY_PID, p.pid()); - List lsofLines = lsofForAll(); - final Set pipes = pipesFromLSOF(lsofLines, p.pid()); - printPipes(pipes, "Parent and waiting child pipes"); - int uniquePipes = redirectError ? 8 : 9; - if (uniquePipes != pipes.size()) { - // Dump all lsof output to aid debugging - System.out.println("\nOutput from lsof"); - lsofLines.forEach(System.err::println); - } - assertEquals(uniquePipes, pipes.size(), - "wrong number of pipes for redirect: " + redirectError); + List lsofLines = lsofForPids(MY_PID, p.pid()); + final Set pipes = pipesFromLSOF(lsofLines, MY_PID, p.pid()); + printPipes(pipes, "Parent and child pipes"); + + // For each of the child standard pipes, check the parent and child uses of the pipe + var pIn = PipeRecord.pipeFor(pipes, p.pid(), 0).orElseThrow(); + Set pIns = PipeRecord.allSamePipes(pipes, pIn); + assertEquals(2, pIns.size(), "StdIn pipe count"); + + // Number of pipe references depending on whether stderr is redirected to stdout + long expected = redirectError ? 3 : 2; + + var pOut = PipeRecord.pipeFor(pipes, p.pid(), 1).orElseThrow(); + Set pOuts = PipeRecord.allSamePipes(pipes, pOut); + assertEquals(expected, pOuts.size(), "StdOut pipe count"); + + var pErr = PipeRecord.pipeFor(pipes, p.pid(), 2).orElseThrow(); + Set pErrs = PipeRecord.allSamePipes(pipes, pErr); + assertEquals(expected, pErrs.size(), "StdErr pipe count"); + String expectedTypeName = redirectError ? "java.lang.ProcessBuilder$NullInputStream" : "java.lang.ProcessImpl$ProcessPipeInputStream"; @@ -196,48 +212,54 @@ public class PipelineLeaksFD { } /** - * Collect a Set of file descriptors and identifying information. - * To identify the pipes in use the `lsof` command is invoked and output scrapped for - * fd's, pids, unique identities of the pipes (to match with parent). - * @return A set of PipeRecords, possibly empty - */ - private static Set pipesForPid(long pid) throws IOException { - var lines = lsofForAll(); - return pipesFromLSOF(lines, pid); - } - - /** - * Extract the PipeRecords from the `lsof` output for this process and a designated child process. + * Extract the PipeRecords from the `lsof` output for a list of processes * * @param lines lines of lsof output - * @param pid pid of child process of interest - * @return a Set of PipeRecords for parent and child + * @param pids varargs list of pids of interest + * @return a Set of PipeRecords for those pids */ - private static LinkedHashSet pipesFromLSOF(List lines, long pid) { + private static LinkedHashSet pipesFromLSOF(List lines, long... pids) { + Arrays.sort(pids); return lines.stream() .map(PipelineLeaksFD::pipeFromLSOF) .filter(pr -> pr != null && - (pr.pid() == pid || pr.pid() == MY_PID)) + Arrays.binarySearch(pids, pr.pid()) >= 0) .collect(Collectors.toCollection(LinkedHashSet::new)); } /** * Collect the output of `lsof` for all files. * Files are used for `lsof` input and output to avoid creating pipes. + * @param pids zero or more pids to request data for; none -> all * @return a List of lines output from `lsof`. */ - private static List lsofForAll() throws IOException { + private static List lsofForPids(long... pids) throws IOException { Path tmpDir = Path.of("."); String tmpPrefix = "lsof-"; Path lsofEmptyInput = Files.createTempFile(tmpDir, tmpPrefix, ".empty"); Path lsofOutput = Files.createTempFile(tmpDir, tmpPrefix, ".tmp"); - try (Process p = new ProcessBuilder("lsof") + + List lsofArgs = new ArrayList<>(); + lsofArgs.add("lsof"); + if (pids.length > 0) { + StringJoiner pidsArg = new StringJoiner(","); + for (long p : pids) { + pidsArg.add(Long.toString(p)); + } + lsofArgs.add("-p"); + lsofArgs.add(pidsArg.toString()); + } + + try (Process p = new ProcessBuilder(lsofArgs) .redirectOutput(lsofOutput.toFile()) .redirectInput(lsofEmptyInput.toFile()) // empty input .redirectError(ProcessBuilder.Redirect.DISCARD) // ignored output .start()) { - int status = p.waitFor(); - assertEquals(0, status, "Process 'lsof' failed"); + boolean status = p.waitFor(Utils.adjustTimeout(120), TimeUnit.SECONDS); + if (!status) { + p.destroyForcibly(); + } + assertTrue(status, "Process 'lsof' failed"); return Files.readAllLines(lsofOutput); } catch (InterruptedException ie) { @@ -255,8 +277,8 @@ public class PipelineLeaksFD { } // Return Pipe from lsof output put, or null (on Mac OS X) - // lsof 55221 rriggs 0 PIPE 0xc76402237956a5cb 16384 ->0xfcb0c07ae447908c - // lsof 55221 rriggs 1 PIPE 0xb486e02f86da463e 16384 ->0xf94eacc85896b4e6 + // lsof 55221 xxxx 0 PIPE 0xc76402237956a5cb 16384 ->0xfcb0c07ae447908c + // lsof 55221 xxxx 1 PIPE 0xb486e02f86da463e 16384 ->0xf94eacc85896b4e6 static PipeRecord pipeFromMacLSOF(String s) { String[] fields = s.split("\\s+"); if ("PIPE".equals(fields[4])) { @@ -269,8 +291,8 @@ public class PipelineLeaksFD { } // Return Pipe from lsof output put, or null (on Linux) - // java 7612 rriggs 14w FIFO 0,12 0t0 117662267 pipe - // java 7612 rriggs 15r FIFO 0,12 0t0 117662268 pipe + // java 7612 xxxx 14w FIFO 0,12 0t0 117662267 pipe + // java 7612 xxxx 15r FIFO 0,12 0t0 117662268 pipe static PipeRecord pipeFromLinuxLSOF(String s) { String[] fields = s.split("\\s+"); if ("FIFO".equals(fields[4])) { @@ -288,6 +310,20 @@ public class PipelineLeaksFD { static PipeRecord lookup(int fd, String myKey, String otherKey, int pid) { return new PipeRecord(pid, fd, KeyedString.getKey(myKey, otherKey)); } + + // Return the PipeRecord matching the fd and pid + static Optional pipeFor(Set pipes, long pid, int fd) { + return pipes.stream() + .filter(p -> p.fd() == fd && p.pid() == pid) + .findFirst(); + } + + // Return all the PipeRecords with the same key (the same OS pipe identification) + static Set allSamePipes(Set pipes, PipeRecord p) { + return pipes.stream() + .filter(p1 -> p1.myKey().key.equals(p.myKey().key)) + .collect(Collectors.toSet()); + } } // A unique name for a string with a count of uses @@ -297,11 +333,9 @@ public class PipelineLeaksFD { private static int nextInt = 1; private final String key; private final String name; - private int count; KeyedString(String key, String name) { this.key = key; this.name = name; - this.count = 0; } KeyedString(String s) { @@ -311,7 +345,6 @@ public class PipelineLeaksFD { static KeyedString getKey(String key, String otherKey) { var k = map.computeIfAbsent(key, KeyedString::new); - k.count++; if (otherKey != null) { map.putIfAbsent(otherKey, k); } @@ -319,7 +352,7 @@ public class PipelineLeaksFD { } public String toString() { - return name + "(" + count + ")"; + return name + ": osInfo: " + key; } } } diff --git a/test/jdk/java/lang/ProcessBuilder/TEST.properties b/test/jdk/java/lang/ProcessBuilder/TEST.properties index c7e8a6850ca..f96e7602fd4 100644 --- a/test/jdk/java/lang/ProcessBuilder/TEST.properties +++ b/test/jdk/java/lang/ProcessBuilder/TEST.properties @@ -1 +1 @@ -maxOutputSize=6000000 +maxOutputSize=12000000 diff --git a/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenBlocking.java b/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenBlocking.java index 733ee261b09..15a134f0bb2 100644 --- a/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenBlocking.java +++ b/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenBlocking.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ * @requires vm.debug != true * @modules jdk.management * @library /test/lib - * @run main/othervm/timeout=1200 GetStackTraceALotWhenBlocking 100000 + * @run main/othervm/timeout=1200 GetStackTraceALotWhenBlocking 10000 */ /* @@ -36,7 +36,7 @@ * @requires vm.debug == true & vm.continuations * @modules jdk.management * @library /test/lib - * @run main/othervm/timeout=1200 GetStackTraceALotWhenBlocking 50000 + * @run main/othervm/timeout=1200 GetStackTraceALotWhenBlocking 5000 */ import java.time.Instant; diff --git a/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java b/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java index ef385e47e21..a23a0de36d2 100644 --- a/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java +++ b/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ * @requires vm.debug != true * @modules jdk.management * @library /test/lib - * @run main/othervm/native/timeout=300 --enable-native-access=ALL-UNNAMED GetStackTraceALotWhenPinned 100000 + * @run main/othervm/native/timeout=300 --enable-native-access=ALL-UNNAMED GetStackTraceALotWhenPinned 10000 */ /* @@ -36,7 +36,7 @@ * @requires vm.debug == true * @modules jdk.management * @library /test/lib - * @run main/othervm/native/timeout=300 --enable-native-access=ALL-UNNAMED GetStackTraceALotWhenPinned 50000 + * @run main/othervm/native/timeout=300 --enable-native-access=ALL-UNNAMED GetStackTraceALotWhenPinned 5000 */ import java.time.Instant; diff --git a/test/jdk/java/lang/invoke/8147078/Test8147078.java b/test/jdk/java/lang/invoke/8147078/Test8147078.java index 08532d30929..51580aa6f10 100644 --- a/test/jdk/java/lang/invoke/8147078/Test8147078.java +++ b/test/jdk/java/lang/invoke/8147078/Test8147078.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,17 +23,18 @@ /* @test * @bug 8147078 - * @run testng/othervm -ea -esa Test8147078 + * @run junit/othervm -ea -esa Test8147078 */ -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import static java.lang.invoke.MethodType.methodType; -import static org.testng.AssertJUnit.*; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; public class Test8147078 { @@ -65,16 +66,10 @@ public class Test8147078 { @Test public void testNoExceptionType() { - boolean caught = false; - try { + var cce = assertThrows(ClassCastException.class, () -> { MethodHandle eek = (MethodHandle) MH_catchException.invoke(MH_target, String.class, MH_handler); - } catch (ClassCastException cce) { - assertEquals("java.lang.String", cce.getMessage()); - caught = true; - } catch (Throwable t) { - fail("unexpected exception caught: " + t); - } - assertTrue(caught); + }); + assertEquals("java.lang.String", cce.getMessage()); } } \ No newline at end of file diff --git a/test/jdk/java/lang/invoke/8177146/TestMethodHandleBind.java b/test/jdk/java/lang/invoke/8177146/TestMethodHandleBind.java index 134cc9f7514..518d07b1518 100644 --- a/test/jdk/java/lang/invoke/8177146/TestMethodHandleBind.java +++ b/test/jdk/java/lang/invoke/8177146/TestMethodHandleBind.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,17 +23,16 @@ /* @test * @bug 8177146 - * @run testng/othervm TestMethodHandleBind + * @run junit/othervm TestMethodHandleBind */ -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodType; import static java.lang.invoke.MethodHandles.lookup; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; public class TestMethodHandleBind extends pkg.A { static class B extends TestMethodHandleBind {} @@ -42,7 +41,7 @@ public class TestMethodHandleBind extends pkg.A { public void testInstanceOfCallerClass() throws Throwable { MethodHandle bound = lookup().bind(new TestMethodHandleBind() , "m1", MethodType.methodType(String.class)); String x = (String)bound.invoke(); - assertEquals(x, this.getClass().getSimpleName()); + assertEquals(this.getClass().getSimpleName(), x); } @Test @@ -50,47 +49,37 @@ public class TestMethodHandleBind extends pkg.A { MethodHandle bound = lookup().bind(new B() , "m1", MethodType.methodType(String.class)); // MethodHandle bound = lookup().findVirtual(B.class, "m1", MethodType.methodType(String.class)).bindTo(new B()); String x = (String)bound.invoke(); - assertEquals(x, "B"); + assertEquals("B", x); } @Test public void testInstanceOfReceiverClass() throws Throwable { - try { - MethodHandle bound = lookup().bind(new pkg.A() , "m1", MethodType.methodType(String.class)); - bound.invoke(); - fail("IllegalAccessException expected"); - } catch (IllegalAccessException e) { - } + assertThrows(IllegalAccessException.class, () -> lookup().bind(new pkg.A() , "m1", MethodType.methodType(String.class))); } @Test public void testPublicMethod() throws Throwable { MethodHandle bound = lookup().bind(new pkg.A() , "m2", MethodType.methodType(String.class)); String x = (String)bound.invoke(); - assertEquals(x, "A"); + assertEquals("A", x); } @Test public void testPublicMethod2() throws Throwable { MethodHandle bound = lookup().bind(new TestMethodHandleBind(), "m2", MethodType.methodType(String.class)); String x = (String)bound.invoke(); - assertEquals(x, this.getClass().getSimpleName()); + assertEquals(this.getClass().getSimpleName(), x); } @Test public void testInstanceOfCallerClassVarargs() throws Throwable { MethodHandle bound = lookup().bind(new TestMethodHandleBind() , "m3", MethodType.methodType(String.class, String[].class)); String x = (String)bound.invoke("a", "b", "c"); - assertEquals(x, this.getClass().getSimpleName() + "abc"); + assertEquals(this.getClass().getSimpleName() + "abc", x); } @Test public void testInstanceOfReceiverClassVarargs() throws Throwable { - try { - MethodHandle bound = lookup().bind(new pkg.A(), "m3", MethodType.methodType(String.class, String[].class)); - bound.invoke(); - fail("IllegalAccessException expected"); - } catch (IllegalAccessException e) { - } + assertThrows(IllegalAccessException.class, () -> lookup().bind(new pkg.A(), "m3", MethodType.methodType(String.class, String[].class))); } } diff --git a/test/jdk/java/lang/invoke/AccessControlTest.java b/test/jdk/java/lang/invoke/AccessControlTest.java index e177f08d876..fcd945a5d7f 100644 --- a/test/jdk/java/lang/invoke/AccessControlTest.java +++ b/test/jdk/java/lang/invoke/AccessControlTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /* @test * @summary test access checking by java.lang.invoke.MethodHandles.Lookup * @compile AccessControlTest.java AccessControlTest_subpkg/Acquaintance_remote.java - * @run testng/othervm test.java.lang.invoke.AccessControlTest + * @run junit/othervm test.java.lang.invoke.AccessControlTest */ package test.java.lang.invoke; @@ -33,12 +33,13 @@ import java.lang.invoke.*; import java.lang.reflect.*; import java.lang.reflect.Modifier; import java.util.*; -import org.testng.annotations.*; import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodHandles.Lookup.*; import static java.lang.invoke.MethodType.*; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; import test.java.lang.invoke.AccessControlTest_subpkg.Acquaintance_remote; @@ -69,7 +70,7 @@ public class AccessControlTest { this.prevLookupClass = lookup.previousLookupClass(); this.lookupModes = lookup.lookupModes(); - assert(lookupString().equals(lookup.toString())); + assertEquals(lookupString(), lookup.toString()); numberOf(lookupClass().getClassLoader()); // assign CL# } public LookupCase(Class lookupClass, Class prevLookupClass, int lookupModes) { @@ -96,7 +97,7 @@ public class AccessControlTest { int cmp = c1.getName().compareTo(c2.getName()); if (cmp != 0) return cmp; cmp = numberOf(c1.getClassLoader()) - numberOf(c2.getClassLoader()); - assert(cmp != 0); + assertNotEquals(0, cmp); return cmp; } else if (p1 != p2){ if (p1 == null) @@ -106,7 +107,7 @@ public class AccessControlTest { int cmp = p1.getName().compareTo(p2.getName()); if (cmp != 0) return cmp; cmp = numberOf(p1.getClassLoader()) - numberOf(p2.getClassLoader()); - assert(cmp != 0); + assertNotEquals(0, cmp); return cmp; } return -(this.lookupModes() - that.lookupModes()); @@ -211,8 +212,8 @@ public class AccessControlTest { c1.getPackageName().equals(c2.getPackageName())); boolean sameTopLevel = (topLevelClass(c1) == topLevelClass(c2)); boolean sameClass = (c1 == c2); - assert(samePackage || !sameTopLevel); - assert(sameTopLevel || !sameClass); + assertTrue(samePackage || !sameTopLevel); + assertTrue(sameTopLevel || !sameClass); boolean accessible = sameClass; if ((modes1 & PACKAGE) != 0) accessible |= samePackage; @@ -251,17 +252,17 @@ public class AccessControlTest { changed |= (PRIVATE|PROTECTED); // [A5] } if (sameClass) { - assert(changed == 0); // [A11] (no deprivation if same class) + assertEquals(0, changed); // [A11] (no deprivation if same class) } - if (accessible) assert((changed & PUBLIC) == 0); + if (accessible) assertEquals(0, changed & PUBLIC); int modes2 = modes1 & ~changed; Class plc = (m1 == m2) ? prevLookupClass() : c1; // [A9] [A10] if ((modes1 & UNCONDITIONAL) != 0) plc = null; // [A8] LookupCase l2 = new LookupCase(c2, plc, modes2); - assert(l2.lookupClass() == c2); // [A1] - assert((modes1 | modes2) == modes1); // [A1-a] (no elevation of access) - assert(l2.prevLookupClass() == null || (modes2 & MODULE) == 0); + assertSame(l2.lookupClass(), c2); // [A1] + assertEquals(modes1, modes1 | modes2); // [A1-a] (no elevation of access) + assertTrue(l2.prevLookupClass() == null || (modes2 & MODULE) == 0); return l2; } @@ -280,8 +281,8 @@ public class AccessControlTest { } if (newModes == oldModes) return this; // return self if no change LookupCase l2 = new LookupCase(lookupClass(), prevLookupClass(), newModes); - assert((oldModes | newModes) == oldModes); // [A2] (no elevation of access) - assert(l2.prevLookupClass() == null || (newModes & MODULE) == 0); + assertEquals(oldModes, oldModes | newModes); // [A2] (no elevation of access) + assertTrue(l2.prevLookupClass() == null || (newModes & MODULE) == 0); return l2; } @@ -331,7 +332,7 @@ public class AccessControlTest { && Modifier.isPublic(m.getModifiers()); } - assert(m1 == m2 && prevLookupClass == null); + assertNull(prevLookupClass); if (!willAccessClass(c2, false)) return false; @@ -380,7 +381,7 @@ public class AccessControlTest { && Modifier.isPublic(c2.getModifiers()); } - assert(m1 == m2 && prevLookupClass == null); + assertNull(prevLookupClass); LookupCase lc = this.in(c2); int modes1 = lc.lookupModes(); @@ -409,8 +410,8 @@ public class AccessControlTest { Class c = cls; for (Class ec; (ec = c.getEnclosingClass()) != null; ) c = ec; - assert(c.getEnclosingClass() == null); - assert(c == cls || cls.getEnclosingClass() != null); + assertNull(c.getEnclosingClass()); + assertTrue(c == cls || cls.getEnclosingClass() != null); return c; } @@ -443,14 +444,14 @@ public class AccessControlTest { if (edges == null) CASE_EDGES.put(l2, edges = new TreeSet<>()); if (edges.add(l1)) { Class c1 = l1.lookupClass(); - assert(l2.lookupClass() == c2); // [A1] + assertSame(l2.lookupClass(), c2); // [A1] int m1 = l1.lookupModes(); int m2 = l2.lookupModes(); - assert((m1 | m2) == m1); // [A2] (no elevation of access) + assertEquals(m1, (m1 | m2)); // [A2] (no elevation of access) LookupCase expect = dropAccess == 0 ? l1.in(c2) : l1.in(c2).dropLookupMode(dropAccess); if (!expect.equals(l2)) System.out.println("*** expect "+l1+" => "+expect+" but got "+l2); - assertEquals(l2, expect); + assertEquals(expect, l2); } } @@ -567,7 +568,7 @@ public class AccessControlTest { if (willAccess != didAccess) { System.out.println(sourceCase+" => "+targetClass.getSimpleName()+(isFindOrAccessClass?"":"."+methodName+methodType)); System.out.println("fail "+(isFindOrAccessClass?kind:"on "+method)+" ex="+accessError); - assertEquals(willAccess, didAccess); + assertEquals(didAccess, willAccess); } testCount++; if (!didAccess) testCountFails++; @@ -579,10 +580,10 @@ public class AccessControlTest { System.out.println(targetClass.getSimpleName()+"."+methodName+methodType); try { Method method = targetClass.getDeclaredMethod(methodName, methodType.parameterArray()); - assertEquals(method.getReturnType(), methodType.returnType()); + assertEquals(methodType.returnType(), method.getReturnType()); int haveMods = method.getModifiers(); - assert(Modifier.isStatic(haveMods)); - assert(targetAccess == fixMods(haveMods)); + assertTrue(Modifier.isStatic(haveMods)); + assertEquals(targetAccess, fixMods(haveMods)); return method; } catch (NoSuchMethodException ex) { throw new AssertionError(methodName, ex); @@ -604,7 +605,7 @@ public class AccessControlTest { case PACKAGE: return "pkg_in_"; case PRIVATE: return "pri_in_"; } - assert(false); + fail(); return "?"; } private static final int[] ACCESS_CASES = { diff --git a/test/jdk/java/lang/invoke/ArrayConstructorTest.java b/test/jdk/java/lang/invoke/ArrayConstructorTest.java index 749bb7926a0..313c2828380 100644 --- a/test/jdk/java/lang/invoke/ArrayConstructorTest.java +++ b/test/jdk/java/lang/invoke/ArrayConstructorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* @test * @bug 8155106 - * @run testng/othervm -ea -esa test.java.lang.invoke.ArrayConstructorTest + * @run junit/othervm -ea -esa test.java.lang.invoke.ArrayConstructorTest */ package test.java.lang.invoke; @@ -32,30 +32,22 @@ import java.lang.invoke.MethodHandles; import static java.lang.invoke.MethodType.methodType; -import static org.testng.AssertJUnit.*; - -import org.testng.annotations.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import static org.junit.jupiter.api.Assertions.*; public class ArrayConstructorTest { static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup(); @Test - public static void testFindConstructorArray() { - boolean caught = false; - try { - MethodHandle h = LOOKUP.findConstructor(Object[].class, methodType(void.class)); - } catch (NoSuchMethodException nsme) { - assertEquals("no constructor for array class: [Ljava.lang.Object;", nsme.getMessage()); - caught = true; - } catch (Exception e) { - throw new AssertionError("unexpected exception: " + e); - } - assertTrue(caught); + public void testFindConstructorArray() { + var nsme = assertThrows(NoSuchMethodException.class, () -> LOOKUP.findConstructor(Object[].class, methodType(void.class))); + assertEquals("no constructor for array class: [Ljava.lang.Object;", nsme.getMessage()); } - @DataProvider static Object[][] arrayConstructorNegative() { return new Object[][]{ {String.class, IllegalArgumentException.class, "not an array class: java.lang.String"}, @@ -63,34 +55,28 @@ public class ArrayConstructorTest { }; } - @Test(dataProvider = "arrayConstructorNegative") - public static void testArrayConstructorNegative(Class clazz, Class exceptionClass, String message) { - boolean caught = false; - try { - MethodHandle h = MethodHandles.arrayConstructor(clazz); - } catch (Exception e) { - assertEquals(exceptionClass, e.getClass()); - if (message != null) { - assertEquals(message, e.getMessage()); - } - caught = true; + @ParameterizedTest + @MethodSource("arrayConstructorNegative") + public void testArrayConstructorNegative(Class clazz, Class exceptionClass, String message) { + var e = assertThrowsExactly(exceptionClass, () -> MethodHandles.arrayConstructor(clazz)); + if (message != null) { + assertEquals(message, e.getMessage()); } - assertTrue(caught); } @Test - public static void testArrayConstructor() throws Throwable { + public void testArrayConstructor() throws Throwable { MethodHandle h = MethodHandles.arrayConstructor(String[].class); assertEquals(methodType(String[].class, int.class), h.type()); String[] a = (String[]) h.invoke(17); assertEquals(17, a.length); } - @Test(expectedExceptions = {NegativeArraySizeException.class}) - public static void testArrayConstructorNegativeIndex() throws Throwable { + @Test + public void testArrayConstructorNegativeIndex() throws Throwable { MethodHandle h = MethodHandles.arrayConstructor(String[].class); assertEquals(methodType(String[].class, int.class), h.type()); - h.invoke(-1); // throws exception + assertThrows(NegativeArraySizeException.class, () -> h.invoke(-1)); } } diff --git a/test/jdk/java/lang/invoke/ArrayLengthTest.java b/test/jdk/java/lang/invoke/ArrayLengthTest.java index 9f3cc6fe240..2ef97442638 100644 --- a/test/jdk/java/lang/invoke/ArrayLengthTest.java +++ b/test/jdk/java/lang/invoke/ArrayLengthTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,36 +22,39 @@ */ /* @test - * @run testng/othervm -ea -esa test.java.lang.invoke.ArrayLengthTest + * @run junit/othervm -ea -esa test.java.lang.invoke.ArrayLengthTest */ package test.java.lang.invoke; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; -import static org.testng.AssertJUnit.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; -import org.testng.annotations.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; public class ArrayLengthTest { - @DataProvider - Object[][] arrayClasses() { - return new Object[][] { - {int[].class}, - {long[].class}, - {float[].class}, - {double[].class}, - {boolean[].class}, - {byte[].class}, - {short[].class}, - {char[].class}, - {Object[].class}, - {StringBuffer[].class} + static Object[] arrayClasses() { + return new Object[] { + int[].class, + long[].class, + float[].class, + double[].class, + boolean[].class, + byte[].class, + short[].class, + char[].class, + Object[].class, + StringBuffer[].class }; } - @Test(dataProvider = "arrayClasses") + @ParameterizedTest + @MethodSource("arrayClasses") public void testArrayLength(Class arrayClass) throws Throwable { MethodHandle arrayLength = MethodHandles.arrayLength(arrayClass); assertEquals(int.class, arrayLength.type().returnType()); @@ -60,25 +63,28 @@ public class ArrayLengthTest { assertEquals(10, arrayLength.invoke(array)); } - @Test(dataProvider = "arrayClasses", expectedExceptions = NullPointerException.class) + @ParameterizedTest + @MethodSource("arrayClasses") public void testArrayLengthInvokeNPE(Class arrayClass) throws Throwable { MethodHandle arrayLength = MethodHandles.arrayLength(arrayClass); - arrayLength.invoke(null); + assertThrows(NullPointerException.class, () -> arrayLength.invoke(null)); } - @Test(expectedExceptions = IllegalArgumentException.class) + @Test public void testArrayLengthNoArray() { - MethodHandles.arrayLength(String.class); + assertThrows(IllegalArgumentException.class, () -> MethodHandles.arrayLength(String.class)); } - @Test(expectedExceptions = NullPointerException.class) + @Test public void testArrayLengthNPE() { - MethodHandles.arrayLength(null); + assertThrows(NullPointerException.class, () -> MethodHandles.arrayLength(null)); } - @Test(expectedExceptions = NullPointerException.class) + @Test public void testNullReference() throws Throwable { MethodHandle arrayLength = MethodHandles.arrayLength(String[].class); - int len = (int)arrayLength.invokeExact((String[])null); + assertThrows(NullPointerException.class, () -> { + int len = (int)arrayLength.invokeExact((String[])null); + }); } } diff --git a/test/jdk/java/lang/invoke/CallerSensitiveMethodHandle.java b/test/jdk/java/lang/invoke/CallerSensitiveMethodHandle.java index 369c2c2bea1..a2756fc2f23 100644 --- a/test/jdk/java/lang/invoke/CallerSensitiveMethodHandle.java +++ b/test/jdk/java/lang/invoke/CallerSensitiveMethodHandle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,20 +22,19 @@ */ /* @test - * @run testng/othervm CallerSensitiveMethodHandle + * @run junit/othervm CallerSensitiveMethodHandle * @summary Check Lookup findVirtual, findStatic and unreflect behavior with * caller sensitive methods with focus on AccessibleObject.setAccessible */ -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles.Lookup; import java.lang.reflect.Field; import static java.lang.invoke.MethodType.*; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; public class CallerSensitiveMethodHandle { private static int field = 0; @@ -46,7 +45,7 @@ public class CallerSensitiveMethodHandle { MethodHandle mh = l.findVirtual(Field.class, "setInt", methodType(void.class, Object.class, int.class)); int newValue = 5; mh.invokeExact(f, (Object) null, newValue); - assertTrue(field == newValue); + assertEquals(newValue, field); } @Test @@ -55,6 +54,6 @@ public class CallerSensitiveMethodHandle { MethodHandle MH_lookup2 = lookup.findStatic(MethodHandles.class, "lookup", methodType(Lookup.class)); Lookup lookup2 = (Lookup) MH_lookup2.invokeExact(); System.out.println(lookup2 + " original lookup class " + lookup.lookupClass()); - assertTrue(lookup2.lookupClass() == lookup.lookupClass()); + assertSame(lookup.lookupClass(), lookup2.lookupClass()); } } diff --git a/test/jdk/java/lang/invoke/ClassSpecializerTest.java b/test/jdk/java/lang/invoke/ClassSpecializerTest.java index 671cf39e217..8bc5c58ad52 100644 --- a/test/jdk/java/lang/invoke/ClassSpecializerTest.java +++ b/test/jdk/java/lang/invoke/ClassSpecializerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * 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,15 +24,13 @@ /* @test * @summary Smoke-test class specializer, used to create BoundMethodHandle classes * @compile/module=java.base java/lang/invoke/ClassSpecializerHelper.java - * @run testng/othervm/timeout=250 -ea -esa ClassSpecializerTest + * @run junit/othervm/timeout=250 -ea -esa ClassSpecializerTest */ // Useful diagnostics to try: // -Djava.lang.invoke.MethodHandle.TRACE_RESOLVE=true // -Djava.lang.invoke.MethodHandle.DUMP_CLASS_FILES=true - -import org.testng.annotations.*; import java.lang.invoke.*; import java.util.ArrayList; import java.util.Arrays; @@ -40,6 +38,11 @@ import java.util.List; import static java.lang.invoke.ClassSpecializerHelper.*; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertSame; + public class ClassSpecializerTest { @Test @@ -58,12 +61,12 @@ public class ClassSpecializerTest { } args.set(0, key * 1000 + 42); Frob f = (Frob) mh.invokeWithArguments(args.toArray()); - assert(f.kind() == k); + assertSame(k, f.kind()); System.out.println("k.f(...) = " + f.toString()); List l = f.asList(); System.out.println("f.l = " + l); args.subList(0,1).clear(); // drop label - assert(args.equals(l)); + assertEquals(args, l); } } private static Object coughUpA(Class pt) throws Throwable { diff --git a/test/jdk/java/lang/invoke/CompileThresholdBootstrapTest.java b/test/jdk/java/lang/invoke/CompileThresholdBootstrapTest.java index 848264b83a3..c6e093bd09a 100644 --- a/test/jdk/java/lang/invoke/CompileThresholdBootstrapTest.java +++ b/test/jdk/java/lang/invoke/CompileThresholdBootstrapTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * 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,27 +26,19 @@ * @bug 8143232 * @summary Test verifies that LF bootstraps properly when run with COMPILE_THRESHOLD set * @compile CompileThresholdBootstrapTest.java - * @run testng/othervm -Djava.lang.invoke.MethodHandle.COMPILE_THRESHOLD=30 test.java.lang.invoke.CompileThresholdBootstrapTest + * @run junit/othervm -Djava.lang.invoke.MethodHandle.COMPILE_THRESHOLD=30 test.java.lang.invoke.CompileThresholdBootstrapTest */ package test.java.lang.invoke; import java.lang.invoke.MethodHandles; -import org.testng.*; -import org.testng.annotations.*; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; public final class CompileThresholdBootstrapTest { @Test public void testBootstrap() throws Throwable { - Assert.assertEquals((int)MethodHandles.constant(int.class, (int)0).invokeExact(), 0); - } - - public static void main(String ... args) { - try { - CompileThresholdBootstrapTest test = new CompileThresholdBootstrapTest(); - test.testBootstrap(); - } catch (Throwable t) { - t.printStackTrace(); - } + assertEquals(0, (int)MethodHandles.constant(int.class, (int)0).invokeExact()); } } diff --git a/test/jdk/java/lang/invoke/ConstantIdentityMHTest.java b/test/jdk/java/lang/invoke/ConstantIdentityMHTest.java index 320fd29abe6..43770ea023b 100644 --- a/test/jdk/java/lang/invoke/ConstantIdentityMHTest.java +++ b/test/jdk/java/lang/invoke/ConstantIdentityMHTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* @test * @summary unit tests for java.lang.invoke.MethodHandles - * @run testng/othervm -ea -esa test.java.lang.invoke.ConstantIdentityMHTest + * @run junit/othervm -ea -esa test.java.lang.invoke.ConstantIdentityMHTest */ package test.java.lang.invoke; @@ -31,13 +31,14 @@ import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; -import static org.testng.Assert.*; -import org.testng.annotations.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; public class ConstantIdentityMHTest { - @DataProvider(name = "testZeroData") - private Object[][] testZeroData() { + private static Object[][] testZeroData() { return new Object[][] { {void.class, "()void"}, {int.class, "()int"}, @@ -52,26 +53,27 @@ public class ConstantIdentityMHTest { }; } - @Test(dataProvider = "testZeroData") + @ParameterizedTest + @MethodSource("testZeroData") public void testZero(Class expectedtype, String expected) throws Throwable { - assertEquals(MethodHandles.zero(expectedtype).type().toString(), expected); + assertEquals(expected, MethodHandles.zero(expectedtype).type().toString()); } - @Test(expectedExceptions={ NullPointerException.class }) + @Test public void testZeroNPE() { - MethodHandle mh = MethodHandles.zero(null); + assertThrows(NullPointerException.class, () -> MethodHandles.zero(null)); } @Test void testEmpty() throws Throwable { MethodHandle cat = lookup().findVirtual(String.class, "concat", methodType(String.class, String.class)); - assertEquals((String)cat.invoke("x","y"), "xy"); + assertEquals("xy", (String)cat.invoke("x","y")); MethodHandle mhEmpty = MethodHandles.empty(cat.type()); - assertEquals((String)mhEmpty.invoke("x","y"), null); + assertNull((String) mhEmpty.invoke("x", "y")); } - @Test(expectedExceptions = { NullPointerException.class }) + @Test void testEmptyNPE() { - MethodHandle lenEmptyMH = MethodHandles.empty(null); + assertThrows(NullPointerException.class, () -> MethodHandles.empty(null)); } } diff --git a/test/jdk/java/lang/invoke/DefineClassTest.java b/test/jdk/java/lang/invoke/DefineClassTest.java index f712c945e59..889607f38f5 100644 --- a/test/jdk/java/lang/invoke/DefineClassTest.java +++ b/test/jdk/java/lang/invoke/DefineClassTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* @test * @modules java.base/java.lang:open - * @run testng/othervm test.DefineClassTest + * @run junit/othervm test.DefineClassTest * @summary Basic test for java.lang.invoke.MethodHandles.Lookup.defineClass */ @@ -38,7 +38,6 @@ import java.net.URLClassLoader; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import org.testng.annotations.Test; import static java.lang.classfile.ClassFile.ACC_PUBLIC; import static java.lang.classfile.ClassFile.ACC_STATIC; @@ -48,7 +47,8 @@ import static java.lang.constant.ConstantDescs.INIT_NAME; import static java.lang.constant.ConstantDescs.MTD_void; import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodHandles.Lookup.*; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; public class DefineClassTest { private static final String THIS_PACKAGE = DefineClassTest.class.getPackageName(); @@ -60,9 +60,9 @@ public class DefineClassTest { * protection domain, as a lookup class. */ void testSameAbode(Class clazz, Class lc) { - assertTrue(clazz.getClassLoader() == lc.getClassLoader()); - assertEquals(clazz.getPackageName(), lc.getPackageName()); - assertTrue(clazz.getProtectionDomain() == lc.getProtectionDomain()); + assertSame(lc.getClassLoader(), clazz.getClassLoader()); + assertEquals(lc.getPackageName(), clazz.getPackageName()); + assertSame(lc.getProtectionDomain(), clazz.getProtectionDomain()); } /** @@ -72,8 +72,8 @@ public class DefineClassTest { void testDiscoverable(Class clazz, Lookup lookup) throws Exception { String cn = clazz.getName(); ClassLoader loader = clazz.getClassLoader(); - assertTrue(Class.forName(cn, false, loader) == clazz); - assertTrue(lookup.findClass(cn) == clazz); + assertSame(clazz, Class.forName(cn, false, loader)); + assertSame(clazz, lookup.findClass(cn)); } /** @@ -86,7 +86,7 @@ public class DefineClassTest { Class clazz = lookup.defineClass(generateClass(CLASS_NAME)); // test name - assertEquals(clazz.getName(), CLASS_NAME); + assertEquals(CLASS_NAME, clazz.getName()); // test loader/package/protection-domain testSameAbode(clazz, lookup.lookupClass()); @@ -95,10 +95,8 @@ public class DefineClassTest { testDiscoverable(clazz, lookup); // attempt defineClass again - try { - lookup.defineClass(generateClass(CLASS_NAME)); - assertTrue(false); - } catch (LinkageError expected) { } + var bytes = generateClass(CLASS_NAME); + assertThrows(LinkageError.class, () -> lookup.defineClass(bytes)); } /** @@ -126,10 +124,7 @@ public class DefineClassTest { classBytes = generateRunner(CLASS_NAME + nextNumber(), THIS_CLASS, "method4"); Class clazz = lookup.defineClass(classBytes); Runnable r = (Runnable) clazz.newInstance(); - try { - r.run(); - assertTrue(false); - } catch (IllegalAccessError expected) { } + assertThrows(IllegalAccessError.class, r::run); } public static void method1() { } @@ -154,12 +149,8 @@ public class DefineClassTest { Class clazz = lookup().defineClass(classBytes); // trigger initializer to run - try { - clazz.newInstance(); - assertTrue(false); - } catch (ExceptionInInitializerError e) { - assertTrue(e.getCause() instanceof IllegalCallerException); - } + var e = assertThrows(ExceptionInInitializerError.class, clazz::newInstance); + assertInstanceOf(IllegalCallerException.class, e.getCause()); } static void fail() { throw new IllegalCallerException(); } @@ -189,9 +180,9 @@ public class DefineClassTest { ClassLoader loader = new URLClassLoader(new URL[] { url1, url2 }); Class target1 = Class.forName("p.C1", false, loader); Class target2 = Class.forName("p.C2", false, loader); - assertTrue(target1.getClassLoader() == loader); - assertTrue(target1.getClassLoader() == loader); - assertNotEquals(target1.getProtectionDomain(), target2.getProtectionDomain()); + assertSame(loader, target1.getClassLoader()); + assertSame(loader, target1.getClassLoader()); + assertNotEquals(target2.getProtectionDomain(), target1.getProtectionDomain()); // protection domain 1 Lookup lookup1 = privateLookupIn(target1, lookup()); @@ -214,43 +205,43 @@ public class DefineClassTest { @Test public void testBootLoader() throws Exception { Lookup lookup = privateLookupIn(Thread.class, lookup()); - assertTrue(lookup.getClass().getClassLoader() == null); + assertNull(lookup.getClass().getClassLoader()); Class clazz = lookup.defineClass(generateClass("java.lang.Foo")); - assertEquals(clazz.getName(), "java.lang.Foo"); + assertEquals("java.lang.Foo", clazz.getName()); testSameAbode(clazz, Thread.class); testDiscoverable(clazz, lookup); } - @Test(expectedExceptions = { IllegalArgumentException.class }) + @Test public void testWrongPackage() throws Exception { - lookup().defineClass(generateClass("other.C")); + assertThrows(IllegalArgumentException.class, () -> lookup().defineClass(generateClass("other.C"))); } - @Test(expectedExceptions = { IllegalAccessException.class }) + @Test public void testNoPackageAccess() throws Exception { Lookup lookup = lookup().dropLookupMode(PACKAGE); - lookup.defineClass(generateClass(THIS_PACKAGE + ".C")); + assertThrows(IllegalAccessException.class, () -> lookup.defineClass(generateClass(THIS_PACKAGE + ".C"))); } - @Test(expectedExceptions = { ClassFormatError.class }) + @Test public void testTruncatedClassFile() throws Exception { - lookup().defineClass(new byte[0]); + assertThrows(ClassFormatError.class, () -> lookup().defineClass(new byte[0])); } - @Test(expectedExceptions = { NullPointerException.class }) + @Test public void testNull() throws Exception { - lookup().defineClass(null); + assertThrows(NullPointerException.class, () -> lookup().defineClass(null)); } - @Test(expectedExceptions = { NoClassDefFoundError.class }) + @Test public void testLinking() throws Exception { - lookup().defineClass(generateNonLinkableClass(THIS_PACKAGE + ".NonLinkableClass")); + assertThrows(NoClassDefFoundError.class, () -> lookup().defineClass(generateNonLinkableClass(THIS_PACKAGE + ".NonLinkableClass"))); } - @Test(expectedExceptions = { IllegalArgumentException.class }) + @Test public void testModuleInfo() throws Exception { - lookup().defineClass(generateModuleInfo()); + assertThrows(IllegalArgumentException.class, () -> lookup().defineClass(generateModuleInfo())); } /** diff --git a/test/jdk/java/lang/invoke/DropArgumentsTest.java b/test/jdk/java/lang/invoke/DropArgumentsTest.java index 2df9b5f63ba..fb82bb312cd 100644 --- a/test/jdk/java/lang/invoke/DropArgumentsTest.java +++ b/test/jdk/java/lang/invoke/DropArgumentsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved. * 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,19 +24,24 @@ /* @test * @bug 8158169 * @summary unit tests for java.lang.invoke.MethodHandles - * @run testng test.java.lang.invoke.DropArgumentsTest + * @run junit test.java.lang.invoke.DropArgumentsTest */ package test.java.lang.invoke; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; -import static org.testng.AssertJUnit.*; -import org.testng.annotations.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; public class DropArgumentsTest { @@ -53,8 +58,7 @@ public class DropArgumentsTest { } - @DataProvider(name = "dropArgumentsToMatchNPEData") - private Object[][] dropArgumentsToMatchNPEData() + private static Object[][] dropArgumentsToMatchNPEData() throws NoSuchMethodException, IllegalAccessException { MethodHandle cat = lookup().findVirtual(String.class, "concat", methodType(String.class, String.class)); return new Object[][] { @@ -63,13 +67,13 @@ public class DropArgumentsTest { }; } - @Test(dataProvider = "dropArgumentsToMatchNPEData", expectedExceptions = { NullPointerException.class }) + @ParameterizedTest + @MethodSource("dropArgumentsToMatchNPEData") public void dropArgumentsToMatchNPE(MethodHandle target, int pos, List> valueType, int skip) { - MethodHandles.dropArgumentsToMatch(target, pos, valueType , skip); + assertThrows(NullPointerException.class, () -> MethodHandles.dropArgumentsToMatch(target, pos, valueType, skip)); } - @DataProvider(name = "dropArgumentsToMatchIAEData") - private Object[][] dropArgumentsToMatchIAEData() + private static Object[][] dropArgumentsToMatchIAEData() throws NoSuchMethodException, IllegalAccessException { MethodHandle cat = lookup().findVirtual(String.class, "concat", methodType(String.class, String.class)); MethodType bigType = cat.type().insertParameterTypes(0, String.class, String.class, int.class); @@ -82,17 +86,20 @@ public class DropArgumentsTest { }; } - @Test(dataProvider = "dropArgumentsToMatchIAEData", expectedExceptions = { IllegalArgumentException.class }) + @ParameterizedTest + @MethodSource("dropArgumentsToMatchIAEData") public void dropArgumentsToMatchIAE(MethodHandle target, int pos, List> valueType, int skip) { - MethodHandles.dropArgumentsToMatch(target, pos, valueType , skip); + assertThrows(IllegalArgumentException.class, () -> MethodHandles.dropArgumentsToMatch(target, pos, valueType, skip)); } - @Test(expectedExceptions = { IllegalArgumentException.class }) + @Test public void dropArgumentsToMatchTestWithVoid() throws Throwable { MethodHandle cat = lookup().findVirtual(String.class, "concat", - MethodType.methodType(String.class, String.class)); - MethodType bigTypewithVoid = cat.type().insertParameterTypes(0, void.class, String.class, int.class); - MethodHandle handle2 = MethodHandles.dropArgumentsToMatch(cat, 0, bigTypewithVoid.parameterList(), 1); + MethodType.methodType(String.class, String.class)); + List> bigTypewithVoid = new ArrayList<>(cat.type().parameterList()); + bigTypewithVoid.addAll(0, List.of(void.class, String.class, int.class)); + assertThrows(IllegalArgumentException.class, () -> + MethodHandles.dropArgumentsToMatch(cat, 0, bigTypewithVoid, 1)); } public static class MethodSet { diff --git a/test/jdk/java/lang/invoke/DropLookupModeTest.java b/test/jdk/java/lang/invoke/DropLookupModeTest.java index 1a4c311be8b..7619793c3c6 100644 --- a/test/jdk/java/lang/invoke/DropLookupModeTest.java +++ b/test/jdk/java/lang/invoke/DropLookupModeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,9 +21,9 @@ * questions. */ -/** +/* * @test - * @run testng DropLookupModeTest + * @run junit DropLookupModeTest * @summary Basic unit tests Lookup::dropLookupMode */ @@ -31,83 +31,85 @@ import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles.Lookup; import static java.lang.invoke.MethodHandles.Lookup.*; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; -@Test public class DropLookupModeTest { /** * Basic test of dropLookupMode */ + @Test public void testBasic() { final Lookup fullPowerLookup = MethodHandles.lookup(); final Class lc = fullPowerLookup.lookupClass(); - assertTrue(fullPowerLookup.lookupModes() == (PUBLIC|MODULE|PACKAGE|PROTECTED|PRIVATE|ORIGINAL)); + assertEquals(PUBLIC | MODULE | PACKAGE | PROTECTED | PRIVATE | ORIGINAL, fullPowerLookup.lookupModes()); Lookup lookup = fullPowerLookup.dropLookupMode(PRIVATE); - assertTrue(lookup.lookupClass() == lc); - assertTrue(lookup.lookupModes() == (PUBLIC|MODULE|PACKAGE)); + assertSame(lc, lookup.lookupClass()); + assertEquals(PUBLIC | MODULE | PACKAGE, lookup.lookupModes()); lookup = fullPowerLookup.dropLookupMode(PROTECTED); - assertTrue(lookup.lookupClass() == lc); - assertTrue(lookup.lookupModes() == (PUBLIC|MODULE|PACKAGE|PRIVATE)); + assertSame(lc, lookup.lookupClass()); + assertEquals(PUBLIC | MODULE | PACKAGE | PRIVATE, lookup.lookupModes()); lookup = fullPowerLookup.dropLookupMode(PACKAGE); - assertTrue(lookup.lookupClass() == lc); - assertTrue(lookup.lookupModes() == (PUBLIC|MODULE)); + assertSame(lc, lookup.lookupClass()); + assertEquals(PUBLIC | MODULE, lookup.lookupModes()); lookup = fullPowerLookup.dropLookupMode(MODULE); - assertTrue(lookup.lookupClass() == lc); - assertTrue(lookup.lookupModes() == (PUBLIC)); + assertSame(lc, lookup.lookupClass()); + assertEquals(PUBLIC, lookup.lookupModes()); lookup = fullPowerLookup.dropLookupMode(PUBLIC); - assertTrue(lookup.lookupClass() == lc); - assertTrue(lookup.lookupModes() == 0); + assertSame(lc, lookup.lookupClass()); + assertEquals(0, lookup.lookupModes()); lookup = fullPowerLookup.dropLookupMode(UNCONDITIONAL); - assertTrue(lookup.lookupClass() == lc); - assertTrue(lookup.lookupModes() == (PUBLIC|MODULE|PACKAGE|PRIVATE)); + assertSame(lc, lookup.lookupClass()); + assertEquals(PUBLIC | MODULE | PACKAGE | PRIVATE, lookup.lookupModes()); } /** * Starting with a full power Lookup, use dropLookupMode to create new Lookups * with reduced access. */ + @Test public void testReducingAccess() { Lookup lookup = MethodHandles.lookup(); final Class lc = lookup.lookupClass(); - assertTrue(lookup.lookupModes() == (PUBLIC|MODULE|PACKAGE|PROTECTED|PRIVATE|ORIGINAL)); + assertEquals(PUBLIC | MODULE | PACKAGE | PROTECTED | PRIVATE | ORIGINAL, lookup.lookupModes()); lookup = lookup.dropLookupMode(PROTECTED); - assertTrue(lookup.lookupClass() == lc); - assertTrue(lookup.lookupModes() == (PUBLIC|MODULE|PACKAGE|PRIVATE)); + assertSame(lc, lookup.lookupClass()); + assertEquals(PUBLIC | MODULE | PACKAGE | PRIVATE, lookup.lookupModes()); lookup = lookup.dropLookupMode(PRIVATE); - assertTrue(lookup.lookupClass() == lc); - assertTrue(lookup.lookupModes() == (PUBLIC|MODULE|PACKAGE)); + assertSame(lc, lookup.lookupClass()); + assertEquals(PUBLIC | MODULE | PACKAGE, lookup.lookupModes()); lookup = lookup.dropLookupMode(PACKAGE); - assertTrue(lookup.lookupClass() == lc); - assertTrue(lookup.lookupModes() == (PUBLIC|MODULE)); + assertSame(lc, lookup.lookupClass()); + assertEquals(PUBLIC | MODULE, lookup.lookupModes()); lookup = lookup.dropLookupMode(MODULE); - assertTrue(lookup.lookupClass() == lc); - assertTrue(lookup.lookupModes() == PUBLIC); + assertSame(lc, lookup.lookupClass()); + assertEquals(PUBLIC, lookup.lookupModes()); lookup = lookup.dropLookupMode(PUBLIC); - assertTrue(lookup.lookupClass() == lc); - assertTrue(lookup.lookupModes() == 0); + assertSame(lc, lookup.lookupClass()); + assertEquals(0, lookup.lookupModes()); // repeat with lookup has no access lookup = lookup.dropLookupMode(PUBLIC); - assertTrue(lookup.lookupClass() == lc); - assertTrue(lookup.lookupModes() == 0); + assertSame(lc, lookup.lookupClass()); + assertEquals(0, lookup.lookupModes()); } - @DataProvider(name = "unconditionals") - public Object[][] unconditionals() { + public static Object[][] unconditionals() { Lookup publicLookup = MethodHandles.publicLookup(); return new Object[][] { { publicLookup, Object.class }, @@ -120,9 +122,10 @@ public class DropLookupModeTest { * Test dropLookupMode on the lookup with public lookup * and UNCONDITIONAL */ - @Test(dataProvider = "unconditionals") + @ParameterizedTest + @MethodSource("unconditionals") public void testUnconditionalLookup(Lookup unconditionalLookup, Class expected) { - assertTrue(unconditionalLookup.lookupModes() == UNCONDITIONAL); + assertEquals(UNCONDITIONAL, unconditionalLookup.lookupModes()); assertPublicLookup(unconditionalLookup.dropLookupMode(PRIVATE), expected); assertPublicLookup(unconditionalLookup.dropLookupMode(PROTECTED), expected); @@ -132,31 +135,27 @@ public class DropLookupModeTest { // drop all access Lookup lookup = unconditionalLookup.dropLookupMode(UNCONDITIONAL); - assertTrue(lookup.lookupClass() == expected); - assertTrue(lookup.lookupModes() == 0); + assertSame(expected, lookup.lookupClass()); + assertEquals(0, lookup.lookupModes()); } private void assertPublicLookup(Lookup lookup, Class expected) { - assertTrue(lookup.lookupClass() == expected); - assertTrue(lookup.lookupModes() == UNCONDITIONAL); - } - - @DataProvider(name = "badInput") - public Object[][] badInput() { - return new Object[][] { - { 0, null }, - { (PACKAGE|PRIVATE), null }, // two modes - { Integer.MAX_VALUE, null }, - { Integer.MIN_VALUE, null }, - }; + assertSame(expected, lookup.lookupClass()); + assertEquals(UNCONDITIONAL, lookup.lookupModes()); } /** * Check that IllegalArgumentException is thrown for bad input */ - @Test(dataProvider = "badInput", expectedExceptions = {IllegalArgumentException.class}) - public void testBadInput(Integer modeToDrop, Object ignore) { - MethodHandles.lookup().dropLookupMode(modeToDrop); + @ParameterizedTest + @ValueSource(ints = { + 0, + (PACKAGE|PRIVATE), // two modes + Integer.MAX_VALUE, + Integer.MIN_VALUE, + }) + public void testBadInput(int modeToDrop) { + assertThrows(IllegalArgumentException.class, () -> MethodHandles.lookup().dropLookupMode(modeToDrop)); } } diff --git a/test/jdk/java/lang/invoke/FilterArgumentsTest.java b/test/jdk/java/lang/invoke/FilterArgumentsTest.java index 3c4884e7c6a..2326799cc1c 100644 --- a/test/jdk/java/lang/invoke/FilterArgumentsTest.java +++ b/test/jdk/java/lang/invoke/FilterArgumentsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /* * @test * @bug 8194554 - * @run testng/othervm test.java.lang.invoke.FilterArgumentsTest + * @run junit/othervm test.java.lang.invoke.FilterArgumentsTest */ package test.java.lang.invoke; @@ -37,40 +37,40 @@ import java.util.List; import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.methodType; -import org.testng.annotations.*; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; public class FilterArgumentsTest { @Test - public static void testFilterA_B_C() throws Throwable { + public void testFilterA_B_C() throws Throwable { FilterTest test = new FilterTest( filterArguments(MH_TEST, 0, MH_FILTER_A, MH_FILTER_B, MH_FILTER_C)); test.run(List.of("A", "B", "C")); } @Test - public static void testFilterA_B() throws Throwable { + public void testFilterA_B() throws Throwable { FilterTest test = new FilterTest( filterArguments(MH_TEST, 0, MH_FILTER_A, MH_FILTER_B)); test.run(List.of("A", "B")); } @Test - public static void testFilterB_C() throws Throwable { + public void testFilterB_C() throws Throwable { FilterTest test = new FilterTest( filterArguments(MH_TEST, 1, MH_FILTER_B, MH_FILTER_C)); test.run(List.of("B", "C")); } @Test - public static void testFilterB() throws Throwable { + public void testFilterB() throws Throwable { FilterTest test = new FilterTest(filterArguments(MH_TEST, 1, MH_FILTER_B)); test.run(List.of("B")); } @Test - public static void testFilterC() throws Throwable { + public void testFilterC() throws Throwable { FilterTest test = new FilterTest(filterArguments(MH_TEST, 2, MH_FILTER_C)); test.run(List.of("C")); } @@ -85,8 +85,8 @@ public class FilterArgumentsTest { void run(List expected) throws Throwable { filters.clear(); - assertEquals((String)mh.invokeExact("x", 0, 'z'), "x-0-z"); - assertEquals(filters, expected); + assertEquals("x-0-z", (String)mh.invokeExact("x", 0, 'z')); + assertEquals(expected, filters); } static String filterA(String s) { diff --git a/test/jdk/java/lang/invoke/FindAccessTest.java b/test/jdk/java/lang/invoke/FindAccessTest.java index f8602ee22bd..3bcff4f5324 100644 --- a/test/jdk/java/lang/invoke/FindAccessTest.java +++ b/test/jdk/java/lang/invoke/FindAccessTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* @test * @bug 8139885 - * @run testng/othervm -ea -esa test.java.lang.invoke.FindAccessTest + * @run junit/othervm -ea -esa test.java.lang.invoke.FindAccessTest */ package test.java.lang.invoke; @@ -33,9 +33,10 @@ import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles.Lookup; import java.lang.invoke.MethodType; -import static org.testng.AssertJUnit.*; +import org.junit.jupiter.api.Test; -import org.testng.annotations.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; /** * Tests for Lookup.findClass/accessClass extensions added in JEP 274. @@ -45,7 +46,7 @@ public class FindAccessTest { static final Lookup LOOKUP = MethodHandles.lookup(); @Test - public static void testFindSpecial() throws Throwable { + public void testFindSpecial() throws Throwable { FindSpecial.C c = new FindSpecial.C(); assertEquals("I1.m", c.m()); MethodType t = MethodType.methodType(String.class); @@ -54,25 +55,18 @@ public class FindAccessTest { } @Test - public static void testFindSpecialAbstract() throws Throwable { + public void testFindSpecialAbstract() throws Throwable { FindSpecial.C c = new FindSpecial.C(); assertEquals("q", c.q()); MethodType t = MethodType.methodType(String.class); - boolean caught = false; - try { - MethodHandle ci3q = LOOKUP.findSpecial(FindSpecial.I3.class, "q", t, FindSpecial.C.class); - } catch (Throwable thrown) { - if (!(thrown instanceof IllegalAccessException) || !FindSpecial.ABSTRACT_ERROR.equals(thrown.getMessage())) { - throw new AssertionError(thrown.getMessage(), thrown); - } - caught = true; - } - assertTrue(caught); + var thrown = assertThrows(IllegalAccessException.class, + () -> LOOKUP.findSpecial(FindSpecial.I3.class, "q", t, FindSpecial.C.class)); + assertEquals(FindSpecial.ABSTRACT_ERROR, thrown.getMessage()); } - @Test(expectedExceptions = {ClassNotFoundException.class}) - public static void testFindClassCNFE() throws ClassNotFoundException, IllegalAccessException { - LOOKUP.findClass("does.not.Exist"); + @Test + public void testFindClassCNFE() throws ClassNotFoundException, IllegalAccessException { + assertThrows(ClassNotFoundException.class, () -> LOOKUP.findClass("does.not.Exist")); } static class FindSpecial { diff --git a/test/jdk/java/lang/invoke/FoldTest.java b/test/jdk/java/lang/invoke/FoldTest.java index 157cfbffe2e..92ba246ebc8 100644 --- a/test/jdk/java/lang/invoke/FoldTest.java +++ b/test/jdk/java/lang/invoke/FoldTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* @test * @bug 8139885 - * @run testng/othervm -ea -esa test.java.lang.invoke.FoldTest + * @run junit/othervm -ea -esa test.java.lang.invoke.FoldTest */ package test.java.lang.invoke; @@ -36,9 +36,9 @@ import java.lang.invoke.MethodType; import static java.lang.invoke.MethodType.methodType; -import static org.testng.AssertJUnit.*; +import org.junit.jupiter.api.Test; -import org.testng.annotations.*; +import static org.junit.jupiter.api.Assertions.assertEquals; /** * Tests for the new fold method handle combinator added in JEP 274. @@ -48,7 +48,7 @@ public class FoldTest { static final Lookup LOOKUP = MethodHandles.lookup(); @Test - public static void testFold0a() throws Throwable { + public void testFold0a() throws Throwable { // equivalence to foldArguments(MethodHandle,MethodHandle) MethodHandle fold = MethodHandles.foldArguments(Fold.MH_multer, 0, Fold.MH_adder); assertEquals(Fold.MT_folded1, fold.type()); @@ -56,7 +56,7 @@ public class FoldTest { } @Test - public static void testFold1a() throws Throwable { + public void testFold1a() throws Throwable { // test foldArguments for folding position 1 MethodHandle fold = MethodHandles.foldArguments(Fold.MH_multer, 1, Fold.MH_adder1); assertEquals(Fold.MT_folded1, fold.type()); @@ -64,7 +64,7 @@ public class FoldTest { } @Test - public static void testFold0b() throws Throwable { + public void testFold0b() throws Throwable { // test foldArguments equivalence with multiple types MethodHandle fold = MethodHandles.foldArguments(Fold.MH_str, 0, Fold.MH_comb); assertEquals(Fold.MT_folded2, fold.type()); @@ -72,7 +72,7 @@ public class FoldTest { } @Test - public static void testFold1b() throws Throwable { + public void testFold1b() throws Throwable { // test folgArguments for folding position 1, with multiple types MethodHandle fold = MethodHandles.foldArguments(Fold.MH_str, 1, Fold.MH_comb2); assertEquals(Fold.MT_folded3, fold.type()); @@ -81,7 +81,7 @@ public class FoldTest { } @Test - public static void testFoldArgumentsExample() throws Throwable { + public void testFoldArgumentsExample() throws Throwable { // test the JavaDoc foldArguments-with-pos example StringWriter swr = new StringWriter(); MethodHandle trace = LOOKUP.findVirtual(StringWriter.class, "write", methodType(void.class, String.class)).bindTo(swr); diff --git a/test/jdk/java/lang/invoke/InvokeGenericTest.java b/test/jdk/java/lang/invoke/InvokeGenericTest.java index ef201caead1..0be810506de 100644 --- a/test/jdk/java/lang/invoke/InvokeGenericTest.java +++ b/test/jdk/java/lang/invoke/InvokeGenericTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /* @test * @summary unit tests for java.lang.invoke.MethodHandle.invoke * @compile InvokeGenericTest.java - * @run testng/othervm test.java.lang.invoke.InvokeGenericTest + * @run junit/othervm test.java.lang.invoke.InvokeGenericTest */ package test.java.lang.invoke; @@ -34,9 +34,13 @@ import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; import java.lang.reflect.*; import java.util.*; -import org.testng.*; -import static org.testng.AssertJUnit.*; -import org.testng.annotations.*; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; /** * @@ -68,7 +72,7 @@ public class InvokeGenericTest { String testName; static int allPosTests, allNegTests; int posTests, negTests; - @AfterMethod + @AfterEach public void printCounts() { if (verbosity >= 2 && (posTests | negTests) != 0) { System.out.println(); @@ -92,14 +96,14 @@ public class InvokeGenericTest { testName = name; } - @BeforeClass + @BeforeAll public static void setUpClass() throws Exception { calledLog.clear(); calledLog.add(null); nextArgVal = INITIAL_ARG_VAL; } - @AfterClass + @AfterAll public static void tearDownClass() throws Exception { int posTests = allPosTests, negTests = allNegTests; if (verbosity >= 2 && (posTests | negTests) != 0) { @@ -127,7 +131,7 @@ public class InvokeGenericTest { System.out.println("actual: "+actual); System.out.println("ex. types: "+getClasses(expected)); System.out.println("act. types: "+getClasses(actual)); - assertEquals("previous method call", expected, actual); + assertEquals(expected, actual, "previous method call"); } static void printCalled(MethodHandle target, String name, Object... args) { if (verbosity >= 3) @@ -389,8 +393,7 @@ public class InvokeGenericTest { } public void testWrongArgumentCount(List> expect, List> observe) throws Throwable { countTest(false); - if (expect.equals(observe)) - assert(false); + assertNotEquals(expect, observe); MethodHandle target = callable(expect); Object[] args = zeroArgs(observe); Object junk; @@ -473,28 +476,25 @@ public class InvokeGenericTest { mh = MethodHandles.filterReturnValue(mh, toString_MH); mh = mh.asType(type); Object res = null; - if (nargs == 2) { - res = mh.invoke((Object)args[0], (Object)args[1]); - assertEquals(expectString, res); - res = mh.invoke((String)args[0], (Object)args[1]); - assertEquals(expectString, res); - res = mh.invoke((Object)args[0], (String)args[1]); - assertEquals(expectString, res); - res = mh.invoke((String)args[0], (String)args[1]); - assertEquals(expectString, res); - res = mh.invoke((String)args[0], (CharSequence)args[1]); - assertEquals(expectString, res); - res = mh.invoke((CharSequence)args[0], (Object)args[1]); - assertEquals(expectString, res); - res = (String) mh.invoke((Object)args[0], (Object)args[1]); - assertEquals(expectString, res); - res = (String) mh.invoke((String)args[0], (Object)args[1]); - assertEquals(expectString, res); - res = (CharSequence) mh.invoke((String)args[0], (Object)args[1]); - assertEquals(expectString, res); - } else { - assert(false); // write this code - } + assertEquals(2, nargs); + res = mh.invoke((Object)args[0], (Object)args[1]); + assertEquals(expectString, res); + res = mh.invoke((String)args[0], (Object)args[1]); + assertEquals(expectString, res); + res = mh.invoke((Object)args[0], (String)args[1]); + assertEquals(expectString, res); + res = mh.invoke((String)args[0], (String)args[1]); + assertEquals(expectString, res); + res = mh.invoke((String)args[0], (CharSequence)args[1]); + assertEquals(expectString, res); + res = mh.invoke((CharSequence)args[0], (Object)args[1]); + assertEquals(expectString, res); + res = (String) mh.invoke((Object)args[0], (Object)args[1]); + assertEquals(expectString, res); + res = (String) mh.invoke((String)args[0], (Object)args[1]); + assertEquals(expectString, res); + res = (CharSequence) mh.invoke((String)args[0], (Object)args[1]); + assertEquals(expectString, res); //System.out.println(res); } diff --git a/test/jdk/java/lang/invoke/InvokeMethodHandleWithBadArgument.java b/test/jdk/java/lang/invoke/InvokeMethodHandleWithBadArgument.java index 2479c22b2f4..f2749cfb164 100644 --- a/test/jdk/java/lang/invoke/InvokeMethodHandleWithBadArgument.java +++ b/test/jdk/java/lang/invoke/InvokeMethodHandleWithBadArgument.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ * @test * @bug 8157246 * @summary Tests invocation of MethodHandle with invalid leading argument - * @run testng/othervm test.java.lang.invoke.InvokeMethodHandleWithBadArgument + * @run junit/othervm test.java.lang.invoke.InvokeMethodHandleWithBadArgument */ package test.java.lang.invoke; @@ -38,9 +38,9 @@ import java.lang.invoke.VarHandle; import static java.lang.invoke.MethodType.methodType; -import static org.testng.AssertJUnit.*; +import org.junit.jupiter.api.Test; -import org.testng.annotations.*; +import static org.junit.jupiter.api.Assertions.*; /** * Tests invocation of MethodHandle with invalid leading argument such as @@ -49,86 +49,100 @@ import org.testng.annotations.*; public class InvokeMethodHandleWithBadArgument { // ---- null array reference ---- - @Test(expectedExceptions = {NullPointerException.class}) - public static void testAsSpreaderPosInvokeWithNull() throws Throwable { + @Test + public void testAsSpreaderPosInvokeWithNull() throws Throwable { MethodHandle spreader = MH_spread.asSpreader(1, int[].class, 3); - spreader.invoke("A", null, "B"); + assertThrows(NullPointerException.class, () -> spreader.invoke("A", null, "B")); } - @Test(expectedExceptions = {NullPointerException.class}) - public static void testAsSpreaderInvokeWithNull() throws Throwable { + @Test + public void testAsSpreaderInvokeWithNull() throws Throwable { MethodHandle spreader = MH_String_equals.asSpreader(String[].class, 2); - assert ((boolean) spreader.invokeExact(new String[]{"me", "me"})); - boolean eq = (boolean) spreader.invokeExact((String[]) null); + assertTrue((boolean) spreader.invokeExact(new String[]{"me", "me"})); + assertThrows(NullPointerException.class, () -> { + boolean eq = (boolean) spreader.invokeExact((String[]) null); + }); } // ---- incorrect array element count ---- - @Test(expectedExceptions = {IllegalArgumentException.class}) - public static void testAsSpreaderPosInvokeWithBadElementCount() throws Throwable { + @Test + public void testAsSpreaderPosInvokeWithBadElementCount() throws Throwable { MethodHandle spreader = MH_spread.asSpreader(1, int[].class, 3); - spreader.invoke("A", new int[]{1, 2}, "B"); + assertThrows(IllegalArgumentException.class, () -> spreader.invoke("A", new int[]{1, 2}, "B")); } - @Test(expectedExceptions = {IllegalArgumentException.class}) - public static void testAsSpreaderInvokeWithBadElementCount() throws Throwable { + @Test + public void testAsSpreaderInvokeWithBadElementCount() throws Throwable { MethodHandle spreader = MH_String_equals.asSpreader(String[].class, 2); - assert (!(boolean) spreader.invokeExact(new String[]{"me", "thee"})); - boolean eq = (boolean) spreader.invokeExact(new String[0]); + assertFalse((boolean) spreader.invokeExact(new String[]{"me", "thee"})); + assertThrows(IllegalArgumentException.class, () -> { + boolean eq = (boolean) spreader.invokeExact(new String[0]); + }); } // ---- spread no argument ---- @Test - public static void testAsSpreaderPosInvokeWithZeroLength() throws Throwable { + public void testAsSpreaderPosInvokeWithZeroLength() throws Throwable { MethodHandle spreader = MH_spread.asSpreader(1, int[].class, 0); - assert("A123B".equals(spreader.invoke("A", (int[])null, 1, 2, 3, "B"))); + assertEquals("A123B", spreader.invoke("A", (int[]) null, 1, 2, 3, "B")); } @Test - public static void testAsSpreaderInvokeWithZeroLength() throws Throwable { + public void testAsSpreaderInvokeWithZeroLength() throws Throwable { MethodHandle spreader = MH_String_equals.asSpreader(String[].class, 0); - assert ((boolean) spreader.invokeExact("me", (Object)"me", new String[0])); + assertTrue((boolean) spreader.invokeExact("me", (Object)"me", new String[0])); boolean eq = (boolean) spreader.invokeExact("me", (Object)"me", (String[]) null); } // ---- invokers with null method/var handle argument ---- - @Test(expectedExceptions = {NullPointerException.class}) - public static void testInvokerWithNull() throws Throwable { + @Test + public void testInvokerWithNull() throws Throwable { MethodType type = methodType(int.class, int.class, int.class); MethodHandle invoker = MethodHandles.invoker(type); - assert((int) invoker.invoke(MH_add, 1, 2) == 3); - int sum = (int)invoker.invoke((MethodHandle)null, 1, 2); + assertEquals(3, (int) invoker.invoke(MH_add, 1, 2)); + assertThrows(NullPointerException.class, () -> { + int sum = (int)invoker.invoke((MethodHandle)null, 1, 2); + }); } - @Test(expectedExceptions = {NullPointerException.class}) - public static void testExactInvokerWithNull() throws Throwable { + @Test + public void testExactInvokerWithNull() throws Throwable { MethodType type = methodType(int.class, int.class, int.class); MethodHandle invoker = MethodHandles.exactInvoker(type); - assert((int) invoker.invoke(MH_add, 1, 2) == 3); - int sum = (int)invoker.invokeExact((MethodHandle)null, 1, 2); + assertEquals(3, (int) invoker.invoke(MH_add, 1, 2)); + assertThrows(NullPointerException.class, () -> { + int sum = (int)invoker.invokeExact((MethodHandle)null, 1, 2); + }); } - @Test(expectedExceptions = {NullPointerException.class}) - public static void testSpreadInvokerWithNull() throws Throwable { + @Test + public void testSpreadInvokerWithNull() throws Throwable { MethodType type = methodType(boolean.class, String.class, String.class); MethodHandle invoker = MethodHandles.spreadInvoker(type, 0); - assert ((boolean) invoker.invoke(MH_String_equals, new String[]{"me", "me"})); - boolean eq = (boolean) invoker.invoke((MethodHandle)null, new String[]{"me", "me"}); + assertTrue((boolean) invoker.invoke(MH_String_equals, new String[]{"me", "me"})); + assertThrows(NullPointerException.class, () -> { + boolean eq = (boolean) invoker.invoke((MethodHandle)null, new String[]{"me", "me"}); + }); } - @Test(expectedExceptions = {NullPointerException.class}) - public static void testVarHandleInvokerWithNull() throws Throwable { + @Test + public void testVarHandleInvokerWithNull() throws Throwable { VarHandle.AccessMode am = VarHandle.AccessMode.GET; MethodHandle invoker = MethodHandles.varHandleInvoker(am, VH_array.accessModeType(am)); - assert ((int) invoker.invoke(VH_array, array, 3) == 3); - int value = (int)invoker.invoke((VarHandle)null, array, 3); + assertEquals(3, (int) invoker.invoke(VH_array, array, 3)); + assertThrows(NullPointerException.class, () -> { + int value = (int)invoker.invoke((VarHandle)null, array, 3); + }); } - @Test(expectedExceptions = {NullPointerException.class}) - public static void testVarHandleExactInvokerWithNull() throws Throwable { + @Test + public void testVarHandleExactInvokerWithNull() throws Throwable { VarHandle.AccessMode am = VarHandle.AccessMode.GET; MethodHandle invoker = MethodHandles.varHandleExactInvoker(am, VH_array.accessModeType(am)); - assert ((int) invoker.invoke(VH_array, array, 3) == 3); - int value = (int)invoker.invokeExact((VarHandle)null, array, 3); + assertEquals(3, (int) invoker.invoke(VH_array, array, 3)); + assertThrows(NullPointerException.class, () -> { + int value = (int)invoker.invokeExact((VarHandle)null, array, 3); + }); } static final Lookup LOOKUP = MethodHandles.lookup(); diff --git a/test/jdk/java/lang/invoke/InvokeWithArgumentsTest.java b/test/jdk/java/lang/invoke/InvokeWithArgumentsTest.java index 63a2101bd67..3a705aca699 100644 --- a/test/jdk/java/lang/invoke/InvokeWithArgumentsTest.java +++ b/test/jdk/java/lang/invoke/InvokeWithArgumentsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,19 +23,19 @@ /* @test * @summary basic tests for MethodHandle.invokeWithArguments - * @run testng test.java.lang.invoke.InvokeWithArgumentsTest + * @run junit test.java.lang.invoke.InvokeWithArgumentsTest */ package test.java.lang.invoke; -import org.testng.Assert; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.WrongMethodTypeException; import static java.lang.invoke.MethodType.methodType; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; public class InvokeWithArgumentsTest { static final MethodHandles.Lookup L = MethodHandles.lookup(); @@ -49,10 +49,7 @@ public class InvokeWithArgumentsTest { MethodHandle mh = L.findStatic(L.lookupClass(), "arity", methodType(Object[].class, Object.class, Object.class, Object[].class)); - try { - mh.invokeWithArguments(""); - Assert.fail("WrongMethodTypeException expected"); - } catch (WrongMethodTypeException e) {} + assertThrows(WrongMethodTypeException.class, () -> mh.invokeWithArguments("")); } static Object[] passThrough(String... a) { @@ -72,10 +69,10 @@ public class InvokeWithArgumentsTest { // Note: the actual array is not preserved, the elements will be // unpacked and then packed into a new array before invoking the method - String[] expected = (String[]) mh.invokeWithArguments(actual); + String[] result = (String[]) mh.invokeWithArguments(actual); - Assert.assertTrue(actual != expected, "Array should not pass through"); - Assert.assertEquals(actual, expected, "Array contents should be equal"); + assertNotSame(actual, result, "Array should not pass through"); + assertArrayEquals(actual, result, "Array contents should be equal"); } @Test @@ -89,8 +86,8 @@ public class InvokeWithArgumentsTest { // will cast to Object become the single element of a new Object[] array Object[] expected = (Object[]) mh.invokeWithArguments("", actual); - Assert.assertEquals(1, expected.length, "Array should contain just one element"); - Assert.assertTrue(actual == expected[0], "Array should pass through"); + assertEquals(1, expected.length, "Array should contain just one element"); + assertSame(actual, expected[0], "Array should pass through"); } static void intArray(int... a) { @@ -100,20 +97,14 @@ public class InvokeWithArgumentsTest { public void testPrimitiveArrayWithNull() throws Throwable { MethodHandle mh = L.findStatic(L.lookupClass(), "intArray", methodType(void.class, int[].class)); - try { - mh.invokeWithArguments(null, null); - Assert.fail("NullPointerException expected"); - } catch (NullPointerException e) {} + assertThrows(NullPointerException.class, () -> mh.invokeWithArguments(null, null)); } @Test public void testPrimitiveArrayWithRef() throws Throwable { MethodHandle mh = L.findStatic(L.lookupClass(), "intArray", methodType(void.class, int[].class)); - try { - mh.invokeWithArguments("A", "B"); - Assert.fail("ClassCastException expected"); - } catch (ClassCastException e) {} + assertThrows(ClassCastException.class, () -> mh.invokeWithArguments("A", "B")); } @@ -127,9 +118,6 @@ public class InvokeWithArgumentsTest { // All numbers, should not throw mh.invokeWithArguments(1, 1.0, 1.0F, 1L); - try { - mh.invokeWithArguments("A"); - Assert.fail("ClassCastException expected"); - } catch (ClassCastException e) {} + assertThrows(ClassCastException.class, () -> mh.invokeWithArguments("A")); } } diff --git a/test/jdk/java/lang/invoke/JavaDocExamplesTest.java b/test/jdk/java/lang/invoke/JavaDocExamplesTest.java index 53257d9876d..0fa2614c83f 100644 --- a/test/jdk/java/lang/invoke/JavaDocExamplesTest.java +++ b/test/jdk/java/lang/invoke/JavaDocExamplesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /* @test * @summary example code used in javadoc for java.lang.invoke API * @compile JavaDocExamplesTest.java - * @run testng/othervm test.java.lang.invoke.JavaDocExamplesTest + * @run junit/othervm test.java.lang.invoke.JavaDocExamplesTest */ package test.java.lang.invoke; @@ -36,8 +36,8 @@ import static java.lang.invoke.MethodType.*; import java.util.*; -import org.testng.*; -import org.testng.annotations.*; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; /** * @author jrose @@ -350,14 +350,14 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum")); static void assertEquals(Object exp, Object act) { if (verbosity > 0) System.out.println("result: "+act); - Assert.assertEquals(exp, act); + Assertions.assertEquals(exp, act); } static void assertTrue(boolean b) { if (verbosity > 0) { System.out.println("result: " + b); } - Assert.assertTrue(b); + Assertions.assertTrue(b); } @Test public void testMethodHandlesSummary() throws Throwable { diff --git a/test/jdk/java/lang/invoke/JavaUtilConcurrentLookupTest.java b/test/jdk/java/lang/invoke/JavaUtilConcurrentLookupTest.java index 9715de8fd46..a9a6861bc05 100644 --- a/test/jdk/java/lang/invoke/JavaUtilConcurrentLookupTest.java +++ b/test/jdk/java/lang/invoke/JavaUtilConcurrentLookupTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,12 +25,11 @@ * @summary Tests that Lookup can be produced from classes under java.util.concurrent * @bug 8154447 * @compile/module=java.base java/util/concurrent/LookupTester.java - * @run testng/othervm JavaUtilConcurrentLookupTest + * @run junit/othervm JavaUtilConcurrentLookupTest */ -import org.testng.annotations.Test; - import java.util.concurrent.LookupTester; +import org.junit.jupiter.api.Test; public class JavaUtilConcurrentLookupTest { diff --git a/test/jdk/java/lang/invoke/LoopCombinatorTest.java b/test/jdk/java/lang/invoke/LoopCombinatorTest.java index 15fb9d320a3..91a752f2666 100644 --- a/test/jdk/java/lang/invoke/LoopCombinatorTest.java +++ b/test/jdk/java/lang/invoke/LoopCombinatorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * 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 @@ * @bug 8154751 * @bug 8154754 * @bug 8167974 - * @run testng/othervm -ea -esa test.java.lang.invoke.LoopCombinatorTest + * @run junit/othervm -ea -esa test.java.lang.invoke.LoopCombinatorTest */ package test.java.lang.invoke; @@ -45,9 +45,12 @@ import java.util.*; import static java.lang.invoke.MethodType.methodType; -import static org.testng.AssertJUnit.*; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; -import org.testng.annotations.*; +import static org.junit.jupiter.api.Assertions.*; /** * Tests for the loop combinators introduced in JEP 274. @@ -57,7 +60,7 @@ public class LoopCombinatorTest { static final Lookup LOOKUP = MethodHandles.lookup(); @Test - public static void testLoopFac() throws Throwable { + public void testLoopFac() throws Throwable { MethodHandle[] counterClause = new MethodHandle[]{Fac.MH_zero, Fac.MH_inc}; MethodHandle[] accumulatorClause = new MethodHandle[]{Fac.MH_one, Fac.MH_mult, Fac.MH_pred, Fac.MH_fin}; MethodHandle loop = MethodHandles.loop(counterClause, accumulatorClause); @@ -66,7 +69,7 @@ public class LoopCombinatorTest { } @Test - public static void testLoopFacNullInit() throws Throwable { + public void testLoopFacNullInit() throws Throwable { // null initializer for counter, should initialize to 0 MethodHandle[] counterClause = new MethodHandle[]{null, Fac.MH_inc}; MethodHandle[] accumulatorClause = new MethodHandle[]{Fac.MH_one, Fac.MH_mult, Fac.MH_pred, Fac.MH_fin}; @@ -76,7 +79,7 @@ public class LoopCombinatorTest { } @Test - public static void testLoopNullInit() throws Throwable { + public void testLoopNullInit() throws Throwable { // null initializer for counter, should initialize to 0, one-clause loop MethodHandle[] counterClause = new MethodHandle[]{null, Loop.MH_inc, Loop.MH_pred, Loop.MH_fin}; MethodHandle loop = MethodHandles.loop(counterClause); @@ -85,7 +88,7 @@ public class LoopCombinatorTest { } @Test - public static void testLoopVoid1() throws Throwable { + public void testLoopVoid1() throws Throwable { // construct a post-checked loop that only does one iteration and has a void body and void local state MethodHandle loop = MethodHandles.loop(new MethodHandle[]{Empty.MH_f, Empty.MH_f, Empty.MH_pred, null}); assertEquals(MethodType.methodType(void.class), loop.type()); @@ -93,7 +96,7 @@ public class LoopCombinatorTest { } @Test - public static void testLoopVoid2() throws Throwable { + public void testLoopVoid2() throws Throwable { // construct a post-checked loop that only does one iteration and has a void body and void local state, // initialized implicitly from the step type MethodHandle loop = MethodHandles.loop(new MethodHandle[]{null, Empty.MH_f, Empty.MH_pred, null}); @@ -102,7 +105,7 @@ public class LoopCombinatorTest { } @Test - public static void testLoopVoid3() throws Throwable { + public void testLoopVoid3() throws Throwable { // construct a post-checked loop that only does one iteration and has a void body and void local state, // and that has a void finalizer MethodHandle loop = MethodHandles.loop(new MethodHandle[]{null, Empty.MH_f, Empty.MH_pred, Empty.MH_f}); @@ -111,7 +114,7 @@ public class LoopCombinatorTest { } @Test - public static void testLoopFacWithVoidState() throws Throwable { + public void testLoopFacWithVoidState() throws Throwable { // like testLoopFac, but with additional void state that outputs a dot MethodHandle[] counterClause = new MethodHandle[]{Fac.MH_zero, Fac.MH_inc}; MethodHandle[] accumulatorClause = new MethodHandle[]{Fac.MH_one, Fac.MH_mult, Fac.MH_pred, Fac.MH_fin}; @@ -122,7 +125,7 @@ public class LoopCombinatorTest { } @Test - public static void testLoopVoidInt() throws Throwable { + public void testLoopVoidInt() throws Throwable { // construct a post-checked loop that only does one iteration and has a void body and void local state, // and that returns a constant MethodHandle loop = MethodHandles.loop(new MethodHandle[]{null, Empty.MH_f, Empty.MH_pred, Empty.MH_c}); @@ -131,7 +134,7 @@ public class LoopCombinatorTest { } @Test - public static void testLoopWithVirtuals() throws Throwable { + public void testLoopWithVirtuals() throws Throwable { // construct a loop (to calculate factorial) that uses a mix of static and virtual methods MethodHandle[] counterClause = new MethodHandle[]{null, LoopWithVirtuals.permute(LoopWithVirtuals.MH_inc)}; MethodHandle[] accumulatorClause = new MethodHandle[]{ @@ -147,7 +150,7 @@ public class LoopCombinatorTest { } @Test - public static void testLoopOmitPred() throws Throwable { + public void testLoopOmitPred() throws Throwable { // construct a loop to calculate factorial that omits a predicate MethodHandle[] counterClause = new MethodHandle[]{null, Fac.MH_inc, null, Fac.MH_fin}; MethodHandle[] accumulatorClause = new MethodHandle[]{Fac.MH_one, Fac.MH_mult, Fac.MH_pred, Fac.MH_fin}; @@ -156,7 +159,6 @@ public class LoopCombinatorTest { assertEquals(120, loop.invoke(5)); } - @DataProvider static Object[][] negativeTestData() { MethodHandle i0 = MethodHandles.constant(int.class, 0); MethodHandle ii = MethodHandles.dropArguments(i0, 0, int.class, int.class); @@ -214,36 +216,36 @@ public class LoopCombinatorTest { } } - @Test(dataProvider = "negativeTestData") - public static void testLoopNegative(MethodHandle[][] clauses, String expectedMessage) throws Throwable { - boolean caught = false; - try { - MH_loop.invokeWithArguments((Object[]) clauses); - } catch (IllegalArgumentException iae) { - assertEquals(expectedMessage, iae.getMessage()); - caught = true; - } - assertTrue(caught); + @ParameterizedTest + @MethodSource("negativeTestData") + public void testLoopNegative(MethodHandle[][] clauses, String expectedMessage) throws Throwable { + var iae = assertThrows(IllegalArgumentException.class, () -> MH_loop.invokeWithArguments((Object[]) clauses)); + assertEquals(expectedMessage, iae.getMessage()); } - @Test(dataProvider = "whileLoopTestData") - public static void testWhileLoop(MethodHandle MH_zero, - MethodHandle MH_pred, - MethodHandle MH_step, - String messageOrNull) throws Throwable { + @ParameterizedTest + @MethodSource("whileLoopPassData") + public void testWhileLoop(MethodHandle MH_zero, + MethodHandle MH_pred, + MethodHandle MH_step) throws Throwable { // int i = 0; while (i < limit) { ++i; } return i; => limit - try { - MethodHandle loop = MethodHandles.whileLoop(MH_zero, MH_pred, MH_step); - assert messageOrNull == null; - if (MH_step.type().equals(While.MH_step.type())) - assertEquals(While.MT_while, loop.type()); - assertEquals(MH_step.type().dropParameterTypes(0, 1), loop.type()); - while (loop.type().parameterCount() > 1) loop = snip(loop); - assertEquals(23, loop.invoke(23)); - } catch (IllegalArgumentException iae) { - assert messageOrNull != null; - assertEqualsFIXME(messageOrNull, iae.getMessage()); - } + MethodHandle loop = MethodHandles.whileLoop(MH_zero, MH_pred, MH_step); + if (MH_step.type().equals(While.MH_step.type())) + assertEquals(While.MT_while, loop.type()); + assertEquals(MH_step.type().dropParameterTypes(0, 1), loop.type()); + while (loop.type().parameterCount() > 1) loop = snip(loop); + assertEquals(23, loop.invoke(23)); + } + + @ParameterizedTest + @MethodSource("whileLoopFailData") + public void testWhileLoopFail(MethodHandle MH_zero, + MethodHandle MH_pred, + MethodHandle MH_step, + String message) throws Throwable { + // int i = 0; while (i < limit) { ++i; } return i; => limit + var iae = assertThrows(IllegalArgumentException.class, () -> MethodHandles.whileLoop(MH_zero, MH_pred, MH_step)); + assertEqualsFIXME(message, iae.getMessage()); } static void assertEqualsFIXME(String expect, String actual) { @@ -253,8 +255,7 @@ public class LoopCombinatorTest { } } - @DataProvider - static Object[][] whileLoopTestData() { + static Object[][] whileLoopPassData() { MethodHandle zeroI = While.MH_zero, zeroX = snip(zeroI), @@ -268,28 +269,44 @@ public class LoopCombinatorTest { ; return new Object[][] { // normal while loop clauses, perhaps with effectively-identical reductions - {zeroI, predII, stepII, null}, - {zeroX, predII, stepII, null}, - {null, predII, stepII, null}, + {zeroI, predII, stepII}, + {zeroX, predII, stepII}, + {null, predII, stepII}, // expanded while loop clauses - {zeroIB, predIIB, stepIIB, null}, - {zeroI, predIIB, stepIIB, null}, - {null, predIIB, stepIIB, null}, - {zeroIB, predII, stepIIB, null}, - {zeroX, predII, stepIIB, null}, - {null, predII, stepIIB, null}, - // short step clauses cause errors - {zeroI, predII, stepIX, "loop predicate must match: (int,int)boolean != (int)boolean"}, - {zeroIB, predIX, stepIX, "loop initializer must match: (int,byte)int != ()int"}, - // bad body type - {zeroI, predII, tweak(stepII, -1, char.class), "body function must match: (int,int)char != (char,int,int)char"}, - {zeroI, predII, tweak(stepII, 0, char.class), "body function must match: (char,int)int != (int,char,int)int"}, - // bad pred type - {zeroI, tweak(predII, -1, char.class), stepII, "loop predicate must match: (int,int)char != (int,int)boolean"}, - {zeroI, tweak(predII, 0, char.class), stepII, "loop predicate must match: (char,int)boolean != (int,int)boolean"}, - // bad init type - {tweak(zeroI, -1, char.class), predII, stepII, "loop initializer must match: (int)char != (int)int"}, - {tweak(zeroI, 0, char.class), predII, stepII, "loop initializer must match: (char)int != (int)int"}, + {zeroIB, predIIB, stepIIB}, + {zeroI, predIIB, stepIIB}, + {null, predIIB, stepIIB}, + {zeroIB, predII, stepIIB}, + {zeroX, predII, stepIIB}, + {null, predII, stepIIB}, + }; + } + + static Object[][] whileLoopFailData() { + MethodHandle + zeroI = While.MH_zero, + zeroX = snip(zeroI), + zeroIB = slap(zeroI, byte.class), + predII = While.MH_pred, + predIX = snip(predII), + predIIB = slap(predII, byte.class), + stepII = While.MH_step, + stepIX = snip(stepII), + stepIIB = slap(stepII, byte.class) + ; + return new Object[][] { + // short step clauses cause errors + {zeroI, predII, stepIX, "loop predicate must match: (int,int)boolean != (int)boolean"}, + {zeroIB, predIX, stepIX, "loop initializer must match: (int,byte)int != ()int"}, + // bad body type + {zeroI, predII, tweak(stepII, -1, char.class), "body function must match: (int,int)char != (char,int,int)char"}, + {zeroI, predII, tweak(stepII, 0, char.class), "body function must match: (char,int)int != (int,char,int)int"}, + // bad pred type + {zeroI, tweak(predII, -1, char.class), stepII, "loop predicate must match: (int,int)char != (int,int)boolean"}, + {zeroI, tweak(predII, 0, char.class), stepII, "loop predicate must match: (char,int)boolean != (int,int)boolean"}, + // bad init type + {tweak(zeroI, -1, char.class), predII, stepII, "loop initializer must match: (int)char != (int)int"}, + {tweak(zeroI, 0, char.class), predII, stepII, "loop initializer must match: (char)int != (int)int"}, }; } @@ -323,53 +340,50 @@ public class LoopCombinatorTest { } @Test - public static void testWhileLoopNoIteration() throws Throwable { + public void testWhileLoopNoIteration() throws Throwable { // a while loop that never executes its body because the predicate evaluates to false immediately MethodHandle loop = MethodHandles.whileLoop(While.MH_initString, While.MH_predString, While.MH_stepString); assertEquals(While.MT_string, loop.type()); assertEquals("a", loop.invoke()); } - @Test(dataProvider = "whileLoopTestData") - public static void testDoWhileLoop(MethodHandle MH_zero, - MethodHandle MH_pred, - MethodHandle MH_step, - String messageOrNull) throws Throwable { + @ParameterizedTest + @MethodSource("whileLoopPassData") + public void testDoWhileLoopPass(MethodHandle MH_zero, + MethodHandle MH_pred, + MethodHandle MH_step) throws Throwable { // int i = 0; do { ++i; } while (i < limit); return i; => limit - try { - MethodHandle loop = MethodHandles.doWhileLoop(MH_zero, MH_step, MH_pred); - assert messageOrNull == null; - if (MH_step.type().equals(While.MH_step.type())) - assertEquals(While.MT_while, loop.type()); - assertEquals(MH_step.type().dropParameterTypes(0, 1), loop.type()); - while (loop.type().parameterCount() > 1) loop = snip(loop); - assertEquals(23, loop.invoke(23)); - } catch (IllegalArgumentException iae) { - assert messageOrNull != null; - if (!messageOrNull.equals(iae.getMessage())) { - // just issue a warning - System.out.println("*** "+messageOrNull+"\n != "+iae.getMessage()); - } - } + MethodHandle loop = MethodHandles.doWhileLoop(MH_zero, MH_step, MH_pred); + if (MH_step.type().equals(While.MH_step.type())) + assertEquals(While.MT_while, loop.type()); + assertEquals(MH_step.type().dropParameterTypes(0, 1), loop.type()); + while (loop.type().parameterCount() > 1) loop = snip(loop); + assertEquals(23, loop.invoke(23)); + } + + @ParameterizedTest + @MethodSource("whileLoopFailData") + public void testDoWhileLoopFail(MethodHandle MH_zero, + MethodHandle MH_pred, + MethodHandle MH_step, + String message) throws Throwable { + // int i = 0; do { ++i; } while (i < limit); return i; => limit + var iae = assertThrows(IllegalArgumentException.class, () -> MethodHandles.doWhileLoop(MH_zero, MH_step, MH_pred)); + assertEqualsFIXME(message, iae.getMessage()); } @Test - public static void testDoWhileBadInit() throws Throwable { - boolean caught = false; - try { - While w = new While(); - MethodHandle loop = MethodHandles.doWhileLoop(MethodHandles.empty(methodType(char.class)), - While.MH_voidBody.bindTo(w), - While.MH_voidPred.bindTo(w)); - } catch (IllegalArgumentException iae) { - assertEquals("loop initializer must match: ()char != (int)void", iae.getMessage()); - caught = true; - } - assertTrue(caught); + public void testDoWhileBadInit() throws Throwable { + While w = new While(); + var iae = assertThrows(IllegalArgumentException.class, () -> + MethodHandles.doWhileLoop(MethodHandles.empty(methodType(char.class)), + While.MH_voidBody.bindTo(w), + While.MH_voidPred.bindTo(w))); + assertEquals("loop initializer must match: ()char != (int)void", iae.getMessage()); } @Test - public static void testWhileZip() throws Throwable { + public void testWhileZip() throws Throwable { MethodHandle loop = MethodHandles.doWhileLoop(While.MH_zipInitZip, While.MH_zipStep, While.MH_zipPred); assertEquals(While.MT_zip, loop.type()); List a = Arrays.asList("a", "b", "c", "d"); @@ -379,22 +393,17 @@ public class LoopCombinatorTest { } @Test - public static void testWhileBadInit() throws Throwable { - boolean caught = false; - try { - While w = new While(); - MethodHandle loop = MethodHandles.whileLoop(MethodHandles.empty(methodType(void.class, char.class)), - While.MH_voidPred.bindTo(w), - While.MH_voidBody.bindTo(w)); - } catch (IllegalArgumentException iae) { - assertEquals("loop initializer must match: (char)void != (int)void", iae.getMessage()); - caught = true; - } - assertTrue(caught); + public void testWhileBadInit() throws Throwable { + While w = new While(); + var iae = assertThrows(IllegalArgumentException.class, () -> + MethodHandles.whileLoop(MethodHandles.empty(methodType(void.class, char.class)), + While.MH_voidPred.bindTo(w), + While.MH_voidBody.bindTo(w))); + assertEquals("loop initializer must match: (char)void != (int)void", iae.getMessage()); } @Test - public static void testWhileVoidInit() throws Throwable { + public void testWhileVoidInit() throws Throwable { While w = new While(); int v = 5; MethodHandle loop = MethodHandles.whileLoop(While.MH_voidInit.bindTo(w), While.MH_voidPred.bindTo(w), @@ -405,7 +414,7 @@ public class LoopCombinatorTest { } @Test - public static void testDoWhileVoidInit() throws Throwable { + public void testDoWhileVoidInit() throws Throwable { While w = new While(); int v = 5; MethodHandle loop = MethodHandles.doWhileLoop(While.MH_voidInit.bindTo(w), While.MH_voidBody.bindTo(w), @@ -415,24 +424,25 @@ public class LoopCombinatorTest { assertEquals(v, w.i); } - @DataProvider static Object[][] nullArgs() { MethodHandle c = MethodHandles.constant(int.class, 1); return new Object[][]{{null, c}, {c, null}}; } - @Test(dataProvider = "nullArgs", expectedExceptions = NullPointerException.class) - public static void testWhileNullArgs(MethodHandle pred, MethodHandle body) { - MethodHandles.whileLoop(null, pred, body); + @ParameterizedTest + @MethodSource("nullArgs") + public void testWhileNullArgs(MethodHandle pred, MethodHandle body) { + assertThrows(NullPointerException.class, () -> MethodHandles.whileLoop(null, pred, body)); } - @Test(dataProvider = "nullArgs", expectedExceptions = NullPointerException.class) - public static void testDoWhileNullArgs(MethodHandle body, MethodHandle pred) { - MethodHandles.whileLoop(null, body, pred); + @ParameterizedTest + @MethodSource("nullArgs") + public void testDoWhileNullArgs(MethodHandle body, MethodHandle pred) { + assertThrows(NullPointerException.class, () -> MethodHandles.whileLoop(null, body, pred)); } @Test - public static void testCountedLoop() throws Throwable { + public void testCountedLoop() throws Throwable { // String s = "Lambdaman!"; for (int i = 0; i < 13; ++i) { s = "na " + s; } return s; => a variation on a well known theme MethodHandle fit13 = MethodHandles.dropArguments(MethodHandles.constant(int.class, 13), 0, String.class); MethodHandle loop = MethodHandles.countedLoop(fit13, Counted.MH_start, Counted.MH_step); @@ -441,7 +451,7 @@ public class LoopCombinatorTest { } @Test - public static void testCountedLoopVoidInit() throws Throwable { + public void testCountedLoopVoidInit() throws Throwable { MethodHandle fit5 = MethodHandles.constant(int.class, 5); for (int i = 0; i < 8; i++) { MethodHandle zero = MethodHandles.zero(void.class); @@ -465,7 +475,7 @@ public class LoopCombinatorTest { } @Test - public static void testCountedArrayLoop() throws Throwable { + public void testCountedArrayLoop() throws Throwable { // int[] a = new int[]{0}; for (int i = 0; i < 13; ++i) { ++a[0]; } => a[0] == 13 MethodHandle fit13 = MethodHandles.dropArguments(MethodHandles.constant(int.class, 13), 0, int[].class); MethodHandle loop = MethodHandles.countedLoop(fit13, null, Counted.MH_stepUpdateArray); @@ -476,37 +486,30 @@ public class LoopCombinatorTest { } @Test - public static void testCountedPrintingLoop() throws Throwable { + public void testCountedPrintingLoop() throws Throwable { MethodHandle fit5 = MethodHandles.constant(int.class, 5); MethodHandle loop = MethodHandles.countedLoop(fit5, null, Counted.MH_printHello); assertEquals(Counted.MT_countedPrinting, loop.type()); loop.invoke(); } - @Test(expectedExceptions = NullPointerException.class) - public static void testCountedLoopNullBody() throws Throwable { + @Test + public void testCountedLoopNullBody() throws Throwable { MethodHandle h5 = MethodHandles.constant(int.class, 5); MethodHandle h13 = MethodHandles.constant(int.class, 13); - MethodHandle loop = MethodHandles.countedLoop(h5, h13, null); - assertEquals(methodType(int.class), loop.type()); - assertEquals(13, loop.invoke()); + assertThrows(NullPointerException.class, () -> MethodHandles.countedLoop(h5, h13, null)); } - @Test(expectedExceptions = NullPointerException.class) - public static void testCountedLoopNullIterations() throws Throwable { - MethodHandle loop = MethodHandles.countedLoop(null, null, null); - assertEquals(methodType(void.class), loop.type()); - loop.invoke(); + @Test + public void testCountedLoopNullIterations() throws Throwable { + assertThrows(NullPointerException.class, () -> MethodHandles.countedLoop(null, null, null)); } - @Test(expectedExceptions = NullPointerException.class) - public static void testCountedLoopNullInitAndBody() throws Throwable { - MethodHandle loop = MethodHandles.countedLoop(MethodHandles.constant(int.class, 5), null, null); - assertEquals(methodType(void.class), loop.type()); - loop.invoke(); + @Test + public void testCountedLoopNullInitAndBody() throws Throwable { + assertThrows(NullPointerException.class, () -> MethodHandles.countedLoop(MethodHandles.constant(int.class, 5), null, null)); } - @DataProvider static Object[][] countedLoopBodyParameters() { Class V = String.class, I = int.class, A = List.class; // return types are of these forms: @@ -531,8 +534,9 @@ public class LoopCombinatorTest { }; } - @Test(dataProvider = "countedLoopBodyParameters") - public static void testCountedLoopBodyParameters(MethodType countType, MethodType initType, MethodType bodyType) throws Throwable { + @ParameterizedTest + @MethodSource("countedLoopBodyParameters") + public void testCountedLoopBodyParameters(MethodType countType, MethodType initType, MethodType bodyType) throws Throwable { MethodHandle loop = MethodHandles.countedLoop( MethodHandles.empty(countType), initType == null ? null : MethodHandles.empty(initType), @@ -546,13 +550,14 @@ public class LoopCombinatorTest { assertEquals(expectType, loop.type()); } - @Test(dataProvider = "countedLoopBodyParameters") - public static void testCountedLoopBodyParametersNullInit(MethodType countType, MethodType initType, MethodType bodyType) throws Throwable { + @ParameterizedTest + @MethodSource("countedLoopBodyParameters") + public void testCountedLoopBodyParametersNullInit(MethodType countType, MethodType initType, MethodType bodyType) throws Throwable { testCountedLoopBodyParameters(countType, null, bodyType); } @Test - public static void testCountedLoopStateInitializedToNull() throws Throwable { + public void testCountedLoopStateInitializedToNull() throws Throwable { MethodHandle loop = MethodHandles.countedLoop(MethodHandles.constant(int.class, 5), MethodHandles.empty(methodType(String.class)), Counted.MH_stateBody); assertEquals(Counted.MT_bodyDeterminesState, loop.type()); @@ -560,7 +565,7 @@ public class LoopCombinatorTest { } @Test - public static void testCountedLoopArgsDefinedByIterations() throws Throwable { + public void testCountedLoopArgsDefinedByIterations() throws Throwable { MethodHandle iterations = MethodHandles.dropArguments(MethodHandles.constant(int.class, 3), 0, String.class); MethodHandle loop = MethodHandles.countedLoop(iterations, @@ -570,7 +575,7 @@ public class LoopCombinatorTest { } @Test - public static void testCountedRangeLoop() throws Throwable { + public void testCountedRangeLoop() throws Throwable { // String s = "Lambdaman!"; for (int i = -5; i < 8; ++i) { s = "na " + s; } return s; => a well known theme MethodHandle fitm5 = MethodHandles.dropArguments(Counted.MH_m5, 0, String.class); MethodHandle fit8 = MethodHandles.dropArguments(Counted.MH_8, 0, String.class); @@ -580,7 +585,7 @@ public class LoopCombinatorTest { } @Test - public static void testCountedLoopCounterInit() throws Throwable { + public void testCountedLoopCounterInit() throws Throwable { // int x = 0; for (int i = 0; i < 5; ++i) { x += i; } return x; => 10 // (only if counter's first value in body is 0) MethodHandle iter = MethodHandles.constant(int.class, 5); @@ -592,7 +597,7 @@ public class LoopCombinatorTest { } @Test - public static void testCountedLoopEmpty() throws Throwable { + public void testCountedLoopEmpty() throws Throwable { // for (int i = 0; i < 5; ++i) { /* empty */ } MethodHandle loop = MethodHandles.countedLoop(MethodHandles.constant(int.class, 5), null, MethodHandles.empty(methodType(void.class, int.class))); @@ -601,7 +606,7 @@ public class LoopCombinatorTest { } @Test - public static void testCountedRangeLoopEmpty() throws Throwable { + public void testCountedRangeLoopEmpty() throws Throwable { // for (int i = -5; i < 5; ++i) { /* empty */ } MethodHandle loop = MethodHandles.countedLoop(MethodHandles.constant(int.class, -5), MethodHandles.constant(int.class, 5), null, MethodHandles.empty(methodType(void.class, int.class))); @@ -609,7 +614,6 @@ public class LoopCombinatorTest { loop.invoke(); } - @DataProvider static Object[][] countedLoopNegativeData() { MethodHandle dummy = MethodHandles.zero(void.class); MethodHandle one = MethodHandles.constant(int.class, 1); @@ -629,35 +633,30 @@ public class LoopCombinatorTest { }; } - @Test(dataProvider = "countedLoopNegativeData") - public static void testCountedLoopNegative(MethodHandle start, MethodHandle end, MethodHandle init, + @ParameterizedTest + @MethodSource("countedLoopNegativeData") + @Disabled //%%%FIXME%%%% + public void testCountedLoopNegative(MethodHandle start, MethodHandle end, MethodHandle init, MethodHandle body, String msg) { - if (true) return; //%%%FIXME%%%% - boolean caught = false; - try { - MethodHandles.countedLoop(start, end, init, body); - } catch (IllegalArgumentException iae) { - assertEquals(msg, iae.getMessage()); - caught = true; - } - assertTrue(caught); + var iae = assertThrows(IllegalArgumentException.class, () -> MethodHandles.countedLoop(start, end, init, body)); + assertEquals(msg, iae.getMessage()); } @Test - public static void testIterateSum() throws Throwable { + public void testIterateSum() throws Throwable { // Integer[] a = new Integer[]{1,2,3,4,5,6}; int sum = 0; for (int e : a) { sum += e; } return sum; => 21 MethodHandle loop = MethodHandles.iteratedLoop(Iterate.MH_sumIterator, Iterate.MH_sumInit, Iterate.MH_sumStep); assertEquals(Iterate.MT_sum, loop.type()); assertEquals(21, loop.invoke(new Integer[]{1, 2, 3, 4, 5, 6})); } - @DataProvider static Object[][] iteratorInits() { return new Object[][]{{Iterate.MH_iteratorFromList}, {Iterate.MH_iteratorFromIterable}, {null}}; } - @Test(dataProvider = "iteratorInits") - public static void testIterateReverse(MethodHandle iterator) throws Throwable { + @ParameterizedTest + @MethodSource("iteratorInits") + public void testIterateReverse(MethodHandle iterator) throws Throwable { // this test uses List as its loop state type; don't try to change that if (iterator != null) iterator = iterator.asType(iterator.type().changeParameterType(0, List.class)); @@ -685,8 +684,9 @@ public class LoopCombinatorTest { } } - @Test(dataProvider = "iteratorInits") - public static void testIterateLength(MethodHandle iterator) throws Throwable { + @ParameterizedTest + @MethodSource("iteratorInits") + public void testIterateLength(MethodHandle iterator) throws Throwable { MethodHandle body = Iterate.MH_lengthStep; MethodHandle init = Iterate.MH_lengthInit; MethodType expectedType = Iterate.MT_length; @@ -708,8 +708,9 @@ public class LoopCombinatorTest { } } - @Test(dataProvider = "iteratorInits") - public static void testIterateMap(MethodHandle iterator) throws Throwable { + @ParameterizedTest + @MethodSource("iteratorInits") + public void testIterateMap(MethodHandle iterator) throws Throwable { MethodHandle body = Iterate.MH_mapStep; MethodHandle init = Iterate.MH_mapInit; MethodType expectedType = Iterate.MT_map; @@ -731,8 +732,9 @@ public class LoopCombinatorTest { } } - @Test(dataProvider = "iteratorInits") - public static void testIteratePrint(MethodHandle iterator) throws Throwable { + @ParameterizedTest + @MethodSource("iteratorInits") + public void testIteratePrint(MethodHandle iterator) throws Throwable { MethodHandle body = Iterate.MH_printStep; MethodType expectedType = Iterate.MT_print; int barity = body.type().parameterCount(); @@ -747,32 +749,28 @@ public class LoopCombinatorTest { loop.invoke(Arrays.asList("hello", "world")); } - @Test(expectedExceptions = NullPointerException.class) - public static void testIterateNullBody() { - MethodHandles.iteratedLoop(MethodHandles.empty(methodType(Iterator.class, int.class)), - MethodHandles.identity(int.class), null); + @Test + public void testIterateNullBody() { + assertThrows(NullPointerException.class, () -> + MethodHandles.iteratedLoop(MethodHandles.empty(methodType(Iterator.class, int.class)), + MethodHandles.identity(int.class), null)); } - @DataProvider static Object[][] wrongIteratorTypes() { return new Object[][]{{void.class}, {Object.class}, {Iterable.class}}; } - @Test(dataProvider = "wrongIteratorTypes") - public static void testIterateVoidIterator(Class it) { - boolean caught = false; + @ParameterizedTest + @MethodSource("wrongIteratorTypes") + public void testIterateVoidIterator(Class it) { MethodType v = methodType(it); - try { - MethodHandles.iteratedLoop(MethodHandles.empty(v), null, MethodHandles.empty(v)); - } catch(IllegalArgumentException iae) { - assertEqualsFIXME("iteratedLoop first argument must have Iterator return type", iae.getMessage()); - caught = true; - } - assertTrue(caught); + var iae = assertThrows(IllegalArgumentException.class, () -> MethodHandles.iteratedLoop(MethodHandles.empty(v), null, MethodHandles.empty(v))); + assertEqualsFIXME("iteratedLoop first argument must have Iterator return type", iae.getMessage()); } - @Test(dataProvider = "iteratorInits") - public static void testIterateVoidInit(MethodHandle iterator) throws Throwable { + @ParameterizedTest + @MethodSource("iteratorInits") + public void testIterateVoidInit(MethodHandle iterator) throws Throwable { // this test uses List as its loop state type; don't try to change that if (iterator != null) iterator = iterator.asType(iterator.type().changeParameterType(0, List.class)); @@ -781,7 +779,6 @@ public class LoopCombinatorTest { loop.invoke(Arrays.asList("hello", "world")); } - @DataProvider static Object[][] iterateParameters() { MethodType i = methodType(int.class); MethodType sil_v = methodType(void.class, String.class, int.class, List.class); @@ -811,8 +808,9 @@ public class LoopCombinatorTest { }; } - @Test(dataProvider = "iterateParameters") - public static void testIterateParameters(MethodType it, MethodType in, MethodType bo, String msg) { + @ParameterizedTest + @MethodSource("iterateParameters") + public void testIterateParameters(MethodType it, MethodType in, MethodType bo, String msg) { boolean negative = !msg.isEmpty(); MethodHandle iterator = it == null ? null : MethodHandles.empty(it); MethodHandle init = in == null ? null : MethodHandles.empty(in); @@ -855,7 +853,7 @@ public class LoopCombinatorTest { } @Test - public static void testIteratorSubclass() throws Throwable { + public void testIteratorSubclass() throws Throwable { MethodHandle loop = MethodHandles.iteratedLoop(MethodHandles.empty(methodType(BogusIterator.class, List.class)), null, MethodHandles.empty(methodType(void.class, String.class, List.class))); assertEquals(methodType(void.class, List.class), loop.type()); diff --git a/test/jdk/java/lang/invoke/MethodHandleInvokeUOE.java b/test/jdk/java/lang/invoke/MethodHandleInvokeUOE.java index e728516fe03..510a65acabf 100644 --- a/test/jdk/java/lang/invoke/MethodHandleInvokeUOE.java +++ b/test/jdk/java/lang/invoke/MethodHandleInvokeUOE.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,20 +24,18 @@ /* @test * @summary Test MethodHandle::invokeExact and MethodHandle::invoke throws * UnsupportedOperationException when called via Method::invoke - * @run testng test.java.lang.invoke.MethodHandleInvokeUOE + * @run junit test.java.lang.invoke.MethodHandleInvokeUOE */ package test.java.lang.invoke; -import org.testng.*; -import org.testng.annotations.*; - import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import static java.lang.invoke.MethodType.*; +import org.junit.jupiter.api.Test; public class MethodHandleInvokeUOE { @Test diff --git a/test/jdk/java/lang/invoke/MethodHandleProxies/Driver.java b/test/jdk/java/lang/invoke/MethodHandleProxies/Driver.java index 0e9c708e8e9..2d99db46c2c 100644 --- a/test/jdk/java/lang/invoke/MethodHandleProxies/Driver.java +++ b/test/jdk/java/lang/invoke/MethodHandleProxies/Driver.java @@ -25,8 +25,8 @@ * @test * @bug 8280377 * @build m1/* m2/* Unnamed - * @run testng/othervm m1/p1.Main - * @run main/othervm Unnamed + * @run junit/othervm m1/p1.Main + * @run junit/othervm Unnamed * @summary Test MethodHandleProxies::asInterfaceInstance with a default * method with varargs */ diff --git a/test/jdk/java/lang/invoke/MethodHandleProxies/Unnamed.java b/test/jdk/java/lang/invoke/MethodHandleProxies/Unnamed.java index f60f36ca9de..8cd9a37cc2f 100644 --- a/test/jdk/java/lang/invoke/MethodHandleProxies/Unnamed.java +++ b/test/jdk/java/lang/invoke/MethodHandleProxies/Unnamed.java @@ -26,13 +26,16 @@ import java.lang.invoke.MethodHandleProxies; import java.lang.invoke.MethodHandles; import java.lang.reflect.Method; -import static org.testng.Assert.*; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; /* * Test MethodHandleProxies::asInterfaceInstance with an inaccessible interface */ public class Unnamed { - public static void main(String... args) throws Throwable { + @Test + void testInaccessible() throws Throwable { MethodHandle target = MethodHandles.constant(String.class, "test"); Class intf = Class.forName("p2.TestIntf"); Object t = MethodHandleProxies.asInterfaceInstance(intf, target); diff --git a/test/jdk/java/lang/invoke/MethodHandleProxies/m1/module-info.java b/test/jdk/java/lang/invoke/MethodHandleProxies/m1/module-info.java index 1bdeddce28f..5e0174635fb 100644 --- a/test/jdk/java/lang/invoke/MethodHandleProxies/m1/module-info.java +++ b/test/jdk/java/lang/invoke/MethodHandleProxies/m1/module-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,6 +22,6 @@ */ module m1 { requires m2; - requires org.testng; + requires org.junit.platform.console.standalone; exports p1; } diff --git a/test/jdk/java/lang/invoke/MethodHandleProxies/m1/p1/Main.java b/test/jdk/java/lang/invoke/MethodHandleProxies/m1/p1/Main.java index df71809996b..1e4ffcb4aac 100644 --- a/test/jdk/java/lang/invoke/MethodHandleProxies/m1/p1/Main.java +++ b/test/jdk/java/lang/invoke/MethodHandleProxies/m1/p1/Main.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,9 +32,8 @@ import java.util.stream.Collectors; import p2.TestIntf; -import org.testng.annotations.Test; - -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; public class Main { public interface A { @@ -57,24 +56,24 @@ public class Main { * Test the invocation of default methods with varargs */ @Test - public static void testVarargsMethods() throws Throwable { + public void testVarargsMethods() throws Throwable { MethodHandle target = MethodHandles.lookup().findStatic(Main.class, "concat", MethodType.methodType(String.class, Object[].class)); C proxy = MethodHandleProxies.asInterfaceInstance(C.class, target); - assertEquals(proxy.c("a", "b", "c"), "abc"); - assertEquals(proxy.aConcat("a", "b", "c"), "[a, b, c]"); - assertEquals(proxy.aConcat(new Object[] { "a", "b", "c" }), "[a, b, c]"); - assertEquals(proxy.bConcat(new Object[] { "a", "b", "c" }), "[a, b, c]"); + assertEquals("abc", proxy.c("a", "b", "c")); + assertEquals("[a, b, c]", proxy.aConcat("a", "b", "c")); + assertEquals("[a, b, c]", proxy.aConcat(new Object[] { "a", "b", "c" })); + assertEquals("[a, b, c]", proxy.bConcat(new Object[] { "a", "b", "c" })); } /* * Test the invocation of a default method of an accessible interface */ @Test - public static void modulePrivateInterface() { + public void modulePrivateInterface() { MethodHandle target = MethodHandles.constant(String.class, "test"); TestIntf t = MethodHandleProxies.asInterfaceInstance(TestIntf.class, target); - assertEquals(t.test(), "test"); + assertEquals("test", t.test()); } } diff --git a/test/jdk/java/lang/invoke/MethodHandles/TestDropReturn.java b/test/jdk/java/lang/invoke/MethodHandles/TestDropReturn.java index ff31dd63f0b..1b8ef6331b3 100644 --- a/test/jdk/java/lang/invoke/MethodHandles/TestDropReturn.java +++ b/test/jdk/java/lang/invoke/MethodHandles/TestDropReturn.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. * 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,33 +24,33 @@ /* * @test * @bug 8255398 - * @run testng TestDropReturn + * @run junit TestDropReturn */ -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import static java.lang.invoke.MethodType.methodType; -import static org.testng.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; public class TestDropReturn { - @Test(dataProvider = "dropReturnCases") + @ParameterizedTest + @MethodSource("dropReturnCases") public void testDropReturn(Class cls, Object testValue) throws Throwable { MethodHandle mh = MethodHandles.identity(cls); - assertEquals(mh.type(), methodType(cls, cls)); + assertEquals(methodType(cls, cls), mh.type()); Object x = mh.invoke(testValue); - assertEquals(x, testValue); + assertEquals(testValue, x); mh = MethodHandles.dropReturn(mh); - assertEquals(mh.type(), methodType(void.class, cls)); + assertEquals(methodType(void.class, cls), mh.type()); mh.invoke(testValue); // should at least work } - @DataProvider public static Object[][] dropReturnCases() { return new Object[][]{ { boolean.class, true }, diff --git a/test/jdk/java/lang/invoke/MethodHandles/TestTableSwitch.java b/test/jdk/java/lang/invoke/MethodHandles/TestTableSwitch.java index 4ff1a99cc28..960d98fb387 100644 --- a/test/jdk/java/lang/invoke/MethodHandles/TestTableSwitch.java +++ b/test/jdk/java/lang/invoke/MethodHandles/TestTableSwitch.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,13 +23,9 @@ /* * @test - * @run testng/othervm -Xverify:all TestTableSwitch + * @run junit/othervm -Xverify:all TestTableSwitch */ -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - -import javax.management.ObjectName; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; @@ -38,7 +34,11 @@ import java.util.List; import java.util.function.IntConsumer; import java.util.function.IntFunction; -import static org.testng.Assert.assertEquals; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.junit.jupiter.api.Assertions.*; public class TestTableSwitch { @@ -111,7 +111,6 @@ public class TestTableSwitch { return args; } - @DataProvider public static Object[][] nonVoidCases() { List tests = new ArrayList<>(); @@ -126,10 +125,11 @@ public class TestTableSwitch { } private static void check(List testValues, Object[] collectedValues) { - assertEquals(collectedValues, testValues.toArray()); + assertArrayEquals(testValues.toArray(), collectedValues); } - @Test(dataProvider = "nonVoidCases") + @ParameterizedTest + @MethodSource("nonVoidCases") public void testNonVoidHandles(Class type, int numCases, List> additionalTypes) throws Throwable { MethodHandle collector = MH_check; List testArguments = new ArrayList<>(); @@ -158,19 +158,19 @@ public class TestTableSwitch { testArguments.add(testValue(additionalType)); } - assertEquals(mhSwitch.invokeWithArguments(testArguments(-1, testArguments)), defaultReturnValue); + assertEquals(defaultReturnValue, mhSwitch.invokeWithArguments(testArguments(-1, testArguments))); for (int i = 0; i < numCases; i++) { - assertEquals(mhSwitch.invokeWithArguments(testArguments(i, testArguments)), returnValues[i]); + assertEquals(returnValues[i], mhSwitch.invokeWithArguments(testArguments(i, testArguments))); } - assertEquals(mhSwitch.invokeWithArguments(testArguments(numCases, testArguments)), defaultReturnValue); + assertEquals(defaultReturnValue, mhSwitch.invokeWithArguments(testArguments(numCases, testArguments))); } @Test public void testVoidHandles() throws Throwable { IntFunction makeTestCase = expectedIndex -> { - IntConsumer test = actualIndex -> assertEquals(actualIndex, expectedIndex); + IntConsumer test = actualIndex -> assertEquals(expectedIndex, actualIndex); return MH_IntConsumer_accept.bindTo(test); }; @@ -187,48 +187,48 @@ public class TestTableSwitch { mhSwitch.invokeExact((int) 2); } - @Test(expectedExceptions = NullPointerException.class) + @Test public void testNullDefaultHandle() { - MethodHandles.tableSwitch(null, simpleTestCase("test")); + assertThrows(NullPointerException.class, () -> MethodHandles.tableSwitch(null, simpleTestCase("test"))); } - @Test(expectedExceptions = NullPointerException.class) + @Test public void testNullCases() { MethodHandle[] cases = null; - MethodHandles.tableSwitch(simpleTestCase("default"), cases); + assertThrows(NullPointerException.class, () -> + MethodHandles.tableSwitch(simpleTestCase("default"), cases)); } - @Test(expectedExceptions = NullPointerException.class) + @Test public void testNullCase() { - MethodHandles.tableSwitch(simpleTestCase("default"), simpleTestCase("case"), null); + assertThrows(NullPointerException.class, () -> MethodHandles.tableSwitch(simpleTestCase("default"), simpleTestCase("case"), null)); } - @Test(expectedExceptions = IllegalArgumentException.class, - expectedExceptionsMessageRegExp = ".*Not enough cases.*") + @Test public void testNotEnoughCases() { - MethodHandles.tableSwitch(simpleTestCase("default")); + assertThrows(IllegalArgumentException.class, () -> MethodHandles.tableSwitch(simpleTestCase("default"))); } - @Test(expectedExceptions = IllegalArgumentException.class, - expectedExceptionsMessageRegExp = ".*Case actions must have int as leading parameter.*") + @Test public void testNotEnoughParameters() { MethodHandle empty = MethodHandles.empty(MethodType.methodType(void.class)); - MethodHandles.tableSwitch(empty, empty, empty); + assertThrows(IllegalArgumentException.class, () -> + MethodHandles.tableSwitch(empty, empty, empty)); } - @Test(expectedExceptions = IllegalArgumentException.class, - expectedExceptionsMessageRegExp = ".*Case actions must have int as leading parameter.*") + @Test public void testNoLeadingIntParameter() { MethodHandle empty = MethodHandles.empty(MethodType.methodType(void.class, double.class)); - MethodHandles.tableSwitch(empty, empty, empty); + assertThrows(IllegalArgumentException.class, () -> + MethodHandles.tableSwitch(empty, empty, empty)); } - @Test(expectedExceptions = IllegalArgumentException.class, - expectedExceptionsMessageRegExp = ".*Case actions must have the same type.*") + @Test public void testWrongCaseType() { // doesn't return a String MethodHandle wrongType = MethodHandles.empty(MethodType.methodType(void.class, int.class)); - MethodHandles.tableSwitch(simpleTestCase("default"), simpleTestCase("case"), wrongType); + assertThrows(IllegalArgumentException.class, () -> + MethodHandles.tableSwitch(simpleTestCase("default"), simpleTestCase("case"), wrongType)); } } diff --git a/test/jdk/java/lang/invoke/MethodHandles/classData/ClassDataTest.java b/test/jdk/java/lang/invoke/MethodHandles/classData/ClassDataTest.java index 5880761f925..f96a6f23162 100644 --- a/test/jdk/java/lang/invoke/MethodHandles/classData/ClassDataTest.java +++ b/test/jdk/java/lang/invoke/MethodHandles/classData/ClassDataTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ * @test * @bug 8230501 * @library /test/lib - * @run testng/othervm ClassDataTest + * @run junit/othervm ClassDataTest */ import java.io.IOException; @@ -54,13 +54,14 @@ import java.util.Map; import java.util.function.Consumer; import java.util.stream.Stream; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import static java.lang.classfile.ClassFile.*; import static java.lang.constant.ConstantDescs.*; import static java.lang.invoke.MethodHandles.Lookup.*; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; public class ClassDataTest { private static final Lookup LOOKUP = MethodHandles.lookup(); @@ -72,10 +73,10 @@ public class ClassDataTest { assertTrue(lookup.hasFullPrivilegeAccess()); int value = MethodHandles.classData(lookup, "_", int.class); - assertEquals(value, 20); + assertEquals(20, value); Integer i = MethodHandles.classData(lookup, "_", Integer.class); - assertEquals(i.intValue(), 20); + assertEquals(20, i.intValue()); } /* @@ -86,8 +87,7 @@ public class ClassDataTest { assertNull(MethodHandles.classData(LOOKUP, "_", Object.class)); } - @DataProvider(name = "teleportedLookup") - private Object[][] teleportedLookup() throws ReflectiveOperationException { + private static Object[][] teleportedLookup() throws ReflectiveOperationException { Lookup lookup = hiddenClass(30); Class hc = lookup.lookupClass(); assertClassData(lookup, 30); @@ -100,32 +100,33 @@ public class ClassDataTest { }; } - @Test(dataProvider = "teleportedLookup", expectedExceptions = { IllegalAccessException.class }) + @ParameterizedTest + @MethodSource("teleportedLookup") public void illegalAccess(Lookup lookup, int access) throws IllegalAccessException { int lookupModes = lookup.lookupModes(); - assertTrue((lookupModes & ORIGINAL) == 0); - assertEquals(lookupModes, access); - MethodHandles.classData(lookup, "_", int.class); + assertEquals(0, lookupModes & ORIGINAL); + assertEquals(access, lookupModes); + assertThrows(IllegalAccessException.class, () -> MethodHandles.classData(lookup, "_", int.class)); } - @Test(expectedExceptions = { ClassCastException.class }) + @Test public void incorrectType() throws IllegalAccessException { Lookup lookup = hiddenClass(20); - MethodHandles.classData(lookup, "_", Long.class); + assertThrows(ClassCastException.class, () -> MethodHandles.classData(lookup, "_", Long.class)); } - @Test(expectedExceptions = { IndexOutOfBoundsException.class }) + @Test public void invalidIndex() throws IllegalAccessException { Lookup lookup = hiddenClass(List.of()); - MethodHandles.classDataAt(lookup, "_", Object.class, 0); + assertThrows(IndexOutOfBoundsException.class, () -> MethodHandles.classDataAt(lookup, "_", Object.class, 0)); } - @Test(expectedExceptions = { NullPointerException.class }) + @Test public void unboxNull() throws IllegalAccessException { List list = new ArrayList<>(); list.add(null); Lookup lookup = hiddenClass(list); - MethodHandles.classDataAt(lookup, "_", int.class, 0); + assertThrows(NullPointerException.class, () -> MethodHandles.classDataAt(lookup, "_", int.class, 0)); } @Test @@ -133,7 +134,7 @@ public class ClassDataTest { List list = new ArrayList<>(); list.add(null); Lookup lookup = hiddenClass(list); - assertTrue(MethodHandles.classDataAt(lookup, "_", Object.class, 0) == null); + assertNull(MethodHandles.classDataAt(lookup, "_", Object.class, 0)); } @Test @@ -142,7 +143,7 @@ public class ClassDataTest { byte[] bytes = builder.classData(ACC_PUBLIC|ACC_STATIC, int.class).build(); Lookup lookup = LOOKUP.defineHiddenClassWithClassData(bytes, 100, true); int value = MethodHandles.classData(lookup, "_", int.class); - assertEquals(value, 100); + assertEquals(100, value); // call through condy assertClassData(lookup, 100); } @@ -153,7 +154,7 @@ public class ClassDataTest { byte[] bytes = builder.classData(ACC_PUBLIC|ACC_STATIC, float.class).build(); Lookup lookup = LOOKUP.defineHiddenClassWithClassData(bytes, 0.1234f, true); float value = MethodHandles.classData(lookup, "_", float.class); - assertEquals(value, 0.1234f); + assertEquals(0.1234f, value); // call through condy assertClassData(lookup, 0.1234f); } @@ -165,7 +166,7 @@ public class ClassDataTest { byte[] bytes = builder.classData(ACC_PUBLIC|ACC_STATIC, Class.class).build(); Lookup lookup = LOOKUP.defineHiddenClassWithClassData(bytes, hc, true); Class value = MethodHandles.classData(lookup, "_", Class.class); - assertEquals(value, hc); + assertEquals(hc, value); // call through condy assertClassData(lookup, hc); } @@ -181,7 +182,7 @@ public class ClassDataTest { colors[0] = "black"; // it will get back the modified class data String[] value = MethodHandles.classData(lookup, "_", String[].class); - assertEquals(value, colors); + assertArrayEquals(colors, value); // even call through condy as it's not a constant assertClassData(lookup, colors); } @@ -194,7 +195,7 @@ public class ClassDataTest { int expected = 102; // element at index=2 Lookup lookup = LOOKUP.defineHiddenClassWithClassData(bytes, cd, true); int value = MethodHandles.classDataAt(lookup, "_", int.class, 2); - assertEquals(value, expected); + assertEquals(expected, value); // call through condy assertClassData(lookup, expected); } @@ -208,7 +209,7 @@ public class ClassDataTest { int expected = 101; // element at index=1 Lookup lookup = LOOKUP.defineHiddenClassWithClassData(bytes, cd, true); int value = MethodHandles.classDataAt(lookup, "_", int.class, 1); - assertEquals(value, expected); + assertEquals(expected, value); // call through condy assertClassData(lookup, expected); } @@ -216,20 +217,12 @@ public class ClassDataTest { private static Lookup hiddenClass(int value) { ClassByteBuilder builder = new ClassByteBuilder("HC"); byte[] bytes = builder.classData(ACC_PUBLIC|ACC_STATIC, int.class).build(); - try { - return LOOKUP.defineHiddenClassWithClassData(bytes, value, true); - } catch (Throwable e) { - throw new RuntimeException(e); - } + return assertDoesNotThrow(() -> LOOKUP.defineHiddenClassWithClassData(bytes, value, true)); } private static Lookup hiddenClass(List list) { ClassByteBuilder builder = new ClassByteBuilder("HC"); byte[] bytes = builder.classData(ACC_PUBLIC|ACC_STATIC, List.class).build(); - try { - return LOOKUP.defineHiddenClassWithClassData(bytes, list, true); - } catch (Throwable e) { - throw new RuntimeException(e); - } + return assertDoesNotThrow(() -> LOOKUP.defineHiddenClassWithClassData(bytes, list, true)); } @Test @@ -242,7 +235,7 @@ public class ClassDataTest { Class hc = hcLookup.lookupClass(); Lookup lookup = LOOKUP.defineHiddenClassWithClassData(bytes, hc, true); Class value = MethodHandles.classData(lookup, "_", Class.class); - assertEquals(value, hc); + assertEquals(hc, value); // call through condy Class c = lookup.lookupClass(); assertClassData(lookup, c.newInstance(), hc); @@ -257,7 +250,7 @@ public class ClassDataTest { int expected = 102; // element at index=2 Lookup lookup = LOOKUP.defineHiddenClassWithClassData(bytes, cd, true); int value = MethodHandles.classDataAt(lookup, "_", int.class, 2); - assertEquals(value, expected); + assertEquals(expected, value); // call through condy Class c = lookup.lookupClass(); assertClassData(lookup, c.newInstance() ,expected); @@ -285,13 +278,13 @@ public class ClassDataTest { Class c = lookup.lookupClass(); assertClassData(lookup, c.newInstance(), mtype); // modify the class data - assertTrue(cd.remove(0) == mtype); + assertSame(mtype, cd.remove(0)); cd.add(0, MethodType.methodType(void.class)); MethodType newMType = cd.get(0); // loading the element using condy returns the original value assertClassData(lookup, c.newInstance(), mtype); // direct invocation of MethodHandles.classDataAt returns the modified value - assertEquals(MethodHandles.classDataAt(lookup, "_", MethodType.class, 0), newMType); + assertEquals(newMType, MethodHandles.classDataAt(lookup, "_", MethodType.class, 0)); } // helper method to extract from a class data map @@ -334,7 +327,7 @@ public class ClassDataTest { assertEquals(mh, v1); } - @Test(expectedExceptions = { IllegalArgumentException.class }) + @Test public void nonDefaultName() throws ReflectiveOperationException { ClassByteBuilder builder = new ClassByteBuilder("nonDefaultName"); byte[] bytes = builder.classData(ACC_PUBLIC|ACC_STATIC, Class.class) @@ -342,7 +335,7 @@ public class ClassDataTest { Lookup lookup = LOOKUP.defineHiddenClassWithClassData(bytes, ClassDataTest.class, true); assertClassData(lookup, ClassDataTest.class); // throw IAE - MethodHandles.classData(lookup, "non_default_name", Class.class); + assertThrows(IllegalArgumentException.class, () -> MethodHandles.classData(lookup, "non_default_name", Class.class)); } static class ClassByteBuilder { @@ -428,7 +421,7 @@ public class ClassDataTest { * Load an int constant from class data via condy and * verify it matches the given value. */ - private void assertClassData(Lookup lookup, int value) throws ReflectiveOperationException { + private static void assertClassData(Lookup lookup, int value) throws ReflectiveOperationException { Class c = lookup.lookupClass(); Method m = c.getMethod("classData"); int v = (int) m.invoke(null); @@ -439,7 +432,7 @@ public class ClassDataTest { * Load an int constant from class data via condy and * verify it matches the given value. */ - private void assertClassData(Lookup lookup, Object o, int value) throws ReflectiveOperationException { + private static void assertClassData(Lookup lookup, Object o, int value) throws ReflectiveOperationException { Class c = lookup.lookupClass(); Method m = c.getMethod("classData"); int v = (int) m.invoke(o); @@ -450,7 +443,7 @@ public class ClassDataTest { * Load a float constant from class data via condy and * verify it matches the given value. */ - private void assertClassData(Lookup lookup, float value) throws ReflectiveOperationException { + private static void assertClassData(Lookup lookup, float value) throws ReflectiveOperationException { Class c = lookup.lookupClass(); Method m = c.getMethod("classData"); float v = (float) m.invoke(null); @@ -461,7 +454,7 @@ public class ClassDataTest { * Load a Class constant from class data via condy and * verify it matches the given value. */ - private void assertClassData(Lookup lookup, Class value) throws ReflectiveOperationException { + private static void assertClassData(Lookup lookup, Class value) throws ReflectiveOperationException { Class c = lookup.lookupClass(); Method m = c.getMethod("classData"); Class v = (Class)m.invoke(null); @@ -472,7 +465,7 @@ public class ClassDataTest { * Load a Class from class data via condy and * verify it matches the given value. */ - private void assertClassData(Lookup lookup, Object o, Class value) throws ReflectiveOperationException { + private static void assertClassData(Lookup lookup, Object o, Class value) throws ReflectiveOperationException { Class c = lookup.lookupClass(); Method m = c.getMethod("classData"); Object v = m.invoke(o); @@ -483,18 +476,29 @@ public class ClassDataTest { * Load an Object from class data via condy and * verify it matches the given value. */ - private void assertClassData(Lookup lookup, Object value) throws ReflectiveOperationException { + private static void assertClassData(Lookup lookup, Object value) throws ReflectiveOperationException { Class c = lookup.lookupClass(); Method m = c.getMethod("classData"); Object v = m.invoke(null); assertEquals(value, v); } + /* + * Load an Object array from class data via condy and + * verify it matches the given value in content. + */ + private static void assertClassData(Lookup lookup, Object[] value) throws ReflectiveOperationException { + Class c = lookup.lookupClass(); + Method m = c.getMethod("classData"); + Object v = m.invoke(null); + assertArrayEquals(value, (Object[]) v); + } + /* * Load an Object from class data via condy and * verify it matches the given value. */ - private void assertClassData(Lookup lookup, Object o, Object value) throws ReflectiveOperationException { + private static void assertClassData(Lookup lookup, Object o, Object value) throws ReflectiveOperationException { Class c = lookup.lookupClass(); Method m = c.getMethod("classData"); Object v = m.invoke(o); diff --git a/test/jdk/java/lang/invoke/MethodHandles/ensureInitialized/Main.java b/test/jdk/java/lang/invoke/MethodHandles/ensureInitialized/Main.java index 58146286da1..afb628d31ba 100644 --- a/test/jdk/java/lang/invoke/MethodHandles/ensureInitialized/Main.java +++ b/test/jdk/java/lang/invoke/MethodHandles/ensureInitialized/Main.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,16 +24,15 @@ import java.lang.invoke.MethodHandles; import java.lang.reflect.Method; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; /** * @test * @bug 8235521 * @summary Tests for Lookup::ensureClassInitialized * @build java.base/* m1/* m2/* Main - * @run testng/othervm --add-modules m1 Main + * @run junit/othervm --add-modules m1 Main */ public class Main { @@ -48,20 +47,20 @@ public class Main { } // access denied to package-private java.lang class - @Test(expectedExceptions = { IllegalAccessException.class }) + @Test public void testPackagePrivate() throws Exception { Class c = Class.forName("java.lang.DefaultInit", false, null); assertFalse(Helper.isInitialized(c)); // access denied - MethodHandles.lookup().ensureInitialized(c); + assertThrows(IllegalAccessException.class, () -> MethodHandles.lookup().ensureInitialized(c)); } // access denied to public class in a non-exported package - @Test(expectedExceptions = { IllegalAccessException.class }) + @Test public void testNonExportedPackage() throws Exception { Class c = Class.forName("jdk.internal.misc.VM", false, null); // access denied - MethodHandles.lookup().ensureInitialized(c); + assertThrows(IllegalAccessException.class, () -> MethodHandles.lookup().ensureInitialized(c)); } // invoke p1.Test::test to test module boundary access @@ -72,9 +71,9 @@ public class Main { m.invoke(null); } - @Test(expectedExceptions = { IllegalArgumentException.class }) + @Test public void testArrayType() throws Exception { Class arrayType = PublicInit.class.arrayType(); - MethodHandles.lookup().ensureInitialized(arrayType); + assertThrows(IllegalArgumentException.class, () -> MethodHandles.lookup().ensureInitialized(arrayType)); } } diff --git a/test/jdk/java/lang/invoke/MethodHandles/privateLookupIn/Driver.java b/test/jdk/java/lang/invoke/MethodHandles/privateLookupIn/Driver.java index 810351bae3e..bf3f1f40913 100644 --- a/test/jdk/java/lang/invoke/MethodHandles/privateLookupIn/Driver.java +++ b/test/jdk/java/lang/invoke/MethodHandles/privateLookupIn/Driver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,6 +24,6 @@ /** * @test * @build test/* m1/* m2/* m3/* Unnamed - * @run testng/othervm test/p.PrivateLookupInTests + * @run junit/othervm test/p.PrivateLookupInTests * @summary Unit tests for MethodHandles.privateLookupIn */ diff --git a/test/jdk/java/lang/invoke/MethodHandles/privateLookupIn/test/module-info.java b/test/jdk/java/lang/invoke/MethodHandles/privateLookupIn/test/module-info.java index da93c879ef1..f364c761aa3 100644 --- a/test/jdk/java/lang/invoke/MethodHandles/privateLookupIn/test/module-info.java +++ b/test/jdk/java/lang/invoke/MethodHandles/privateLookupIn/test/module-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,6 +22,6 @@ */ module test { - requires org.testng; - exports p to org.testng; // TestNG invokes the public methods + requires org.junit.platform.console.standalone; + exports p to org.junit.platform.console.standalone; // JUnit invokes the public methods in PrivateLookupInTests } diff --git a/test/jdk/java/lang/invoke/MethodHandles/privateLookupIn/test/p/PrivateLookupInTests.java b/test/jdk/java/lang/invoke/MethodHandles/privateLookupIn/test/p/PrivateLookupInTests.java index b17204de013..068d2fb534e 100644 --- a/test/jdk/java/lang/invoke/MethodHandles/privateLookupIn/test/p/PrivateLookupInTests.java +++ b/test/jdk/java/lang/invoke/MethodHandles/privateLookupIn/test/p/PrivateLookupInTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved. * 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,15 +29,14 @@ import java.lang.reflect.Modifier; import static java.lang.invoke.MethodHandles.Lookup.*; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; /** * Unit tests for MethodHandles.privateLookupIn */ -@Test public class PrivateLookupInTests { /** * A public and non-public types in the test module but in a different @@ -52,24 +51,25 @@ public class PrivateLookupInTests { * private static final Object obj = ... * } */ - private Class publicType; - private Class nonPublicType; + private static Class publicType; + private static Class nonPublicType; // initialize and sanity check publicType/nonPublicType - @BeforeTest - public void init() throws Exception { + @BeforeAll + public static void init() throws Exception { publicType = Class.forName("p.internal.PublicType"); - assertTrue(this.getClass().getModule() == publicType.getModule()); - assertNotEquals(this.getClass().getPackageName(), publicType.getPackageName()); + assertSame(PrivateLookupInTests.class.getModule(), publicType.getModule()); + assertNotEquals(publicType.getPackageName(), PrivateLookupInTests.class.getPackageName()); assertTrue(Modifier.isPublic(publicType.getModifiers())); nonPublicType = Class.forName("p.internal.NonPublicType"); - assertTrue(this.getClass().getModule() == nonPublicType.getModule()); - assertNotEquals(this.getClass().getPackageName(), nonPublicType.getPackageName()); + assertSame(PrivateLookupInTests.class.getModule(), nonPublicType.getModule()); + assertNotEquals(nonPublicType.getPackageName(), PrivateLookupInTests.class.getPackageName()); assertFalse(Modifier.isPublic(nonPublicType.getModifiers())); } // Invoke MethodHandles.privateLookupIn with a full-power caller + @Test public void testAllAccessCallerSameModule() throws Throwable { Lookup lookup = MethodHandles.privateLookupIn(nonPublicType, MethodHandles.lookup()); assertTrue(lookup.lookupClass() == nonPublicType); @@ -82,29 +82,31 @@ public class PrivateLookupInTests { } // Invoke MethodHandles.privateLookupIn with a reduced-power caller - @Test(expectedExceptions = {IllegalAccessException.class}) + @Test public void testReducedAccessCallerSameModule() throws Throwable { Lookup caller = MethodHandles.lookup().dropLookupMode(PACKAGE); - assertTrue((caller.lookupModes() & PRIVATE) == 0); - assertTrue((caller.lookupModes() & PACKAGE) == 0); - assertTrue((caller.lookupModes() & MODULE) != 0); - assertTrue((caller.lookupModes() & ORIGINAL) == 0); - - Lookup lookup = MethodHandles.privateLookupIn(nonPublicType, caller); + assertEquals(0, caller.lookupModes() & PRIVATE); + assertEquals(0, caller.lookupModes() & PACKAGE); + assertNotEquals(0, caller.lookupModes() & MODULE); + assertEquals(0, caller.lookupModes() & ORIGINAL); + assertThrows(IllegalAccessException.class, () -> + MethodHandles.privateLookupIn(nonPublicType, caller)); } // Invoke MethodHandles.privateLookupIn with the public lookup as caller - @Test(expectedExceptions = {IllegalAccessException.class}) + @Test public void testPublicLookupSameModule() throws Exception { Lookup caller = MethodHandles.publicLookup(); - Lookup lookup = MethodHandles.privateLookupIn(publicType, caller); + assertThrows(IllegalAccessException.class, () -> + MethodHandles.privateLookupIn(publicType, caller)); } // test reads m1, open module m1 containing p1 + @Test public void testTargetClassInOpenModule() throws Throwable { // m1/p1.Type Class clazz = Class.forName("p1.Type"); - assertEquals(clazz.getModule().getName(), "m1"); + assertEquals("m1", clazz.getModule().getName()); // ensure that this module reads m1 Module thisModule = getClass().getModule(); @@ -113,9 +115,9 @@ public class PrivateLookupInTests { assertTrue(m1.isOpen("p1", thisModule)); Lookup lookup = MethodHandles.privateLookupIn(clazz, MethodHandles.lookup()); - assertTrue(lookup.lookupClass() == clazz); - assertTrue((lookup.lookupModes() & PRIVATE) == PRIVATE); - assertTrue((lookup.lookupModes() & MODULE) == 0); + assertSame(clazz, lookup.lookupClass()); + assertEquals(PRIVATE, lookup.lookupModes() & PRIVATE); + assertEquals(0, lookup.lookupModes() & MODULE); // get obj field MethodHandle mh = lookup.findStaticGetter(clazz, "obj", Object.class); @@ -123,6 +125,7 @@ public class PrivateLookupInTests { } // test target class in unnamed module + @Test public void testTargetClassInUnnamedModule() throws Throwable { Class clazz = Class.forName("Unnamed"); assertFalse(clazz.getModule().isNamed()); @@ -130,76 +133,72 @@ public class PrivateLookupInTests { // thisModule does not read the unnamed module Module thisModule = getClass().getModule(); assertFalse(thisModule.canRead(clazz.getModule())); - try { - MethodHandles.privateLookupIn(clazz, MethodHandles.lookup()); - assertTrue(false); - } catch (IllegalAccessException expected) { } + var baseLookup = MethodHandles.lookup(); + assertThrows(IllegalAccessException.class, () -> MethodHandles.privateLookupIn(clazz, baseLookup)); // thisModule reads the unnamed module thisModule.addReads(clazz.getModule()); - Lookup lookup = MethodHandles.privateLookupIn(clazz, MethodHandles.lookup()); - assertTrue(lookup.lookupClass() == clazz); - assertTrue((lookup.lookupModes() & PRIVATE) == PRIVATE); - assertTrue((lookup.lookupModes() & MODULE) == 0); + Lookup lookup = MethodHandles.privateLookupIn(clazz, baseLookup); + assertSame(clazz, lookup.lookupClass()); + assertEquals(PRIVATE, (lookup.lookupModes() & PRIVATE)); + assertEquals(0, (lookup.lookupModes() & MODULE)); } // test does not read m2, m2 opens p2 to test - @Test(expectedExceptions = {IllegalAccessException.class}) + @Test public void testCallerDoesNotRead() throws Throwable { // m2/p2.Type Class clazz = Class.forName("p2.Type"); - assertEquals(clazz.getModule().getName(), "m2"); - + assertEquals("m2", clazz.getModule().getName()); Module thisModule = getClass().getModule(); Module m2 = clazz.getModule(); assertFalse(thisModule.canRead(m2)); assertTrue(m2.isOpen("p2", thisModule)); - - Lookup lookup = MethodHandles.privateLookupIn(clazz, MethodHandles.lookup()); + assertThrows(IllegalAccessException.class, () -> + MethodHandles.privateLookupIn(clazz, MethodHandles.lookup())); } // test reads m3, m3 does not open p3 to test - @Test(expectedExceptions = {IllegalAccessException.class}) + @Test public void testNotOpenToCaller() throws Throwable { // m3/p2.Type Class clazz = Class.forName("p3.Type"); - assertEquals(clazz.getModule().getName(), "m3"); - + assertEquals("m3", clazz.getModule().getName()); Module thisModule = getClass().getModule(); Module m3 = clazz.getModule(); thisModule.addReads(clazz.getModule()); assertFalse(m3.isOpen("p3", thisModule)); - - Lookup lookup = MethodHandles.privateLookupIn(clazz, MethodHandles.lookup()); + assertThrows(IllegalAccessException.class, () -> + MethodHandles.privateLookupIn(clazz, MethodHandles.lookup())); } // Invoke MethodHandles.privateLookupIn with a primitive class - @Test(expectedExceptions = {IllegalArgumentException.class}) + @Test public void testPrimitiveClassAsTargetClass() throws Exception { - MethodHandles.privateLookupIn(int.class, MethodHandles.lookup()); + assertThrows(IllegalArgumentException.class, () -> MethodHandles.privateLookupIn(int.class, MethodHandles.lookup())); } // Invoke MethodHandles.privateLookupIn with an array class - @Test(expectedExceptions = {IllegalArgumentException.class}) + @Test public void testArrayClassAsTargetClass() throws Exception { - MethodHandles.privateLookupIn(PrivateLookupInTests[].class, MethodHandles.lookup()); + assertThrows(IllegalArgumentException.class, () -> MethodHandles.privateLookupIn(PrivateLookupInTests[].class, MethodHandles.lookup())); } // Invoke MethodHandles.privateLookupIn with a primitive array class - @Test(expectedExceptions = {IllegalArgumentException.class}) + @Test public void testPrimitiveArrayClassAsTargetClass() throws Exception { - MethodHandles.privateLookupIn(int[].class, MethodHandles.lookup()); + assertThrows(IllegalArgumentException.class, () -> MethodHandles.privateLookupIn(int[].class, MethodHandles.lookup())); } // Invoke MethodHandles.privateLookupIn with null - @Test(expectedExceptions = {NullPointerException.class}) + @Test public void testNullTargetClass() throws Exception { - MethodHandles.privateLookupIn(null, MethodHandles.lookup()); + assertThrows(NullPointerException.class, () -> MethodHandles.privateLookupIn(null, MethodHandles.lookup())); } // Invoke MethodHandles.privateLookupIn with null - @Test(expectedExceptions = {NullPointerException.class}) + @Test public void testNullCaller() throws Exception { - MethodHandles.privateLookupIn(getClass(), null); + assertThrows(NullPointerException.class, () -> MethodHandles.privateLookupIn(getClass(), null)); } } diff --git a/test/jdk/java/lang/invoke/MethodHandlesCollectArgsTest.java b/test/jdk/java/lang/invoke/MethodHandlesCollectArgsTest.java index 5fc0083d5fb..20f03454d32 100644 --- a/test/jdk/java/lang/invoke/MethodHandlesCollectArgsTest.java +++ b/test/jdk/java/lang/invoke/MethodHandlesCollectArgsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,18 +23,17 @@ /* @test * @bug 8259922 - * @run testng/othervm MethodHandlesCollectArgsTest + * @run junit/othervm MethodHandlesCollectArgsTest */ -import org.testng.annotations.Test; -import org.testng.annotations.DataProvider; - import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import static java.lang.invoke.MethodType.methodType; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; public class MethodHandlesCollectArgsTest { @@ -43,7 +42,6 @@ public class MethodHandlesCollectArgsTest { private static final MethodHandle FILTER_INT = MethodHandles.empty(methodType(int.class, String.class)); private static final MethodHandle FILTER_VOID = MethodHandles.empty(methodType(void.class, String.class)); - @DataProvider(name = "illegalPos") public static Object[][] illegalPos() { return new Object[][] { {TARGET_II_I, 2, FILTER_INT}, @@ -57,7 +55,6 @@ public class MethodHandlesCollectArgsTest { }; } - @DataProvider(name = "validPos") public static Object[][] validPos() { return new Object[][] { {TARGET_II_I, 0, FILTER_INT, methodType(int.class, String.class, int.class)}, @@ -69,14 +66,16 @@ public class MethodHandlesCollectArgsTest { }; } - @Test(dataProvider="illegalPos", expectedExceptions = {IllegalArgumentException.class}) + @ParameterizedTest + @MethodSource("illegalPos") public void illegalPosition(MethodHandle target, int position, MethodHandle filter) { - MethodHandles.collectArguments(target, position, filter); + assertThrows(IllegalArgumentException.class, () -> MethodHandles.collectArguments(target, position, filter)); } - @Test(dataProvider="validPos") + @ParameterizedTest + @MethodSource("validPos") public void legalPosition(MethodHandle target, int position, MethodHandle filter, MethodType expectedType) { MethodHandle result = MethodHandles.collectArguments(target, position, filter); - assertEquals(result.type(), expectedType); + assertEquals(expectedType, result.type()); } } diff --git a/test/jdk/java/lang/invoke/MethodHandlesGeneralTest.java b/test/jdk/java/lang/invoke/MethodHandlesGeneralTest.java index b60c35fc30b..588227fef15 100644 --- a/test/jdk/java/lang/invoke/MethodHandlesGeneralTest.java +++ b/test/jdk/java/lang/invoke/MethodHandlesGeneralTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,6 +60,7 @@ import java.util.Map; import static java.lang.invoke.MethodType.methodType; import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; public class MethodHandlesGeneralTest extends MethodHandlesTest { @@ -398,7 +399,7 @@ public class MethodHandlesGeneralTest extends MethodHandlesTest { Object obj = target.invokeWithArguments(args); if (!(defc == Example.class && params.length < 2)) assertCalled(defc.getSimpleName()+".", args); - assertTrue("instance of "+defc.getName(), defc.isInstance(obj)); + assertInstanceOf(defc, obj); } @Test @@ -971,8 +972,7 @@ public class MethodHandlesGeneralTest extends MethodHandlesTest { arrayToMH = new SubIntExample[length]; else return; // can't make an ArrayStoreException test - assert(arrayType.isInstance(arrayToMH)) - : Arrays.asList(arrayType, arrayToMH.getClass(), testSetter, negTest); + assertInstanceOf(arrayType, arrayToMH, () -> Arrays.asList(testSetter, negTest).toString()); break; } countTest(positive); diff --git a/test/jdk/java/lang/invoke/MethodTypeTest.java b/test/jdk/java/lang/invoke/MethodTypeTest.java index 8ac03d1a7fd..dccc82fa348 100644 --- a/test/jdk/java/lang/invoke/MethodTypeTest.java +++ b/test/jdk/java/lang/invoke/MethodTypeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ * @bug 8366028 * @summary unit tests for java.lang.invoke.MethodType * @compile MethodTypeTest.java - * @run testng/othervm test.java.lang.invoke.MethodTypeTest + * @run junit/othervm test.java.lang.invoke.MethodTypeTest */ package test.java.lang.invoke; @@ -35,11 +35,13 @@ import java.lang.invoke.MethodType; import java.lang.reflect.Method; import java.util.*; -import org.testng.*; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; -import static org.testng.Assert.assertThrows; -import static org.testng.AssertJUnit.*; -import org.testng.annotations.*; +import static org.junit.jupiter.api.Assertions.*; /** * @@ -57,7 +59,7 @@ public class MethodTypeTest { private MethodType[] GALLERY; private Method compareTo; - @BeforeMethod + @BeforeEach public void setUp() throws Exception { rtype = void.class; ptypes = new Class[] { int.class, String.class }; @@ -98,7 +100,7 @@ public class MethodTypeTest { }; } - @AfterMethod + @AfterEach public void tearDown() throws Exception { } @@ -107,7 +109,7 @@ public class MethodTypeTest { public void testDistinct() { List gallery2 = new ArrayList<>(); for (MethodType mt : GALLERY) { - assertFalse(mt.toString(), gallery2.contains(mt)); + assertFalse(gallery2.contains(mt), mt.toString()); gallery2.add(mt); } // check self-equality also: @@ -198,9 +200,9 @@ public class MethodTypeTest { for (int i = 0; i < instances.length; i++) { MethodType instance = instances[i]; String result = instance.toMethodDescriptorString(); - assertEquals("#"+i, expResults[i], result); + assertEquals(expResults[i], result, "#"+i); MethodType parsed = MethodType.fromMethodDescriptorString(result, loader); - assertSame("--#"+i, instance, parsed); + assertSame(instance, parsed, "--#"+i); } } private static String concat(Object... parts) { @@ -221,8 +223,7 @@ public class MethodTypeTest { return sb.toString().replace('.', '/'); } - @DataProvider(name = "badMethodDescriptorStrings") - public String[] badMethodDescriptorStrings() { + public static String[] badMethodDescriptorStrings() { return new String[] { "(I)", "(V)V", @@ -239,9 +240,12 @@ public class MethodTypeTest { } // JDK-8366028 - @Test(dataProvider = "badMethodDescriptorStrings", expectedExceptions = IllegalArgumentException.class) + @ParameterizedTest + @MethodSource("badMethodDescriptorStrings") public void testFromMethodDescriptorStringNegatives(String desc) { - MethodType.fromMethodDescriptorString(desc, null); + assertThrows(IllegalArgumentException.class, () -> { + MethodType.fromMethodDescriptorString(desc, null); + }); } @Test @@ -251,7 +255,7 @@ public class MethodTypeTest { boolean[] expResults = {true, false, true, false, true, true, false, true}; for (int i = 0; i < instances.length; i++) { boolean result = instances[i].hasPrimitives(); - assertEquals("#"+i, expResults[i], result); + assertEquals(expResults[i], result, "#"+i); } } @@ -263,7 +267,7 @@ public class MethodTypeTest { for (int i = 0; i < instances.length; i++) { System.out.println(" hasWrappers "+instances[i]); boolean result = instances[i].hasWrappers(); - assertEquals("#"+i, expResults[i], result); + assertEquals(expResults[i], result, "#"+i); } } @@ -274,7 +278,7 @@ public class MethodTypeTest { MethodType[] expResults = {mt_viO, mt_OO2, mt_vv, mt_Ov, mt_iO2, mt_OOi, mt_OO2, mt_iOi}; for (int i = 0; i < instances.length; i++) { MethodType result = instances[i].erase(); - assertSame("#"+i, expResults[i], result); + assertSame(expResults[i], result, "#"+i); } } @@ -285,7 +289,7 @@ public class MethodTypeTest { MethodType[] expResults = {mt_OO2, mt_OO2, mt_Ov, mt_Ov, mt_OO2, mt_OO2, mt_OO2, mt_OO2}; for (int i = 0; i < instances.length; i++) { MethodType result = instances[i].generic(); - assertSame("#"+i, expResults[i], result); + assertSame(expResults[i], result, "#"+i); } } @@ -296,7 +300,7 @@ public class MethodTypeTest { MethodType[] expResults = {mt_VIS, mt_OO2, mt_Vv, mt_Ov, mt_ISI, mt_ISI, mt_ISI, mt_ISI}; for (int i = 0; i < instances.length; i++) { MethodType result = instances[i].wrap(); - assertSame("#"+i, expResults[i], result); + assertSame(expResults[i], result, "#"+i); } } @@ -307,7 +311,7 @@ public class MethodTypeTest { MethodType[] expResults = {mt_viS, mt_OO2, mt_vv, mt_Ov, mt_iSi, mt_iSi, mt_iSi, mt_iSi}; for (int i = 0; i < instances.length; i++) { MethodType result = instances[i].unwrap(); - assertSame("#"+i, expResults[i], result); + assertSame(expResults[i], result, "#"+i); } } @@ -436,7 +440,7 @@ public class MethodTypeTest { MethodType instance = instances[i]; String result = instance.toString(); System.out.println("#"+i+":"+result); - assertEquals("#"+i, expResults[i], result); + assertEquals(expResults[i], result, "#"+i); } } diff --git a/test/jdk/java/lang/invoke/PermuteArgsReturnVoidTest.java b/test/jdk/java/lang/invoke/PermuteArgsReturnVoidTest.java index b01a4aa2a99..6bd604dcd36 100644 --- a/test/jdk/java/lang/invoke/PermuteArgsReturnVoidTest.java +++ b/test/jdk/java/lang/invoke/PermuteArgsReturnVoidTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * 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,21 +24,21 @@ /* @test * @bug 8184119 * @summary test permutation when return value is directly derived from an argument - * @run testng/othervm test.java.lang.invoke.PermuteArgsReturnVoidTest + * @run junit/othervm test.java.lang.invoke.PermuteArgsReturnVoidTest */ package test.java.lang.invoke; -import org.testng.Assert; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import static java.lang.invoke.MethodHandles.dropArguments; import static java.lang.invoke.MethodHandles.identity; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; public class PermuteArgsReturnVoidTest { @@ -65,8 +65,8 @@ public class PermuteArgsReturnVoidTest { MethodHandle p = MethodHandles.permuteArguments(f, MethodType.methodType(String.class, String.class, int.class, int.class), 0, 2, 1); String s = (String) p.invoke("IN", 0, 0); - Assert.assertEquals(s.getClass(), String.class); - Assert.assertEquals(s, "IN"); + assertEquals(String.class, s.getClass()); + assertEquals("IN", s); } @Test @@ -84,7 +84,7 @@ public class PermuteArgsReturnVoidTest { MethodHandle p = MethodHandles.permuteArguments(f, MethodType.methodType(String.class, String.class, int.class, int.class), 0, 2, 1); String s = (String) p.invoke("IN", 0, 0); - Assert.assertEquals(s.getClass(), String.class); - Assert.assertEquals(s, "IN"); + assertEquals(String.class, s.getClass()); + assertEquals("IN", s); } } diff --git a/test/jdk/java/lang/invoke/PermuteArgsTest.java b/test/jdk/java/lang/invoke/PermuteArgsTest.java index 3586dc9382f..77558714d11 100644 --- a/test/jdk/java/lang/invoke/PermuteArgsTest.java +++ b/test/jdk/java/lang/invoke/PermuteArgsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /* @test * @summary unit tests for method handles which permute their arguments * @library /test/lib /java/lang/invoke/common - * @run testng/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyDependencies -ea -esa -DPermuteArgsTest.MAX_ARITY=8 test.java.lang.invoke.PermuteArgsTest + * @run junit/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyDependencies -ea -esa -DPermuteArgsTest.MAX_ARITY=8 test.java.lang.invoke.PermuteArgsTest */ /* Examples of manual runs: @@ -35,7 +35,6 @@ package test.java.lang.invoke; -import org.testng.annotations.Test; import test.java.lang.invoke.lib.CodeCacheOverflowProcessor; import java.lang.invoke.MethodHandle; @@ -52,6 +51,10 @@ import static java.lang.invoke.MethodHandles.Lookup; import static java.lang.invoke.MethodHandles.lookup; import static java.lang.invoke.MethodHandles.permuteArguments; import static java.lang.invoke.MethodType.methodType; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; public class PermuteArgsTest { private static final Class CLASS = PermuteArgsTest.class; @@ -259,11 +262,11 @@ public class PermuteArgsTest { reverse(perm, 0, perm.length); } switch (perm.length) { - case 2: assert(testCases - testCases0 == 2); break; - case 3: assert(testCases - testCases0 == 6); break; - case 4: assert(testCases - testCases0 == 24); break; - case 5: assert(testCases - testCases0 == 120); break; - case 6: assert(testCases - testCases0 > 720/3); break; + case 2 -> assertEquals(2, testCases - testCases0); + case 3 -> assertEquals(6, testCases - testCases0); + case 4 -> assertEquals(24, testCases - testCases0); + case 5 -> assertEquals(120, testCases - testCases0); + case 6 -> assertTrue(testCases - testCases0 > 720/3); } } diff --git a/test/jdk/java/lang/invoke/SpreadCollectTest.java b/test/jdk/java/lang/invoke/SpreadCollectTest.java index bcddcd449f8..d58ebab3611 100644 --- a/test/jdk/java/lang/invoke/SpreadCollectTest.java +++ b/test/jdk/java/lang/invoke/SpreadCollectTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /* @test * @bug 8139885 * @bug 8143798 - * @run testng/othervm -ea -esa test.java.lang.invoke.SpreadCollectTest + * @run junit/othervm -ea -esa test.java.lang.invoke.SpreadCollectTest */ package test.java.lang.invoke; @@ -39,9 +39,11 @@ import java.util.*; import static java.lang.invoke.MethodType.methodType; -import static org.testng.AssertJUnit.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; -import org.testng.annotations.*; +import static org.junit.jupiter.api.Assertions.*; /** * Tests for the new asSpreader/asCollector API added in JEP 274. @@ -51,14 +53,14 @@ public class SpreadCollectTest { static final Lookup LOOKUP = MethodHandles.lookup(); @Test - public static void testAsSpreader() throws Throwable { + public void testAsSpreader() throws Throwable { MethodHandle spreader = SpreadCollect.MH_forSpreading.asSpreader(1, int[].class, 3); assertEquals(SpreadCollect.MT_spreader, spreader.type()); assertEquals("A456B", (String) spreader.invoke("A", new int[]{4, 5, 6}, "B")); } @Test - public static void testAsSpreaderExample() throws Throwable { + public void testAsSpreaderExample() throws Throwable { // test the JavaDoc asSpreader-with-pos example MethodHandle compare = LOOKUP.findStatic(Objects.class, "compare", methodType(int.class, Object.class, Object.class, Comparator.class)); MethodHandle compare2FromArray = compare.asSpreader(0, Object[].class, 2); @@ -66,49 +68,43 @@ public class SpreadCollectTest { Comparator cmp = (a, b) -> a - b; assertTrue((int) compare2FromArray.invoke(Arrays.copyOfRange(ints, 0, 2), cmp) < 0); assertTrue((int) compare2FromArray.invoke(Arrays.copyOfRange(ints, 1, 3), cmp) > 0); - assertTrue((int) compare2FromArray.invoke(Arrays.copyOfRange(ints, 2, 4), cmp) == 0); + assertEquals(0, (int) compare2FromArray.invoke(Arrays.copyOfRange(ints, 2, 4), cmp)); } - @DataProvider static Object[][] asSpreaderIllegalPositions() { return new Object[][]{{-7}, {3}, {19}}; } - @Test(dataProvider = "asSpreaderIllegalPositions") - public static void testAsSpreaderIllegalPos(int p) throws Throwable { - boolean caught = false; - try { - SpreadCollect.MH_forSpreading.asSpreader(p, Object[].class, 3); - } catch (IllegalArgumentException iae) { - assertEquals("bad spread position", iae.getMessage()); - caught = true; - } - assertTrue(caught); - } - - @Test(expectedExceptions = {WrongMethodTypeException.class}) - public static void testAsSpreaderIllegalMethodType() { - MethodHandle h = MethodHandles.dropArguments(MethodHandles.constant(String.class, ""), 0, int.class, int.class); - MethodHandle s = h.asSpreader(String[].class, 1); - } - - @Test(expectedExceptions = {NullPointerException.class}) - public static void testAsSpreaderNullArrayType() { - SpreadCollect.MH_forSpreading.asSpreader(null, 0); - } - - @Test(expectedExceptions = {NullPointerException.class}) - public static void testAsSpreaderNullArrayNonZeroLength() { - SpreadCollect.MH_forSpreading.asSpreader(null, 1); - } - - @Test(expectedExceptions = {IllegalArgumentException.class}) - public static void testAsSpreaderTooManyParams() throws Throwable { - SpreadCollect.MH_forSpreading.asSpreader(1, int[].class, 6); + @ParameterizedTest + @MethodSource("asSpreaderIllegalPositions") + public void testAsSpreaderIllegalPos(int p) throws Throwable { + var iae = assertThrows(IllegalArgumentException.class, () -> SpreadCollect.MH_forSpreading.asSpreader(p, Object[].class, 3)); + assertEquals("bad spread position", iae.getMessage()); } @Test - public static void testAsCollector() throws Throwable { + public void testAsSpreaderIllegalMethodType() { + MethodHandle h = MethodHandles.dropArguments(MethodHandles.constant(String.class, ""), 0, int.class, int.class); + assertThrows(WrongMethodTypeException.class, () -> h.asSpreader(String[].class, 1)); + } + + @Test + public void testAsSpreaderNullArrayType() { + assertThrows(NullPointerException.class, () -> SpreadCollect.MH_forSpreading.asSpreader(null, 0)); + } + + @Test + public void testAsSpreaderNullArrayNonZeroLength() { + assertThrows(NullPointerException.class, () -> SpreadCollect.MH_forSpreading.asSpreader(null, 1)); + } + + @Test + public void testAsSpreaderTooManyParams() throws Throwable { + assertThrows(IllegalArgumentException.class, () -> SpreadCollect.MH_forSpreading.asSpreader(1, int[].class, 6)); + } + + @Test + public void testAsCollector() throws Throwable { MethodHandle collector = SpreadCollect.MH_forCollecting.asCollector(1, int[].class, 1); assertEquals(SpreadCollect.MT_collector1, collector.type()); assertEquals("A4B", (String) collector.invoke("A", 4, "B")); @@ -121,7 +117,7 @@ public class SpreadCollectTest { } @Test - public static void testAsCollectorInvokeWithArguments() throws Throwable { + public void testAsCollectorInvokeWithArguments() throws Throwable { MethodHandle collector = SpreadCollect.MH_forCollecting.asCollector(1, int[].class, 1); assertEquals(SpreadCollect.MT_collector1, collector.type()); assertEquals("A4B", (String) collector.invokeWithArguments("A", 4, "B")); @@ -134,7 +130,7 @@ public class SpreadCollectTest { } @Test - public static void testAsCollectorLeading() throws Throwable { + public void testAsCollectorLeading() throws Throwable { MethodHandle collector = SpreadCollect.MH_forCollectingLeading.asCollector(0, int[].class, 1); assertEquals(SpreadCollect.MT_collectorLeading1, collector.type()); assertEquals("7Q", (String) collector.invoke(7, "Q")); @@ -147,7 +143,7 @@ public class SpreadCollectTest { } @Test - public static void testAsCollectorLeadingInvokeWithArguments() throws Throwable { + public void testAsCollectorLeadingInvokeWithArguments() throws Throwable { MethodHandle collector = SpreadCollect.MH_forCollectingLeading.asCollector(0, int[].class, 1); assertEquals(SpreadCollect.MT_collectorLeading1, collector.type()); assertEquals("7Q", (String) collector.invokeWithArguments(7, "Q")); @@ -160,31 +156,25 @@ public class SpreadCollectTest { } @Test - public static void testAsCollectorNone() throws Throwable { + public void testAsCollectorNone() throws Throwable { MethodHandle collector = SpreadCollect.MH_forCollecting.asCollector(1, int[].class, 0); assertEquals(SpreadCollect.MT_collector0, collector.type()); assertEquals("AB", (String) collector.invoke("A", "B")); } - @DataProvider static Object[][] asCollectorIllegalPositions() { return new Object[][]{{-1}, {17}}; } - @Test(dataProvider = "asCollectorIllegalPositions") - public static void testAsCollectorIllegalPos(int p) { - boolean caught = false; - try { - SpreadCollect.MH_forCollecting.asCollector(p, int[].class, 0); - } catch (IllegalArgumentException iae) { - assertEquals("bad collect position", iae.getMessage()); - caught = true; - } - assertTrue(caught); + @ParameterizedTest + @MethodSource("asCollectorIllegalPositions") + public void testAsCollectorIllegalPos(int p) { + var iae = assertThrows(IllegalArgumentException.class, () -> SpreadCollect.MH_forCollecting.asCollector(p, int[].class, 0)); + assertEquals("bad collect position", iae.getMessage()); } @Test - public static void testAsCollectorExample() throws Throwable { + public void testAsCollectorExample() throws Throwable { // test the JavaDoc asCollector-with-pos example StringWriter swr = new StringWriter(); MethodHandle swWrite = LOOKUP. diff --git a/test/jdk/java/lang/invoke/TestVHInvokerCaching.java b/test/jdk/java/lang/invoke/TestVHInvokerCaching.java index 0a1ae5914ca..e5c7d50daa7 100644 --- a/test/jdk/java/lang/invoke/TestVHInvokerCaching.java +++ b/test/jdk/java/lang/invoke/TestVHInvokerCaching.java @@ -23,12 +23,9 @@ /* @test * @bug 8265079 - * @run testng/othervm -Xverify:all TestVHInvokerCaching + * @run junit/othervm -Xverify:all TestVHInvokerCaching */ -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; @@ -37,12 +34,16 @@ import java.util.ArrayList; import java.util.List; import static java.lang.invoke.MethodHandles.lookup; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertSame; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; public class TestVHInvokerCaching { - @Test(dataProvider = "testHandles") - public static void testVHIInvokerCaching(VarHandle testHandle) throws Throwable { + @ParameterizedTest + @MethodSource("testHandles") + public void testVHIInvokerCaching(VarHandle testHandle) throws Throwable { for (VarHandle.AccessMode mode : VarHandle.AccessMode.values()) { MethodHandle handle1 = MethodHandles.varHandleInvoker(mode, testHandle.accessModeType(mode)); MethodHandle handle2 = MethodHandles.varHandleInvoker(mode, testHandle.accessModeType(mode)); @@ -56,7 +57,6 @@ public class TestVHInvokerCaching { } } - @DataProvider public static Object[][] testHandles() throws NoSuchFieldException, IllegalAccessException { List testHandles = new ArrayList<>(); diff --git a/test/jdk/java/lang/invoke/ThrowExceptionsTest.java b/test/jdk/java/lang/invoke/ThrowExceptionsTest.java index e12bb7040c4..627a056faec 100644 --- a/test/jdk/java/lang/invoke/ThrowExceptionsTest.java +++ b/test/jdk/java/lang/invoke/ThrowExceptionsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,14 +23,11 @@ /* @test * @summary unit tests for method handles which permute their arguments - * @run testng test.java.lang.invoke.ThrowExceptionsTest + * @run junit test.java.lang.invoke.ThrowExceptionsTest */ package test.java.lang.invoke; -import org.testng.*; -import org.testng.annotations.*; - import java.util.*; import java.lang.reflect.*; @@ -38,6 +35,10 @@ import java.lang.invoke.*; import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + public class ThrowExceptionsTest { private static final Class CLASS = ThrowExceptionsTest.class; private static final Lookup LOOKUP = lookup(); @@ -51,7 +52,7 @@ public class ThrowExceptionsTest { // mostly call testWMTCallee, but sometimes call its void-returning variant MethodHandle mh = testWMTCallee(); MethodHandle mh1 = mh.asType(mh.type().changeReturnType(void.class)); - assert(mh1 != mh); + assertNotSame(mh, mh1); testWMT(mh, mh1, 1000); } @@ -108,7 +109,7 @@ public class ThrowExceptionsTest { MethodHandle[] cell = { null }; // recursion point MethodHandle getCell = insertArguments(arrayElementGetter(cell.getClass()), 0, cell, 0); MethodHandle invokeCell = foldArguments(exactInvoker(cellType), getCell); - assert(invokeCell.type() == cellType); + assertSame(cellType, invokeCell.type()); cell[0] = invokeCell; // make it conformable to any type: invokeCell = dropArguments(invokeCell, 0, Object[].class).asVarargsCollector(Object[].class); @@ -189,7 +190,6 @@ public class ThrowExceptionsTest { try { // FIXME: should not have to retype this n = (int) mh.invokeExact((Object)this, "x"); - assertEquals(n, i - catches); // Using the exact type for this causes endless deopt due to // 'non_cached_result' in SystemDictionary::find_method_handle_invoke. // The problem is that the compiler thread needs to access a cached @@ -198,7 +198,9 @@ public class ThrowExceptionsTest { } catch (Exception ex) { savedEx = ex; catches++; + continue; } + assertEquals(i - catches, n); } //VERBOSE: System.out.println("reps="+reps+" catches="+catches); return savedEx; @@ -220,9 +222,4 @@ public class ThrowExceptionsTest { } return savedEx; } - - private static void assertEquals(Object x, Object y) { - if (x == y || x != null && x.equals(y)) return; - throw new RuntimeException(x+" != "+y); - } } diff --git a/test/jdk/java/lang/invoke/TryFinallyTest.java b/test/jdk/java/lang/invoke/TryFinallyTest.java index 4a3c255201e..ebe276ede93 100644 --- a/test/jdk/java/lang/invoke/TryFinallyTest.java +++ b/test/jdk/java/lang/invoke/TryFinallyTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* @test * @bug 8139885 8150824 8150825 8194238 8233920 - * @run testng/othervm -ea -esa -Xverify:all test.java.lang.invoke.TryFinallyTest + * @run junit/othervm -ea -esa -Xverify:all test.java.lang.invoke.TryFinallyTest */ package test.java.lang.invoke; @@ -35,9 +35,12 @@ import java.lang.invoke.MethodType; import static java.lang.invoke.MethodType.methodType; -import static org.testng.AssertJUnit.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; -import org.testng.annotations.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; /** * Tests for the tryFinally method handle combinator introduced in JEP 274. @@ -47,13 +50,12 @@ public class TryFinallyTest { static final Lookup LOOKUP = MethodHandles.lookup(); @Test - public static void testTryFinally() throws Throwable { + public void testTryFinally() throws Throwable { MethodHandle hello = MethodHandles.tryFinally(TryFinally.MH_greet, TryFinally.MH_exclaim); assertEquals(TryFinally.MT_hello, hello.type()); assertEquals("Hello, world!", hello.invoke("world")); } - @DataProvider static Object[][] tryFinallyArgs() { return new Object[][] { { boolean.class, true }, @@ -68,8 +70,9 @@ public class TryFinallyTest { }; } - @Test(dataProvider = "tryFinallyArgs") - public static void testTryFinally(Class argType, Object arg) throws Throwable { + @ParameterizedTest + @MethodSource("tryFinallyArgs") + public void testTryFinally(Class argType, Object arg) throws Throwable { MethodHandle identity = MethodHandles.identity(argType); MethodHandle tryFinally = MethodHandles.tryFinally( identity, @@ -78,31 +81,31 @@ public class TryFinallyTest { assertEquals(arg, tryFinally.invoke(arg)); } - @Test(dataProvider = "tryFinallyArgs", expectedExceptions = TryFinally.T1.class) - public static void testTryFinallyException(Class argType, Object arg) throws Throwable { + @ParameterizedTest + @MethodSource("tryFinallyArgs") + public void testTryFinallyException(Class argType, Object arg) throws Throwable { MethodHandle identity = TryFinally.MH_throwingTargetIdentity.asType(methodType(argType, argType)); MethodHandle tryFinally = MethodHandles.tryFinally( identity, MethodHandles.dropArguments(identity, 0, TryFinally.T1.class)); assertEquals(methodType(argType, argType), tryFinally.type()); - tryFinally.invoke(arg); // should throw + assertThrows(TryFinally.T1.class, () -> tryFinally.invoke(arg)); } @Test - public static void testTryFinallyVoid() throws Throwable { + public void testTryFinallyVoid() throws Throwable { MethodHandle tfVoid = MethodHandles.tryFinally(TryFinally.MH_print, TryFinally.MH_printMore); assertEquals(TryFinally.MT_printHello, tfVoid.type()); tfVoid.invoke("world"); } @Test - public static void testTryFinallySublist() throws Throwable { + public void testTryFinallySublist() throws Throwable { MethodHandle helloMore = MethodHandles.tryFinally(TryFinally.MH_greetMore, TryFinally.MH_exclaimMore); assertEquals(TryFinally.MT_moreHello, helloMore.type()); assertEquals("Hello, world and universe (but world first)!", helloMore.invoke("world", "universe")); } - @DataProvider static Object[][] omitTrailingArguments() { MethodHandle c = TryFinally.MH_voidCleanup; return new Object[][]{ @@ -114,13 +117,13 @@ public class TryFinallyTest { }; } - @Test(dataProvider = "omitTrailingArguments") - public static void testTryFinallyOmitTrailingArguments(MethodHandle cleanup) throws Throwable { + @ParameterizedTest + @MethodSource("omitTrailingArguments") + public void testTryFinallyOmitTrailingArguments(MethodHandle cleanup) throws Throwable { MethodHandle tf = MethodHandles.tryFinally(TryFinally.MH_dummyTarget, cleanup); tf.invoke(1, 2L, "a", 23, 42L, "b"); } - @DataProvider static Object[][] negativeTestData() { MethodHandle intid = MethodHandles.identity(int.class); MethodHandle intco = MethodHandles.constant(int.class, 0); @@ -145,29 +148,18 @@ public class TryFinallyTest { }; } - @Test(dataProvider = "negativeTestData") - public static void testTryFinallyNegative(MethodHandle target, MethodHandle cleanup, String expectedMessage) { - boolean caught = false; - try { - MethodHandles.tryFinally(target, cleanup); - } catch (IllegalArgumentException iae) { - assertEquals(expectedMessage, iae.getMessage()); - caught = true; - } - assertTrue(caught); + @ParameterizedTest + @MethodSource("negativeTestData") + public void testTryFinallyNegative(MethodHandle target, MethodHandle cleanup, String expectedMessage) { + var iae = assertThrows(IllegalArgumentException.class, () -> MethodHandles.tryFinally(target, cleanup)); + assertEquals(expectedMessage, iae.getMessage()); } @Test - public static void testTryFinallyThrowableCheck() { + public void testTryFinallyThrowableCheck() { MethodHandle mh = MethodHandles.tryFinally(TryFinally.MH_throwingTarget, TryFinally.MH_catchingCleanup); - try { - mh.invoke(); - fail("ClassCastException expected"); - } catch (Throwable t) { - assertTrue("Throwable not assignable to ClassCastException: " + t, - ClassCastException.class.isAssignableFrom(t.getClass())); - } + assertThrows(ClassCastException.class, mh::invoke); } static class TryFinally { diff --git a/test/jdk/java/lang/invoke/VarArgsTest.java b/test/jdk/java/lang/invoke/VarArgsTest.java index bb17881b514..bcea9a0b54e 100644 --- a/test/jdk/java/lang/invoke/VarArgsTest.java +++ b/test/jdk/java/lang/invoke/VarArgsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,19 +23,18 @@ /* @test * @summary unit tests for java.lang.invoke.MethodHandles - * @run testng/othervm -ea -esa test.java.lang.invoke.VarArgsTest + * @run junit/othervm -ea -esa test.java.lang.invoke.VarArgsTest */ package test.java.lang.invoke; import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; import java.util.Arrays; import java.util.List; import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; -import static org.testng.AssertJUnit.*; -import org.testng.annotations.*; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; public class VarArgsTest { @@ -61,17 +60,17 @@ public class VarArgsTest { MethodHandle asList = publicLookup() .findStatic(Arrays.class, "asList", methodType(List.class, Object[].class)); MethodHandle asListWithVarargs = asList.withVarargs(asList.isVarargsCollector()); - assert(asListWithVarargs.isVarargsCollector()); + assertTrue(asListWithVarargs.isVarargsCollector()); assertEquals("[]", asListWithVarargs.invoke().toString()); assertEquals("[1]", asListWithVarargs.invoke(1).toString()); assertEquals("[two, too]", asListWithVarargs.invoke("two", "too").toString()); } - @Test(expectedExceptions = { IllegalArgumentException.class }) + @Test public void testWithVarargsIAE() throws Throwable { MethodHandle lenMH = publicLookup() - .findVirtual(String.class, "length", methodType(int.class)); - MethodHandle lenMHWithVarargs = lenMH.withVarargs(true); + .findVirtual(String.class, "length", methodType(int.class)); + assertThrows(IllegalArgumentException.class, () -> lenMH.withVarargs(true)); } } diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleBaseByteArrayTest.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleBaseByteArrayTest.java index f09ba518e48..c89fcc8289b 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleBaseByteArrayTest.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleBaseByteArrayTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,9 +21,6 @@ * questions. */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; - import java.lang.invoke.VarHandle; import java.nio.ByteBuffer; import java.nio.ByteOrder; @@ -32,6 +29,7 @@ import java.util.Arrays; import java.util.EnumSet; import java.util.List; import java.util.function.Function; +import org.junit.jupiter.api.BeforeAll; public abstract class VarHandleBaseByteArrayTest extends VarHandleBaseTest { @@ -338,7 +336,7 @@ public abstract class VarHandleBaseByteArrayTest extends VarHandleBaseTest { bavss.add(dbb_offset_unaligned_ro); } - @BeforeClass + @BeforeAll public void setup() { setupByteSources(); vhss = setupVarHandleSources(true); @@ -346,13 +344,10 @@ public abstract class VarHandleBaseByteArrayTest extends VarHandleBaseTest { abstract List setupVarHandleSources(boolean same); - - @DataProvider public Object[][] varHandlesProvider() throws Exception { return vhss.stream().map(cvh -> new Object[]{cvh}).toArray(Object[][]::new); } - @DataProvider public Object[][] typesProvider() throws Exception { List> aepts = Arrays.asList(byte[].class, int.class); List> bbpts = Arrays.asList(ByteBuffer.class, int.class); diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleBaseTest.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleBaseTest.java index 0c9a7fd3953..0e029b8f5f7 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleBaseTest.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleBaseTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 +36,7 @@ import java.util.Map; import java.util.stream.Stream; import static java.util.stream.Collectors.toList; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; abstract class VarHandleBaseTest { static final int ITERS = Integer.getInteger("iters", 1); @@ -136,18 +136,7 @@ abstract class VarHandleBaseTest { static void checkWithThrowable(Class re, Object message, ThrowingRunnable r) { - Throwable _e = null; - try { - r.run(); - } - catch (Throwable e) { - _e = e; - } - message = message == null ? "" : message + ". "; - assertNotNull(_e, String.format("%sNo throwable thrown. Expected %s", message, re)); - if (!re.isInstance(_e)) { - fail(String.format("%sIncorrect throwable thrown, %s. Expected %s", message, _e, re), _e); - } + assertThrows(re, r::run, message == null ? null : message.toString()); } @@ -277,11 +266,11 @@ abstract class VarHandleBaseTest { } private static MethodHandle bind(VarHandle vh, MethodHandle mh, MethodType emt) { - assertEquals(mh.type(), emt.insertParameterTypes(0, VarHandle.class), + assertEquals(emt.insertParameterTypes(0, VarHandle.class), mh.type(), "MethodHandle type differs from access mode type"); MethodHandleInfo info = MethodHandles.lookup().revealDirect(mh); - assertEquals(info.getMethodType(), emt, + assertEquals(emt, info.getMethodType(), "MethodHandleInfo method type differs from access mode type"); return mh.bindTo(vh); @@ -472,39 +461,39 @@ abstract class VarHandleBaseTest { for (TestAccessMode accessMode : testAccessModes()) { MethodType amt = vh.accessModeType(accessMode.toAccessMode()); - assertEquals(amt.parameterList().subList(0, pts.size()), pts); + assertEquals(pts, amt.parameterList().subList(0, pts.size())); } for (TestAccessMode testAccessMode : testAccessModesOfType(TestAccessType.GET)) { MethodType mt = vh.accessModeType(testAccessMode.toAccessMode()); - assertEquals(mt.returnType(), vh.varType()); - assertEquals(mt.parameterList(), pts); + assertEquals(vh.varType(), mt.returnType()); + assertEquals(pts, mt.parameterList()); } for (TestAccessMode testAccessMode : testAccessModesOfType(TestAccessType.SET)) { MethodType mt = vh.accessModeType(testAccessMode.toAccessMode()); - assertEquals(mt.returnType(), void.class); - assertEquals(mt.parameterType(mt.parameterCount() - 1), vh.varType()); + assertEquals(void.class, mt.returnType()); + assertEquals(vh.varType(), mt.parameterType(mt.parameterCount() - 1)); } for (TestAccessMode testAccessMode : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) { MethodType mt = vh.accessModeType(testAccessMode.toAccessMode()); - assertEquals(mt.returnType(), boolean.class); - assertEquals(mt.parameterType(mt.parameterCount() - 1), vh.varType()); - assertEquals(mt.parameterType(mt.parameterCount() - 2), vh.varType()); + assertEquals(boolean.class, mt.returnType()); + assertEquals(vh.varType(), mt.parameterType(mt.parameterCount() - 1)); + assertEquals(vh.varType(), mt.parameterType(mt.parameterCount() - 2)); } for (TestAccessMode testAccessMode : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) { MethodType mt = vh.accessModeType(testAccessMode.toAccessMode()); - assertEquals(mt.returnType(), vh.varType()); - assertEquals(mt.parameterType(mt.parameterCount() - 1), vh.varType()); - assertEquals(mt.parameterType(mt.parameterCount() - 2), vh.varType()); + assertEquals(vh.varType(), mt.returnType()); + assertEquals(vh.varType(), mt.parameterType(mt.parameterCount() - 1)); + assertEquals(vh.varType(), mt.parameterType(mt.parameterCount() - 2)); } for (TestAccessMode testAccessMode : testAccessModesOfType(TestAccessType.GET_AND_SET, TestAccessType.GET_AND_ADD)) { MethodType mt = vh.accessModeType(testAccessMode.toAccessMode()); - assertEquals(mt.returnType(), vh.varType()); - assertEquals(mt.parameterType(mt.parameterCount() - 1), vh.varType()); + assertEquals(vh.varType(), mt.returnType()); + assertEquals(vh.varType(), mt.parameterType(mt.parameterCount() - 1)); } } diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleMethodReferenceTest.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleMethodReferenceTest.java index 02de5a3e186..23e46096073 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleMethodReferenceTest.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleMethodReferenceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,12 +25,12 @@ * @test * @bug 8195650 * @summary Test linking of method references to VarHandle access methods. - * @run testng VarHandleMethodReferenceTest + * @run junit VarHandleMethodReferenceTest */ -import org.testng.annotations.Test; import java.lang.invoke.*; +import org.junit.jupiter.api.Test; public class VarHandleMethodReferenceTest { diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java index a9cd5a61655..548e008b09e 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,28 +23,30 @@ /* * @test - * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessBoolean + * @run junit/othervm -Diters=10 -Xint VarHandleTestAccessBoolean * * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations * to hit compilation thresholds * - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestAccessBoolean - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestAccessBoolean - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestAccessBoolean + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestAccessBoolean + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestAccessBoolean + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestAccessBoolean */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestAccessBoolean extends VarHandleBaseTest { static final boolean static_final_v = true; @@ -108,7 +110,7 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { return vhs.toArray(new VarHandle[0]); } - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestAccessBoolean.class, "final_v", boolean.class); @@ -125,8 +127,6 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { vhArray = MethodHandles.arrayElementVarHandle(boolean[].class); } - - @DataProvider public Object[][] varHandlesProvider() throws Exception { List vhs = new ArrayList<>(); vhs.add(vhField); @@ -156,7 +156,8 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { } } - @Test(dataProvider = "varHandlesProvider") + @ParameterizedTest + @MethodSource("varHandlesProvider") public void testIsAccessModeSupported(VarHandle vh) { assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET)); @@ -194,8 +195,6 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE)); } - - @DataProvider public Object[][] typesProvider() throws Exception { List types = new ArrayList<>(); types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessBoolean.class)}); @@ -205,16 +204,16 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { return types.stream().toArray(Object[][]::new); } - @Test(dataProvider = "typesProvider") + @ParameterizedTest + @MethodSource("typesProvider") public void testTypes(VarHandle vh, List> pts) { - assertEquals(vh.varType(), boolean.class); + assertEquals(boolean.class, vh.varType()); - assertEquals(vh.coordinateTypes(), pts); + assertEquals(pts, vh.coordinateTypes()); testTypes(vh); } - @Test public void testLookupInstanceToStatic() { checkIAE("Lookup of static final field to instance final field", () -> { @@ -241,8 +240,6 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { }); } - - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -284,7 +281,8 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -297,26 +295,26 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { // Plain { boolean x = (boolean) vh.get(recv); - assertEquals(x, true, "get boolean value"); + assertEquals(true, x, "get boolean value"); } // Volatile { boolean x = (boolean) vh.getVolatile(recv); - assertEquals(x, true, "getVolatile boolean value"); + assertEquals(true, x, "getVolatile boolean value"); } // Lazy { boolean x = (boolean) vh.getAcquire(recv); - assertEquals(x, true, "getRelease boolean value"); + assertEquals(true, x, "getRelease boolean value"); } // Opaque { boolean x = (boolean) vh.getOpaque(recv); - assertEquals(x, true, "getOpaque boolean value"); + assertEquals(true, x, "getOpaque boolean value"); } } @@ -357,26 +355,26 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { // Plain { boolean x = (boolean) vh.get(); - assertEquals(x, true, "get boolean value"); + assertEquals(true, x, "get boolean value"); } // Volatile { boolean x = (boolean) vh.getVolatile(); - assertEquals(x, true, "getVolatile boolean value"); + assertEquals(true, x, "getVolatile boolean value"); } // Lazy { boolean x = (boolean) vh.getAcquire(); - assertEquals(x, true, "getRelease boolean value"); + assertEquals(true, x, "getRelease boolean value"); } // Opaque { boolean x = (boolean) vh.getOpaque(); - assertEquals(x, true, "getOpaque boolean value"); + assertEquals(true, x, "getOpaque boolean value"); } } @@ -418,7 +416,7 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { { vh.set(recv, true); boolean x = (boolean) vh.get(recv); - assertEquals(x, true, "set boolean value"); + assertEquals(true, x, "set boolean value"); } @@ -426,21 +424,21 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { { vh.setVolatile(recv, false); boolean x = (boolean) vh.getVolatile(recv); - assertEquals(x, false, "setVolatile boolean value"); + assertEquals(false, x, "setVolatile boolean value"); } // Lazy { vh.setRelease(recv, true); boolean x = (boolean) vh.getAcquire(recv); - assertEquals(x, true, "setRelease boolean value"); + assertEquals(true, x, "setRelease boolean value"); } // Opaque { vh.setOpaque(recv, false); boolean x = (boolean) vh.getOpaque(recv); - assertEquals(x, false, "setOpaque boolean value"); + assertEquals(false, x, "setOpaque boolean value"); } vh.set(recv, true); @@ -450,56 +448,56 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { boolean r = vh.compareAndSet(recv, true, false); assertEquals(r, true, "success compareAndSet boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, false, "success compareAndSet boolean value"); + assertEquals(false, x, "success compareAndSet boolean value"); } { boolean r = vh.compareAndSet(recv, true, false); assertEquals(r, false, "failing compareAndSet boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, false, "failing compareAndSet boolean value"); + assertEquals(false, x, "failing compareAndSet boolean value"); } { boolean r = (boolean) vh.compareAndExchange(recv, false, true); assertEquals(r, false, "success compareAndExchange boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, true, "success compareAndExchange boolean value"); + assertEquals(true, x, "success compareAndExchange boolean value"); } { boolean r = (boolean) vh.compareAndExchange(recv, false, false); assertEquals(r, true, "failing compareAndExchange boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, true, "failing compareAndExchange boolean value"); + assertEquals(true, x, "failing compareAndExchange boolean value"); } { boolean r = (boolean) vh.compareAndExchangeAcquire(recv, true, false); assertEquals(r, true, "success compareAndExchangeAcquire boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, false, "success compareAndExchangeAcquire boolean value"); + assertEquals(false, x, "success compareAndExchangeAcquire boolean value"); } { boolean r = (boolean) vh.compareAndExchangeAcquire(recv, true, false); assertEquals(r, false, "failing compareAndExchangeAcquire boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, false, "failing compareAndExchangeAcquire boolean value"); + assertEquals(false, x, "failing compareAndExchangeAcquire boolean value"); } { boolean r = (boolean) vh.compareAndExchangeRelease(recv, false, true); assertEquals(r, false, "success compareAndExchangeRelease boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, true, "success compareAndExchangeRelease boolean value"); + assertEquals(true, x, "success compareAndExchangeRelease boolean value"); } { boolean r = (boolean) vh.compareAndExchangeRelease(recv, false, false); assertEquals(r, true, "failing compareAndExchangeRelease boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, true, "failing compareAndExchangeRelease boolean value"); + assertEquals(true, x, "failing compareAndExchangeRelease boolean value"); } { @@ -510,14 +508,14 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, false, "success weakCompareAndSetPlain boolean value"); + assertEquals(false, x, "success weakCompareAndSetPlain boolean value"); } { boolean success = vh.weakCompareAndSetPlain(recv, true, false); assertEquals(success, false, "failing weakCompareAndSetPlain boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, false, "failing weakCompareAndSetPlain boolean value"); + assertEquals(false, x, "failing weakCompareAndSetPlain boolean value"); } { @@ -528,14 +526,14 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, true, "success weakCompareAndSetAcquire boolean"); + assertEquals(true, x, "success weakCompareAndSetAcquire boolean"); } { boolean success = vh.weakCompareAndSetAcquire(recv, false, false); assertEquals(success, false, "failing weakCompareAndSetAcquire boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, true, "failing weakCompareAndSetAcquire boolean value"); + assertEquals(true, x, "failing weakCompareAndSetAcquire boolean value"); } { @@ -546,14 +544,14 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, false, "success weakCompareAndSetRelease boolean"); + assertEquals(false, x, "success weakCompareAndSetRelease boolean"); } { boolean success = vh.weakCompareAndSetRelease(recv, true, false); assertEquals(success, false, "failing weakCompareAndSetRelease boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, false, "failing weakCompareAndSetRelease boolean value"); + assertEquals(false, x, "failing weakCompareAndSetRelease boolean value"); } { @@ -564,14 +562,14 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, true, "success weakCompareAndSet boolean value"); + assertEquals(true, x, "success weakCompareAndSet boolean value"); } { boolean success = vh.weakCompareAndSet(recv, false, false); assertEquals(success, false, "failing weakCompareAndSet boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, true, "failing weakCompareAndSet boolean value"); + assertEquals(true, x, "failing weakCompareAndSet boolean value"); } // Compare set and get @@ -579,27 +577,27 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { vh.set(recv, true); boolean o = (boolean) vh.getAndSet(recv, false); - assertEquals(o, true, "getAndSet boolean"); + assertEquals(true, o, "getAndSet boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, false, "getAndSet boolean value"); + assertEquals(false, x, "getAndSet boolean value"); } { vh.set(recv, true); boolean o = (boolean) vh.getAndSetAcquire(recv, false); - assertEquals(o, true, "getAndSetAcquire boolean"); + assertEquals(true, o, "getAndSetAcquire boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, false, "getAndSetAcquire boolean value"); + assertEquals(false, x, "getAndSetAcquire boolean value"); } { vh.set(recv, true); boolean o = (boolean) vh.getAndSetRelease(recv, false); - assertEquals(o, true, "getAndSetRelease boolean"); + assertEquals(true, o, "getAndSetRelease boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, false, "getAndSetRelease boolean value"); + assertEquals(false, x, "getAndSetRelease boolean value"); } @@ -608,27 +606,27 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { vh.set(recv, true); boolean o = (boolean) vh.getAndBitwiseOr(recv, false); - assertEquals(o, true, "getAndBitwiseOr boolean"); + assertEquals(true, o, "getAndBitwiseOr boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, (boolean)(true | false), "getAndBitwiseOr boolean value"); + assertEquals((boolean)(true | false), x, "getAndBitwiseOr boolean value"); } { vh.set(recv, true); boolean o = (boolean) vh.getAndBitwiseOrAcquire(recv, false); - assertEquals(o, true, "getAndBitwiseOrAcquire boolean"); + assertEquals(true, o, "getAndBitwiseOrAcquire boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, (boolean)(true | false), "getAndBitwiseOrAcquire boolean value"); + assertEquals((boolean)(true | false), x, "getAndBitwiseOrAcquire boolean value"); } { vh.set(recv, true); boolean o = (boolean) vh.getAndBitwiseOrRelease(recv, false); - assertEquals(o, true, "getAndBitwiseOrRelease boolean"); + assertEquals(true, o, "getAndBitwiseOrRelease boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, (boolean)(true | false), "getAndBitwiseOrRelease boolean value"); + assertEquals((boolean)(true | false), x, "getAndBitwiseOrRelease boolean value"); } // get and bitwise and @@ -636,27 +634,27 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { vh.set(recv, true); boolean o = (boolean) vh.getAndBitwiseAnd(recv, false); - assertEquals(o, true, "getAndBitwiseAnd boolean"); + assertEquals(true, o, "getAndBitwiseAnd boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, (boolean)(true & false), "getAndBitwiseAnd boolean value"); + assertEquals((boolean)(true & false), x, "getAndBitwiseAnd boolean value"); } { vh.set(recv, true); boolean o = (boolean) vh.getAndBitwiseAndAcquire(recv, false); - assertEquals(o, true, "getAndBitwiseAndAcquire boolean"); + assertEquals(true, o, "getAndBitwiseAndAcquire boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, (boolean)(true & false), "getAndBitwiseAndAcquire boolean value"); + assertEquals((boolean)(true & false), x, "getAndBitwiseAndAcquire boolean value"); } { vh.set(recv, true); boolean o = (boolean) vh.getAndBitwiseAndRelease(recv, false); - assertEquals(o, true, "getAndBitwiseAndRelease boolean"); + assertEquals(true, o, "getAndBitwiseAndRelease boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, (boolean)(true & false), "getAndBitwiseAndRelease boolean value"); + assertEquals((boolean)(true & false), x, "getAndBitwiseAndRelease boolean value"); } // get and bitwise xor @@ -664,27 +662,27 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { vh.set(recv, true); boolean o = (boolean) vh.getAndBitwiseXor(recv, false); - assertEquals(o, true, "getAndBitwiseXor boolean"); + assertEquals(true, o, "getAndBitwiseXor boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, (boolean)(true ^ false), "getAndBitwiseXor boolean value"); + assertEquals((boolean)(true ^ false), x, "getAndBitwiseXor boolean value"); } { vh.set(recv, true); boolean o = (boolean) vh.getAndBitwiseXorAcquire(recv, false); - assertEquals(o, true, "getAndBitwiseXorAcquire boolean"); + assertEquals(true, o, "getAndBitwiseXorAcquire boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, (boolean)(true ^ false), "getAndBitwiseXorAcquire boolean value"); + assertEquals((boolean)(true ^ false), x, "getAndBitwiseXorAcquire boolean value"); } { vh.set(recv, true); boolean o = (boolean) vh.getAndBitwiseXorRelease(recv, false); - assertEquals(o, true, "getAndBitwiseXorRelease boolean"); + assertEquals(true, o, "getAndBitwiseXorRelease boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, (boolean)(true ^ false), "getAndBitwiseXorRelease boolean value"); + assertEquals((boolean)(true ^ false), x, "getAndBitwiseXorRelease boolean value"); } } @@ -710,7 +708,7 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { { vh.set(true); boolean x = (boolean) vh.get(); - assertEquals(x, true, "set boolean value"); + assertEquals(true, x, "set boolean value"); } @@ -718,21 +716,21 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { { vh.setVolatile(false); boolean x = (boolean) vh.getVolatile(); - assertEquals(x, false, "setVolatile boolean value"); + assertEquals(false, x, "setVolatile boolean value"); } // Lazy { vh.setRelease(true); boolean x = (boolean) vh.getAcquire(); - assertEquals(x, true, "setRelease boolean value"); + assertEquals(true, x, "setRelease boolean value"); } // Opaque { vh.setOpaque(false); boolean x = (boolean) vh.getOpaque(); - assertEquals(x, false, "setOpaque boolean value"); + assertEquals(false, x, "setOpaque boolean value"); } vh.set(true); @@ -742,56 +740,56 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { boolean r = vh.compareAndSet(true, false); assertEquals(r, true, "success compareAndSet boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, false, "success compareAndSet boolean value"); + assertEquals(false, x, "success compareAndSet boolean value"); } { boolean r = vh.compareAndSet(true, false); assertEquals(r, false, "failing compareAndSet boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, false, "failing compareAndSet boolean value"); + assertEquals(false, x, "failing compareAndSet boolean value"); } { boolean r = (boolean) vh.compareAndExchange(false, true); assertEquals(r, false, "success compareAndExchange boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, true, "success compareAndExchange boolean value"); + assertEquals(true, x, "success compareAndExchange boolean value"); } { boolean r = (boolean) vh.compareAndExchange(false, false); assertEquals(r, true, "failing compareAndExchange boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, true, "failing compareAndExchange boolean value"); + assertEquals(true, x, "failing compareAndExchange boolean value"); } { boolean r = (boolean) vh.compareAndExchangeAcquire(true, false); assertEquals(r, true, "success compareAndExchangeAcquire boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, false, "success compareAndExchangeAcquire boolean value"); + assertEquals(false, x, "success compareAndExchangeAcquire boolean value"); } { boolean r = (boolean) vh.compareAndExchangeAcquire(true, false); assertEquals(r, false, "failing compareAndExchangeAcquire boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, false, "failing compareAndExchangeAcquire boolean value"); + assertEquals(false, x, "failing compareAndExchangeAcquire boolean value"); } { boolean r = (boolean) vh.compareAndExchangeRelease(false, true); assertEquals(r, false, "success compareAndExchangeRelease boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, true, "success compareAndExchangeRelease boolean value"); + assertEquals(true, x, "success compareAndExchangeRelease boolean value"); } { boolean r = (boolean) vh.compareAndExchangeRelease(false, false); assertEquals(r, true, "failing compareAndExchangeRelease boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, true, "failing compareAndExchangeRelease boolean value"); + assertEquals(true, x, "failing compareAndExchangeRelease boolean value"); } { @@ -802,14 +800,14 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, false, "success weakCompareAndSetPlain boolean value"); + assertEquals(false, x, "success weakCompareAndSetPlain boolean value"); } { boolean success = vh.weakCompareAndSetPlain(true, false); assertEquals(success, false, "failing weakCompareAndSetPlain boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, false, "failing weakCompareAndSetPlain boolean value"); + assertEquals(false, x, "failing weakCompareAndSetPlain boolean value"); } { @@ -820,14 +818,14 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, true, "success weakCompareAndSetAcquire boolean"); + assertEquals(true, x, "success weakCompareAndSetAcquire boolean"); } { boolean success = vh.weakCompareAndSetAcquire(false, false); assertEquals(success, false, "failing weakCompareAndSetAcquire boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, true, "failing weakCompareAndSetAcquire boolean value"); + assertEquals(true, x, "failing weakCompareAndSetAcquire boolean value"); } { @@ -838,14 +836,14 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, false, "success weakCompareAndSetRelease boolean"); + assertEquals(false, x, "success weakCompareAndSetRelease boolean"); } { boolean success = vh.weakCompareAndSetRelease(true, false); assertEquals(success, false, "failing weakCompareAndSetRelease boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, false, "failing weakCompareAndSetRelease boolean value"); + assertEquals(false, x, "failing weakCompareAndSetRelease boolean value"); } { @@ -856,14 +854,14 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, true, "success weakCompareAndSet boolean"); + assertEquals(true, x, "success weakCompareAndSet boolean"); } { boolean success = vh.weakCompareAndSet(false, false); assertEquals(success, false, "failing weakCompareAndSet boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, true, "failing weakCompareAndSet boolean value"); + assertEquals(true, x, "failing weakCompareAndSet boolean value"); } // Compare set and get @@ -871,27 +869,27 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { vh.set(true); boolean o = (boolean) vh.getAndSet(false); - assertEquals(o, true, "getAndSet boolean"); + assertEquals(true, o, "getAndSet boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, false, "getAndSet boolean value"); + assertEquals(false, x, "getAndSet boolean value"); } { vh.set(true); boolean o = (boolean) vh.getAndSetAcquire(false); - assertEquals(o, true, "getAndSetAcquire boolean"); + assertEquals(true, o, "getAndSetAcquire boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, false, "getAndSetAcquire boolean value"); + assertEquals(false, x, "getAndSetAcquire boolean value"); } { vh.set(true); boolean o = (boolean) vh.getAndSetRelease(false); - assertEquals(o, true, "getAndSetRelease boolean"); + assertEquals(true, o, "getAndSetRelease boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, false, "getAndSetRelease boolean value"); + assertEquals(false, x, "getAndSetRelease boolean value"); } @@ -900,27 +898,27 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { vh.set(true); boolean o = (boolean) vh.getAndBitwiseOr(false); - assertEquals(o, true, "getAndBitwiseOr boolean"); + assertEquals(true, o, "getAndBitwiseOr boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, (boolean)(true | false), "getAndBitwiseOr boolean value"); + assertEquals((boolean)(true | false), x, "getAndBitwiseOr boolean value"); } { vh.set(true); boolean o = (boolean) vh.getAndBitwiseOrAcquire(false); - assertEquals(o, true, "getAndBitwiseOrAcquire boolean"); + assertEquals(true, o, "getAndBitwiseOrAcquire boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, (boolean)(true | false), "getAndBitwiseOrAcquire boolean value"); + assertEquals((boolean)(true | false), x, "getAndBitwiseOrAcquire boolean value"); } { vh.set(true); boolean o = (boolean) vh.getAndBitwiseOrRelease(false); - assertEquals(o, true, "getAndBitwiseOrRelease boolean"); + assertEquals(true, o, "getAndBitwiseOrRelease boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, (boolean)(true | false), "getAndBitwiseOrRelease boolean value"); + assertEquals((boolean)(true | false), x, "getAndBitwiseOrRelease boolean value"); } // get and bitwise and @@ -928,27 +926,27 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { vh.set(true); boolean o = (boolean) vh.getAndBitwiseAnd(false); - assertEquals(o, true, "getAndBitwiseAnd boolean"); + assertEquals(true, o, "getAndBitwiseAnd boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, (boolean)(true & false), "getAndBitwiseAnd boolean value"); + assertEquals((boolean)(true & false), x, "getAndBitwiseAnd boolean value"); } { vh.set(true); boolean o = (boolean) vh.getAndBitwiseAndAcquire(false); - assertEquals(o, true, "getAndBitwiseAndAcquire boolean"); + assertEquals(true, o, "getAndBitwiseAndAcquire boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, (boolean)(true & false), "getAndBitwiseAndAcquire boolean value"); + assertEquals((boolean)(true & false), x, "getAndBitwiseAndAcquire boolean value"); } { vh.set(true); boolean o = (boolean) vh.getAndBitwiseAndRelease(false); - assertEquals(o, true, "getAndBitwiseAndRelease boolean"); + assertEquals(true, o, "getAndBitwiseAndRelease boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, (boolean)(true & false), "getAndBitwiseAndRelease boolean value"); + assertEquals((boolean)(true & false), x, "getAndBitwiseAndRelease boolean value"); } // get and bitwise xor @@ -956,27 +954,27 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { vh.set(true); boolean o = (boolean) vh.getAndBitwiseXor(false); - assertEquals(o, true, "getAndBitwiseXor boolean"); + assertEquals(true, o, "getAndBitwiseXor boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, (boolean)(true ^ false), "getAndBitwiseXor boolean value"); + assertEquals((boolean)(true ^ false), x, "getAndBitwiseXor boolean value"); } { vh.set(true); boolean o = (boolean) vh.getAndBitwiseXorAcquire(false); - assertEquals(o, true, "getAndBitwiseXorAcquire boolean"); + assertEquals(true, o, "getAndBitwiseXorAcquire boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, (boolean)(true ^ false), "getAndBitwiseXorAcquire boolean value"); + assertEquals((boolean)(true ^ false), x, "getAndBitwiseXorAcquire boolean value"); } { vh.set(true); boolean o = (boolean) vh.getAndBitwiseXorRelease(false); - assertEquals(o, true, "getAndBitwiseXorRelease boolean"); + assertEquals(true, o, "getAndBitwiseXorRelease boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, (boolean)(true ^ false), "getAndBitwiseXorRelease boolean value"); + assertEquals((boolean)(true ^ false), x, "getAndBitwiseXorRelease boolean value"); } } @@ -1005,7 +1003,7 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { { vh.set(array, i, true); boolean x = (boolean) vh.get(array, i); - assertEquals(x, true, "get boolean value"); + assertEquals(true, x, "get boolean value"); } @@ -1013,21 +1011,21 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { { vh.setVolatile(array, i, false); boolean x = (boolean) vh.getVolatile(array, i); - assertEquals(x, false, "setVolatile boolean value"); + assertEquals(false, x, "setVolatile boolean value"); } // Lazy { vh.setRelease(array, i, true); boolean x = (boolean) vh.getAcquire(array, i); - assertEquals(x, true, "setRelease boolean value"); + assertEquals(true, x, "setRelease boolean value"); } // Opaque { vh.setOpaque(array, i, false); boolean x = (boolean) vh.getOpaque(array, i); - assertEquals(x, false, "setOpaque boolean value"); + assertEquals(false, x, "setOpaque boolean value"); } vh.set(array, i, true); @@ -1037,56 +1035,56 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { boolean r = vh.compareAndSet(array, i, true, false); assertEquals(r, true, "success compareAndSet boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, false, "success compareAndSet boolean value"); + assertEquals(false, x, "success compareAndSet boolean value"); } { boolean r = vh.compareAndSet(array, i, true, false); assertEquals(r, false, "failing compareAndSet boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, false, "failing compareAndSet boolean value"); + assertEquals(false, x, "failing compareAndSet boolean value"); } { boolean r = (boolean) vh.compareAndExchange(array, i, false, true); assertEquals(r, false, "success compareAndExchange boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, true, "success compareAndExchange boolean value"); + assertEquals(true, x, "success compareAndExchange boolean value"); } { boolean r = (boolean) vh.compareAndExchange(array, i, false, false); assertEquals(r, true, "failing compareAndExchange boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, true, "failing compareAndExchange boolean value"); + assertEquals(true, x, "failing compareAndExchange boolean value"); } { boolean r = (boolean) vh.compareAndExchangeAcquire(array, i, true, false); assertEquals(r, true, "success compareAndExchangeAcquire boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, false, "success compareAndExchangeAcquire boolean value"); + assertEquals(false, x, "success compareAndExchangeAcquire boolean value"); } { boolean r = (boolean) vh.compareAndExchangeAcquire(array, i, true, false); assertEquals(r, false, "failing compareAndExchangeAcquire boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, false, "failing compareAndExchangeAcquire boolean value"); + assertEquals(false, x, "failing compareAndExchangeAcquire boolean value"); } { boolean r = (boolean) vh.compareAndExchangeRelease(array, i, false, true); assertEquals(r, false, "success compareAndExchangeRelease boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, true, "success compareAndExchangeRelease boolean value"); + assertEquals(true, x, "success compareAndExchangeRelease boolean value"); } { boolean r = (boolean) vh.compareAndExchangeRelease(array, i, false, false); assertEquals(r, true, "failing compareAndExchangeRelease boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, true, "failing compareAndExchangeRelease boolean value"); + assertEquals(true, x, "failing compareAndExchangeRelease boolean value"); } { @@ -1097,14 +1095,14 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, false, "success weakCompareAndSetPlain boolean value"); + assertEquals(false, x, "success weakCompareAndSetPlain boolean value"); } { boolean success = vh.weakCompareAndSetPlain(array, i, true, false); assertEquals(success, false, "failing weakCompareAndSetPlain boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, false, "failing weakCompareAndSetPlain boolean value"); + assertEquals(false, x, "failing weakCompareAndSetPlain boolean value"); } { @@ -1115,14 +1113,14 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, true, "success weakCompareAndSetAcquire boolean"); + assertEquals(true, x, "success weakCompareAndSetAcquire boolean"); } { boolean success = vh.weakCompareAndSetAcquire(array, i, false, false); assertEquals(success, false, "failing weakCompareAndSetAcquire boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, true, "failing weakCompareAndSetAcquire boolean value"); + assertEquals(true, x, "failing weakCompareAndSetAcquire boolean value"); } { @@ -1133,14 +1131,14 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, false, "success weakCompareAndSetRelease boolean"); + assertEquals(false, x, "success weakCompareAndSetRelease boolean"); } { boolean success = vh.weakCompareAndSetRelease(array, i, true, false); assertEquals(success, false, "failing weakCompareAndSetRelease boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, false, "failing weakCompareAndSetRelease boolean value"); + assertEquals(false, x, "failing weakCompareAndSetRelease boolean value"); } { @@ -1151,14 +1149,14 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, true, "success weakCompareAndSet boolean"); + assertEquals(true, x, "success weakCompareAndSet boolean"); } { boolean success = vh.weakCompareAndSet(array, i, false, false); assertEquals(success, false, "failing weakCompareAndSet boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, true, "failing weakCompareAndSet boolean value"); + assertEquals(true, x, "failing weakCompareAndSet boolean value"); } // Compare set and get @@ -1166,27 +1164,27 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { vh.set(array, i, true); boolean o = (boolean) vh.getAndSet(array, i, false); - assertEquals(o, true, "getAndSet boolean"); + assertEquals(true, o, "getAndSet boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, false, "getAndSet boolean value"); + assertEquals(false, x, "getAndSet boolean value"); } { vh.set(array, i, true); boolean o = (boolean) vh.getAndSetAcquire(array, i, false); - assertEquals(o, true, "getAndSetAcquire boolean"); + assertEquals(true, o, "getAndSetAcquire boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, false, "getAndSetAcquire boolean value"); + assertEquals(false, x, "getAndSetAcquire boolean value"); } { vh.set(array, i, true); boolean o = (boolean) vh.getAndSetRelease(array, i, false); - assertEquals(o, true, "getAndSetRelease boolean"); + assertEquals(true, o, "getAndSetRelease boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, false, "getAndSetRelease boolean value"); + assertEquals(false, x, "getAndSetRelease boolean value"); } @@ -1195,27 +1193,27 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { vh.set(array, i, true); boolean o = (boolean) vh.getAndBitwiseOr(array, i, false); - assertEquals(o, true, "getAndBitwiseOr boolean"); + assertEquals(true, o, "getAndBitwiseOr boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, (boolean)(true | false), "getAndBitwiseOr boolean value"); + assertEquals((boolean)(true | false), x, "getAndBitwiseOr boolean value"); } { vh.set(array, i, true); boolean o = (boolean) vh.getAndBitwiseOrAcquire(array, i, false); - assertEquals(o, true, "getAndBitwiseOrAcquire boolean"); + assertEquals(true, o, "getAndBitwiseOrAcquire boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, (boolean)(true | false), "getAndBitwiseOrAcquire boolean value"); + assertEquals((boolean)(true | false), x, "getAndBitwiseOrAcquire boolean value"); } { vh.set(array, i, true); boolean o = (boolean) vh.getAndBitwiseOrRelease(array, i, false); - assertEquals(o, true, "getAndBitwiseOrRelease boolean"); + assertEquals(true, o, "getAndBitwiseOrRelease boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, (boolean)(true | false), "getAndBitwiseOrRelease boolean value"); + assertEquals((boolean)(true | false), x, "getAndBitwiseOrRelease boolean value"); } // get and bitwise and @@ -1223,27 +1221,27 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { vh.set(array, i, true); boolean o = (boolean) vh.getAndBitwiseAnd(array, i, false); - assertEquals(o, true, "getAndBitwiseAnd boolean"); + assertEquals(true, o, "getAndBitwiseAnd boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, (boolean)(true & false), "getAndBitwiseAnd boolean value"); + assertEquals((boolean)(true & false), x, "getAndBitwiseAnd boolean value"); } { vh.set(array, i, true); boolean o = (boolean) vh.getAndBitwiseAndAcquire(array, i, false); - assertEquals(o, true, "getAndBitwiseAndAcquire boolean"); + assertEquals(true, o, "getAndBitwiseAndAcquire boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, (boolean)(true & false), "getAndBitwiseAndAcquire boolean value"); + assertEquals((boolean)(true & false), x, "getAndBitwiseAndAcquire boolean value"); } { vh.set(array, i, true); boolean o = (boolean) vh.getAndBitwiseAndRelease(array, i, false); - assertEquals(o, true, "getAndBitwiseAndRelease boolean"); + assertEquals(true, o, "getAndBitwiseAndRelease boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, (boolean)(true & false), "getAndBitwiseAndRelease boolean value"); + assertEquals((boolean)(true & false), x, "getAndBitwiseAndRelease boolean value"); } // get and bitwise xor @@ -1251,27 +1249,27 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { vh.set(array, i, true); boolean o = (boolean) vh.getAndBitwiseXor(array, i, false); - assertEquals(o, true, "getAndBitwiseXor boolean"); + assertEquals(true, o, "getAndBitwiseXor boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, (boolean)(true ^ false), "getAndBitwiseXor boolean value"); + assertEquals((boolean)(true ^ false), x, "getAndBitwiseXor boolean value"); } { vh.set(array, i, true); boolean o = (boolean) vh.getAndBitwiseXorAcquire(array, i, false); - assertEquals(o, true, "getAndBitwiseXorAcquire boolean"); + assertEquals(true, o, "getAndBitwiseXorAcquire boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, (boolean)(true ^ false), "getAndBitwiseXorAcquire boolean value"); + assertEquals((boolean)(true ^ false), x, "getAndBitwiseXorAcquire boolean value"); } { vh.set(array, i, true); boolean o = (boolean) vh.getAndBitwiseXorRelease(array, i, false); - assertEquals(o, true, "getAndBitwiseXorRelease boolean"); + assertEquals(true, o, "getAndBitwiseXorRelease boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, (boolean)(true ^ false), "getAndBitwiseXorRelease boolean value"); + assertEquals((boolean)(true ^ false), x, "getAndBitwiseXorRelease boolean value"); } } } diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java index 5dc4bf2d1d5..42c465af75e 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,28 +23,30 @@ /* * @test - * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessByte + * @run junit/othervm -Diters=10 -Xint VarHandleTestAccessByte * * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations * to hit compilation thresholds * - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestAccessByte - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestAccessByte - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestAccessByte + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestAccessByte + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestAccessByte + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestAccessByte */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestAccessByte extends VarHandleBaseTest { static final byte static_final_v = (byte)0x01; @@ -108,7 +110,7 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { return vhs.toArray(new VarHandle[0]); } - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestAccessByte.class, "final_v", byte.class); @@ -125,8 +127,6 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { vhArray = MethodHandles.arrayElementVarHandle(byte[].class); } - - @DataProvider public Object[][] varHandlesProvider() throws Exception { List vhs = new ArrayList<>(); vhs.add(vhField); @@ -156,7 +156,8 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { } } - @Test(dataProvider = "varHandlesProvider") + @ParameterizedTest + @MethodSource("varHandlesProvider") public void testIsAccessModeSupported(VarHandle vh) { assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET)); @@ -194,8 +195,6 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE)); } - - @DataProvider public Object[][] typesProvider() throws Exception { List types = new ArrayList<>(); types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessByte.class)}); @@ -205,16 +204,16 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { return types.stream().toArray(Object[][]::new); } - @Test(dataProvider = "typesProvider") + @ParameterizedTest + @MethodSource("typesProvider") public void testTypes(VarHandle vh, List> pts) { - assertEquals(vh.varType(), byte.class); + assertEquals(byte.class, vh.varType()); - assertEquals(vh.coordinateTypes(), pts); + assertEquals(pts, vh.coordinateTypes()); testTypes(vh); } - @Test public void testLookupInstanceToStatic() { checkIAE("Lookup of static final field to instance final field", () -> { @@ -241,8 +240,6 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { }); } - - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -284,7 +281,8 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -297,26 +295,26 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { // Plain { byte x = (byte) vh.get(recv); - assertEquals(x, (byte)0x01, "get byte value"); + assertEquals((byte)0x01, x, "get byte value"); } // Volatile { byte x = (byte) vh.getVolatile(recv); - assertEquals(x, (byte)0x01, "getVolatile byte value"); + assertEquals((byte)0x01, x, "getVolatile byte value"); } // Lazy { byte x = (byte) vh.getAcquire(recv); - assertEquals(x, (byte)0x01, "getRelease byte value"); + assertEquals((byte)0x01, x, "getRelease byte value"); } // Opaque { byte x = (byte) vh.getOpaque(recv); - assertEquals(x, (byte)0x01, "getOpaque byte value"); + assertEquals((byte)0x01, x, "getOpaque byte value"); } } @@ -346,26 +344,26 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { // Plain { byte x = (byte) vh.get(); - assertEquals(x, (byte)0x01, "get byte value"); + assertEquals((byte)0x01, x, "get byte value"); } // Volatile { byte x = (byte) vh.getVolatile(); - assertEquals(x, (byte)0x01, "getVolatile byte value"); + assertEquals((byte)0x01, x, "getVolatile byte value"); } // Lazy { byte x = (byte) vh.getAcquire(); - assertEquals(x, (byte)0x01, "getRelease byte value"); + assertEquals((byte)0x01, x, "getRelease byte value"); } // Opaque { byte x = (byte) vh.getOpaque(); - assertEquals(x, (byte)0x01, "getOpaque byte value"); + assertEquals((byte)0x01, x, "getOpaque byte value"); } } @@ -396,7 +394,7 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { { vh.set(recv, (byte)0x01); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)0x01, "set byte value"); + assertEquals((byte)0x01, x, "set byte value"); } @@ -404,21 +402,21 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { { vh.setVolatile(recv, (byte)0x23); byte x = (byte) vh.getVolatile(recv); - assertEquals(x, (byte)0x23, "setVolatile byte value"); + assertEquals((byte)0x23, x, "setVolatile byte value"); } // Lazy { vh.setRelease(recv, (byte)0x01); byte x = (byte) vh.getAcquire(recv); - assertEquals(x, (byte)0x01, "setRelease byte value"); + assertEquals((byte)0x01, x, "setRelease byte value"); } // Opaque { vh.setOpaque(recv, (byte)0x23); byte x = (byte) vh.getOpaque(recv); - assertEquals(x, (byte)0x23, "setOpaque byte value"); + assertEquals((byte)0x23, x, "setOpaque byte value"); } vh.set(recv, (byte)0x01); @@ -428,56 +426,56 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { boolean r = vh.compareAndSet(recv, (byte)0x01, (byte)0x23); assertEquals(r, true, "success compareAndSet byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)0x23, "success compareAndSet byte value"); + assertEquals((byte)0x23, x, "success compareAndSet byte value"); } { boolean r = vh.compareAndSet(recv, (byte)0x01, (byte)0x45); assertEquals(r, false, "failing compareAndSet byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)0x23, "failing compareAndSet byte value"); + assertEquals((byte)0x23, x, "failing compareAndSet byte value"); } { byte r = (byte) vh.compareAndExchange(recv, (byte)0x23, (byte)0x01); assertEquals(r, (byte)0x23, "success compareAndExchange byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)0x01, "success compareAndExchange byte value"); + assertEquals((byte)0x01, x, "success compareAndExchange byte value"); } { byte r = (byte) vh.compareAndExchange(recv, (byte)0x23, (byte)0x45); assertEquals(r, (byte)0x01, "failing compareAndExchange byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)0x01, "failing compareAndExchange byte value"); + assertEquals((byte)0x01, x, "failing compareAndExchange byte value"); } { byte r = (byte) vh.compareAndExchangeAcquire(recv, (byte)0x01, (byte)0x23); assertEquals(r, (byte)0x01, "success compareAndExchangeAcquire byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)0x23, "success compareAndExchangeAcquire byte value"); + assertEquals((byte)0x23, x, "success compareAndExchangeAcquire byte value"); } { byte r = (byte) vh.compareAndExchangeAcquire(recv, (byte)0x01, (byte)0x45); assertEquals(r, (byte)0x23, "failing compareAndExchangeAcquire byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)0x23, "failing compareAndExchangeAcquire byte value"); + assertEquals((byte)0x23, x, "failing compareAndExchangeAcquire byte value"); } { byte r = (byte) vh.compareAndExchangeRelease(recv, (byte)0x23, (byte)0x01); assertEquals(r, (byte)0x23, "success compareAndExchangeRelease byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)0x01, "success compareAndExchangeRelease byte value"); + assertEquals((byte)0x01, x, "success compareAndExchangeRelease byte value"); } { byte r = (byte) vh.compareAndExchangeRelease(recv, (byte)0x23, (byte)0x45); assertEquals(r, (byte)0x01, "failing compareAndExchangeRelease byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)0x01, "failing compareAndExchangeRelease byte value"); + assertEquals((byte)0x01, x, "failing compareAndExchangeRelease byte value"); } { @@ -488,14 +486,14 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)0x23, "success weakCompareAndSetPlain byte value"); + assertEquals((byte)0x23, x, "success weakCompareAndSetPlain byte value"); } { boolean success = vh.weakCompareAndSetPlain(recv, (byte)0x01, (byte)0x45); assertEquals(success, false, "failing weakCompareAndSetPlain byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)0x23, "failing weakCompareAndSetPlain byte value"); + assertEquals((byte)0x23, x, "failing weakCompareAndSetPlain byte value"); } { @@ -506,14 +504,14 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)0x01, "success weakCompareAndSetAcquire byte"); + assertEquals((byte)0x01, x, "success weakCompareAndSetAcquire byte"); } { boolean success = vh.weakCompareAndSetAcquire(recv, (byte)0x23, (byte)0x45); assertEquals(success, false, "failing weakCompareAndSetAcquire byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)0x01, "failing weakCompareAndSetAcquire byte value"); + assertEquals((byte)0x01, x, "failing weakCompareAndSetAcquire byte value"); } { @@ -524,14 +522,14 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)0x23, "success weakCompareAndSetRelease byte"); + assertEquals((byte)0x23, x, "success weakCompareAndSetRelease byte"); } { boolean success = vh.weakCompareAndSetRelease(recv, (byte)0x01, (byte)0x45); assertEquals(success, false, "failing weakCompareAndSetRelease byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)0x23, "failing weakCompareAndSetRelease byte value"); + assertEquals((byte)0x23, x, "failing weakCompareAndSetRelease byte value"); } { @@ -542,14 +540,14 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)0x01, "success weakCompareAndSet byte value"); + assertEquals((byte)0x01, x, "success weakCompareAndSet byte value"); } { boolean success = vh.weakCompareAndSet(recv, (byte)0x23, (byte)0x45); assertEquals(success, false, "failing weakCompareAndSet byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)0x01, "failing weakCompareAndSet byte value"); + assertEquals((byte)0x01, x, "failing weakCompareAndSet byte value"); } // Compare set and get @@ -557,27 +555,27 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { vh.set(recv, (byte)0x01); byte o = (byte) vh.getAndSet(recv, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndSet byte"); + assertEquals((byte)0x01, o, "getAndSet byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)0x23, "getAndSet byte value"); + assertEquals((byte)0x23, x, "getAndSet byte value"); } { vh.set(recv, (byte)0x01); byte o = (byte) vh.getAndSetAcquire(recv, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndSetAcquire byte"); + assertEquals((byte)0x01, o, "getAndSetAcquire byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)0x23, "getAndSetAcquire byte value"); + assertEquals((byte)0x23, x, "getAndSetAcquire byte value"); } { vh.set(recv, (byte)0x01); byte o = (byte) vh.getAndSetRelease(recv, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndSetRelease byte"); + assertEquals((byte)0x01, o, "getAndSetRelease byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)0x23, "getAndSetRelease byte value"); + assertEquals((byte)0x23, x, "getAndSetRelease byte value"); } // get and add, add and get @@ -585,27 +583,27 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { vh.set(recv, (byte)0x01); byte o = (byte) vh.getAndAdd(recv, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndAdd byte"); + assertEquals((byte)0x01, o, "getAndAdd byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)((byte)0x01 + (byte)0x23), "getAndAdd byte value"); + assertEquals((byte)((byte)0x01 + (byte)0x23), x, "getAndAdd byte value"); } { vh.set(recv, (byte)0x01); byte o = (byte) vh.getAndAddAcquire(recv, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndAddAcquire byte"); + assertEquals((byte)0x01, o, "getAndAddAcquire byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)((byte)0x01 + (byte)0x23), "getAndAddAcquire byte value"); + assertEquals((byte)((byte)0x01 + (byte)0x23), x, "getAndAddAcquire byte value"); } { vh.set(recv, (byte)0x01); byte o = (byte) vh.getAndAddRelease(recv, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndAddReleasebyte"); + assertEquals((byte)0x01, o, "getAndAddReleasebyte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)((byte)0x01 + (byte)0x23), "getAndAddRelease byte value"); + assertEquals((byte)((byte)0x01 + (byte)0x23), x, "getAndAddRelease byte value"); } // get and bitwise or @@ -613,27 +611,27 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { vh.set(recv, (byte)0x01); byte o = (byte) vh.getAndBitwiseOr(recv, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseOr byte"); + assertEquals((byte)0x01, o, "getAndBitwiseOr byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)((byte)0x01 | (byte)0x23), "getAndBitwiseOr byte value"); + assertEquals((byte)((byte)0x01 | (byte)0x23), x, "getAndBitwiseOr byte value"); } { vh.set(recv, (byte)0x01); byte o = (byte) vh.getAndBitwiseOrAcquire(recv, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseOrAcquire byte"); + assertEquals((byte)0x01, o, "getAndBitwiseOrAcquire byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)((byte)0x01 | (byte)0x23), "getAndBitwiseOrAcquire byte value"); + assertEquals((byte)((byte)0x01 | (byte)0x23), x, "getAndBitwiseOrAcquire byte value"); } { vh.set(recv, (byte)0x01); byte o = (byte) vh.getAndBitwiseOrRelease(recv, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseOrRelease byte"); + assertEquals((byte)0x01, o, "getAndBitwiseOrRelease byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)((byte)0x01 | (byte)0x23), "getAndBitwiseOrRelease byte value"); + assertEquals((byte)((byte)0x01 | (byte)0x23), x, "getAndBitwiseOrRelease byte value"); } // get and bitwise and @@ -641,27 +639,27 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { vh.set(recv, (byte)0x01); byte o = (byte) vh.getAndBitwiseAnd(recv, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseAnd byte"); + assertEquals((byte)0x01, o, "getAndBitwiseAnd byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)((byte)0x01 & (byte)0x23), "getAndBitwiseAnd byte value"); + assertEquals((byte)((byte)0x01 & (byte)0x23), x, "getAndBitwiseAnd byte value"); } { vh.set(recv, (byte)0x01); byte o = (byte) vh.getAndBitwiseAndAcquire(recv, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseAndAcquire byte"); + assertEquals((byte)0x01, o, "getAndBitwiseAndAcquire byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)((byte)0x01 & (byte)0x23), "getAndBitwiseAndAcquire byte value"); + assertEquals((byte)((byte)0x01 & (byte)0x23), x, "getAndBitwiseAndAcquire byte value"); } { vh.set(recv, (byte)0x01); byte o = (byte) vh.getAndBitwiseAndRelease(recv, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseAndRelease byte"); + assertEquals((byte)0x01, o, "getAndBitwiseAndRelease byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)((byte)0x01 & (byte)0x23), "getAndBitwiseAndRelease byte value"); + assertEquals((byte)((byte)0x01 & (byte)0x23), x, "getAndBitwiseAndRelease byte value"); } // get and bitwise xor @@ -669,27 +667,27 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { vh.set(recv, (byte)0x01); byte o = (byte) vh.getAndBitwiseXor(recv, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseXor byte"); + assertEquals((byte)0x01, o, "getAndBitwiseXor byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)((byte)0x01 ^ (byte)0x23), "getAndBitwiseXor byte value"); + assertEquals((byte)((byte)0x01 ^ (byte)0x23), x, "getAndBitwiseXor byte value"); } { vh.set(recv, (byte)0x01); byte o = (byte) vh.getAndBitwiseXorAcquire(recv, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseXorAcquire byte"); + assertEquals((byte)0x01, o, "getAndBitwiseXorAcquire byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)((byte)0x01 ^ (byte)0x23), "getAndBitwiseXorAcquire byte value"); + assertEquals((byte)((byte)0x01 ^ (byte)0x23), x, "getAndBitwiseXorAcquire byte value"); } { vh.set(recv, (byte)0x01); byte o = (byte) vh.getAndBitwiseXorRelease(recv, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseXorRelease byte"); + assertEquals((byte)0x01, o, "getAndBitwiseXorRelease byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)((byte)0x01 ^ (byte)0x23), "getAndBitwiseXorRelease byte value"); + assertEquals((byte)((byte)0x01 ^ (byte)0x23), x, "getAndBitwiseXorRelease byte value"); } } @@ -704,7 +702,7 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { { vh.set((byte)0x01); byte x = (byte) vh.get(); - assertEquals(x, (byte)0x01, "set byte value"); + assertEquals((byte)0x01, x, "set byte value"); } @@ -712,21 +710,21 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { { vh.setVolatile((byte)0x23); byte x = (byte) vh.getVolatile(); - assertEquals(x, (byte)0x23, "setVolatile byte value"); + assertEquals((byte)0x23, x, "setVolatile byte value"); } // Lazy { vh.setRelease((byte)0x01); byte x = (byte) vh.getAcquire(); - assertEquals(x, (byte)0x01, "setRelease byte value"); + assertEquals((byte)0x01, x, "setRelease byte value"); } // Opaque { vh.setOpaque((byte)0x23); byte x = (byte) vh.getOpaque(); - assertEquals(x, (byte)0x23, "setOpaque byte value"); + assertEquals((byte)0x23, x, "setOpaque byte value"); } vh.set((byte)0x01); @@ -736,56 +734,56 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { boolean r = vh.compareAndSet((byte)0x01, (byte)0x23); assertEquals(r, true, "success compareAndSet byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)0x23, "success compareAndSet byte value"); + assertEquals((byte)0x23, x, "success compareAndSet byte value"); } { boolean r = vh.compareAndSet((byte)0x01, (byte)0x45); assertEquals(r, false, "failing compareAndSet byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)0x23, "failing compareAndSet byte value"); + assertEquals((byte)0x23, x, "failing compareAndSet byte value"); } { byte r = (byte) vh.compareAndExchange((byte)0x23, (byte)0x01); assertEquals(r, (byte)0x23, "success compareAndExchange byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)0x01, "success compareAndExchange byte value"); + assertEquals((byte)0x01, x, "success compareAndExchange byte value"); } { byte r = (byte) vh.compareAndExchange((byte)0x23, (byte)0x45); assertEquals(r, (byte)0x01, "failing compareAndExchange byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)0x01, "failing compareAndExchange byte value"); + assertEquals((byte)0x01, x, "failing compareAndExchange byte value"); } { byte r = (byte) vh.compareAndExchangeAcquire((byte)0x01, (byte)0x23); assertEquals(r, (byte)0x01, "success compareAndExchangeAcquire byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)0x23, "success compareAndExchangeAcquire byte value"); + assertEquals((byte)0x23, x, "success compareAndExchangeAcquire byte value"); } { byte r = (byte) vh.compareAndExchangeAcquire((byte)0x01, (byte)0x45); assertEquals(r, (byte)0x23, "failing compareAndExchangeAcquire byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)0x23, "failing compareAndExchangeAcquire byte value"); + assertEquals((byte)0x23, x, "failing compareAndExchangeAcquire byte value"); } { byte r = (byte) vh.compareAndExchangeRelease((byte)0x23, (byte)0x01); assertEquals(r, (byte)0x23, "success compareAndExchangeRelease byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)0x01, "success compareAndExchangeRelease byte value"); + assertEquals((byte)0x01, x, "success compareAndExchangeRelease byte value"); } { byte r = (byte) vh.compareAndExchangeRelease((byte)0x23, (byte)0x45); assertEquals(r, (byte)0x01, "failing compareAndExchangeRelease byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)0x01, "failing compareAndExchangeRelease byte value"); + assertEquals((byte)0x01, x, "failing compareAndExchangeRelease byte value"); } { @@ -796,14 +794,14 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)0x23, "success weakCompareAndSetPlain byte value"); + assertEquals((byte)0x23, x, "success weakCompareAndSetPlain byte value"); } { boolean success = vh.weakCompareAndSetPlain((byte)0x01, (byte)0x45); assertEquals(success, false, "failing weakCompareAndSetPlain byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)0x23, "failing weakCompareAndSetPlain byte value"); + assertEquals((byte)0x23, x, "failing weakCompareAndSetPlain byte value"); } { @@ -814,14 +812,14 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)0x01, "success weakCompareAndSetAcquire byte"); + assertEquals((byte)0x01, x, "success weakCompareAndSetAcquire byte"); } { boolean success = vh.weakCompareAndSetAcquire((byte)0x23, (byte)0x45); assertEquals(success, false, "failing weakCompareAndSetAcquire byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)0x01, "failing weakCompareAndSetAcquire byte value"); + assertEquals((byte)0x01, x, "failing weakCompareAndSetAcquire byte value"); } { @@ -832,14 +830,14 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)0x23, "success weakCompareAndSetRelease byte"); + assertEquals((byte)0x23, x, "success weakCompareAndSetRelease byte"); } { boolean success = vh.weakCompareAndSetRelease((byte)0x01, (byte)0x45); assertEquals(success, false, "failing weakCompareAndSetRelease byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)0x23, "failing weakCompareAndSetRelease byte value"); + assertEquals((byte)0x23, x, "failing weakCompareAndSetRelease byte value"); } { @@ -850,14 +848,14 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)0x01, "success weakCompareAndSet byte"); + assertEquals((byte)0x01, x, "success weakCompareAndSet byte"); } { boolean success = vh.weakCompareAndSet((byte)0x23, (byte)0x45); assertEquals(success, false, "failing weakCompareAndSet byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)0x01, "failing weakCompareAndSet byte value"); + assertEquals((byte)0x01, x, "failing weakCompareAndSet byte value"); } // Compare set and get @@ -865,27 +863,27 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { vh.set((byte)0x01); byte o = (byte) vh.getAndSet((byte)0x23); - assertEquals(o, (byte)0x01, "getAndSet byte"); + assertEquals((byte)0x01, o, "getAndSet byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)0x23, "getAndSet byte value"); + assertEquals((byte)0x23, x, "getAndSet byte value"); } { vh.set((byte)0x01); byte o = (byte) vh.getAndSetAcquire((byte)0x23); - assertEquals(o, (byte)0x01, "getAndSetAcquire byte"); + assertEquals((byte)0x01, o, "getAndSetAcquire byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)0x23, "getAndSetAcquire byte value"); + assertEquals((byte)0x23, x, "getAndSetAcquire byte value"); } { vh.set((byte)0x01); byte o = (byte) vh.getAndSetRelease((byte)0x23); - assertEquals(o, (byte)0x01, "getAndSetRelease byte"); + assertEquals((byte)0x01, o, "getAndSetRelease byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)0x23, "getAndSetRelease byte value"); + assertEquals((byte)0x23, x, "getAndSetRelease byte value"); } // get and add, add and get @@ -893,27 +891,27 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { vh.set((byte)0x01); byte o = (byte) vh.getAndAdd((byte)0x23); - assertEquals(o, (byte)0x01, "getAndAdd byte"); + assertEquals((byte)0x01, o, "getAndAdd byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)((byte)0x01 + (byte)0x23), "getAndAdd byte value"); + assertEquals((byte)((byte)0x01 + (byte)0x23), x, "getAndAdd byte value"); } { vh.set((byte)0x01); byte o = (byte) vh.getAndAddAcquire((byte)0x23); - assertEquals(o, (byte)0x01, "getAndAddAcquire byte"); + assertEquals((byte)0x01, o, "getAndAddAcquire byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)((byte)0x01 + (byte)0x23), "getAndAddAcquire byte value"); + assertEquals((byte)((byte)0x01 + (byte)0x23), x, "getAndAddAcquire byte value"); } { vh.set((byte)0x01); byte o = (byte) vh.getAndAddRelease((byte)0x23); - assertEquals(o, (byte)0x01, "getAndAddReleasebyte"); + assertEquals((byte)0x01, o, "getAndAddReleasebyte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)((byte)0x01 + (byte)0x23), "getAndAddRelease byte value"); + assertEquals((byte)((byte)0x01 + (byte)0x23), x, "getAndAddRelease byte value"); } // get and bitwise or @@ -921,27 +919,27 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { vh.set((byte)0x01); byte o = (byte) vh.getAndBitwiseOr((byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseOr byte"); + assertEquals((byte)0x01, o, "getAndBitwiseOr byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)((byte)0x01 | (byte)0x23), "getAndBitwiseOr byte value"); + assertEquals((byte)((byte)0x01 | (byte)0x23), x, "getAndBitwiseOr byte value"); } { vh.set((byte)0x01); byte o = (byte) vh.getAndBitwiseOrAcquire((byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseOrAcquire byte"); + assertEquals((byte)0x01, o, "getAndBitwiseOrAcquire byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)((byte)0x01 | (byte)0x23), "getAndBitwiseOrAcquire byte value"); + assertEquals((byte)((byte)0x01 | (byte)0x23), x, "getAndBitwiseOrAcquire byte value"); } { vh.set((byte)0x01); byte o = (byte) vh.getAndBitwiseOrRelease((byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseOrRelease byte"); + assertEquals((byte)0x01, o, "getAndBitwiseOrRelease byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)((byte)0x01 | (byte)0x23), "getAndBitwiseOrRelease byte value"); + assertEquals((byte)((byte)0x01 | (byte)0x23), x, "getAndBitwiseOrRelease byte value"); } // get and bitwise and @@ -949,27 +947,27 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { vh.set((byte)0x01); byte o = (byte) vh.getAndBitwiseAnd((byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseAnd byte"); + assertEquals((byte)0x01, o, "getAndBitwiseAnd byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)((byte)0x01 & (byte)0x23), "getAndBitwiseAnd byte value"); + assertEquals((byte)((byte)0x01 & (byte)0x23), x, "getAndBitwiseAnd byte value"); } { vh.set((byte)0x01); byte o = (byte) vh.getAndBitwiseAndAcquire((byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseAndAcquire byte"); + assertEquals((byte)0x01, o, "getAndBitwiseAndAcquire byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)((byte)0x01 & (byte)0x23), "getAndBitwiseAndAcquire byte value"); + assertEquals((byte)((byte)0x01 & (byte)0x23), x, "getAndBitwiseAndAcquire byte value"); } { vh.set((byte)0x01); byte o = (byte) vh.getAndBitwiseAndRelease((byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseAndRelease byte"); + assertEquals((byte)0x01, o, "getAndBitwiseAndRelease byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)((byte)0x01 & (byte)0x23), "getAndBitwiseAndRelease byte value"); + assertEquals((byte)((byte)0x01 & (byte)0x23), x, "getAndBitwiseAndRelease byte value"); } // get and bitwise xor @@ -977,27 +975,27 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { vh.set((byte)0x01); byte o = (byte) vh.getAndBitwiseXor((byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseXor byte"); + assertEquals((byte)0x01, o, "getAndBitwiseXor byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)((byte)0x01 ^ (byte)0x23), "getAndBitwiseXor byte value"); + assertEquals((byte)((byte)0x01 ^ (byte)0x23), x, "getAndBitwiseXor byte value"); } { vh.set((byte)0x01); byte o = (byte) vh.getAndBitwiseXorAcquire((byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseXorAcquire byte"); + assertEquals((byte)0x01, o, "getAndBitwiseXorAcquire byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)((byte)0x01 ^ (byte)0x23), "getAndBitwiseXorAcquire byte value"); + assertEquals((byte)((byte)0x01 ^ (byte)0x23), x, "getAndBitwiseXorAcquire byte value"); } { vh.set((byte)0x01); byte o = (byte) vh.getAndBitwiseXorRelease((byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseXorRelease byte"); + assertEquals((byte)0x01, o, "getAndBitwiseXorRelease byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)((byte)0x01 ^ (byte)0x23), "getAndBitwiseXorRelease byte value"); + assertEquals((byte)((byte)0x01 ^ (byte)0x23), x, "getAndBitwiseXorRelease byte value"); } } @@ -1015,7 +1013,7 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { { vh.set(array, i, (byte)0x01); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)0x01, "get byte value"); + assertEquals((byte)0x01, x, "get byte value"); } @@ -1023,21 +1021,21 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { { vh.setVolatile(array, i, (byte)0x23); byte x = (byte) vh.getVolatile(array, i); - assertEquals(x, (byte)0x23, "setVolatile byte value"); + assertEquals((byte)0x23, x, "setVolatile byte value"); } // Lazy { vh.setRelease(array, i, (byte)0x01); byte x = (byte) vh.getAcquire(array, i); - assertEquals(x, (byte)0x01, "setRelease byte value"); + assertEquals((byte)0x01, x, "setRelease byte value"); } // Opaque { vh.setOpaque(array, i, (byte)0x23); byte x = (byte) vh.getOpaque(array, i); - assertEquals(x, (byte)0x23, "setOpaque byte value"); + assertEquals((byte)0x23, x, "setOpaque byte value"); } vh.set(array, i, (byte)0x01); @@ -1047,56 +1045,56 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { boolean r = vh.compareAndSet(array, i, (byte)0x01, (byte)0x23); assertEquals(r, true, "success compareAndSet byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)0x23, "success compareAndSet byte value"); + assertEquals((byte)0x23, x, "success compareAndSet byte value"); } { boolean r = vh.compareAndSet(array, i, (byte)0x01, (byte)0x45); assertEquals(r, false, "failing compareAndSet byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)0x23, "failing compareAndSet byte value"); + assertEquals((byte)0x23, x, "failing compareAndSet byte value"); } { byte r = (byte) vh.compareAndExchange(array, i, (byte)0x23, (byte)0x01); assertEquals(r, (byte)0x23, "success compareAndExchange byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)0x01, "success compareAndExchange byte value"); + assertEquals((byte)0x01, x, "success compareAndExchange byte value"); } { byte r = (byte) vh.compareAndExchange(array, i, (byte)0x23, (byte)0x45); assertEquals(r, (byte)0x01, "failing compareAndExchange byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)0x01, "failing compareAndExchange byte value"); + assertEquals((byte)0x01, x, "failing compareAndExchange byte value"); } { byte r = (byte) vh.compareAndExchangeAcquire(array, i, (byte)0x01, (byte)0x23); assertEquals(r, (byte)0x01, "success compareAndExchangeAcquire byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)0x23, "success compareAndExchangeAcquire byte value"); + assertEquals((byte)0x23, x, "success compareAndExchangeAcquire byte value"); } { byte r = (byte) vh.compareAndExchangeAcquire(array, i, (byte)0x01, (byte)0x45); assertEquals(r, (byte)0x23, "failing compareAndExchangeAcquire byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)0x23, "failing compareAndExchangeAcquire byte value"); + assertEquals((byte)0x23, x, "failing compareAndExchangeAcquire byte value"); } { byte r = (byte) vh.compareAndExchangeRelease(array, i, (byte)0x23, (byte)0x01); assertEquals(r, (byte)0x23, "success compareAndExchangeRelease byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)0x01, "success compareAndExchangeRelease byte value"); + assertEquals((byte)0x01, x, "success compareAndExchangeRelease byte value"); } { byte r = (byte) vh.compareAndExchangeRelease(array, i, (byte)0x23, (byte)0x45); assertEquals(r, (byte)0x01, "failing compareAndExchangeRelease byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)0x01, "failing compareAndExchangeRelease byte value"); + assertEquals((byte)0x01, x, "failing compareAndExchangeRelease byte value"); } { @@ -1107,14 +1105,14 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)0x23, "success weakCompareAndSetPlain byte value"); + assertEquals((byte)0x23, x, "success weakCompareAndSetPlain byte value"); } { boolean success = vh.weakCompareAndSetPlain(array, i, (byte)0x01, (byte)0x45); assertEquals(success, false, "failing weakCompareAndSetPlain byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)0x23, "failing weakCompareAndSetPlain byte value"); + assertEquals((byte)0x23, x, "failing weakCompareAndSetPlain byte value"); } { @@ -1125,14 +1123,14 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)0x01, "success weakCompareAndSetAcquire byte"); + assertEquals((byte)0x01, x, "success weakCompareAndSetAcquire byte"); } { boolean success = vh.weakCompareAndSetAcquire(array, i, (byte)0x23, (byte)0x45); assertEquals(success, false, "failing weakCompareAndSetAcquire byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)0x01, "failing weakCompareAndSetAcquire byte value"); + assertEquals((byte)0x01, x, "failing weakCompareAndSetAcquire byte value"); } { @@ -1143,14 +1141,14 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)0x23, "success weakCompareAndSetRelease byte"); + assertEquals((byte)0x23, x, "success weakCompareAndSetRelease byte"); } { boolean success = vh.weakCompareAndSetRelease(array, i, (byte)0x01, (byte)0x45); assertEquals(success, false, "failing weakCompareAndSetRelease byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)0x23, "failing weakCompareAndSetRelease byte value"); + assertEquals((byte)0x23, x, "failing weakCompareAndSetRelease byte value"); } { @@ -1161,14 +1159,14 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)0x01, "success weakCompareAndSet byte"); + assertEquals((byte)0x01, x, "success weakCompareAndSet byte"); } { boolean success = vh.weakCompareAndSet(array, i, (byte)0x23, (byte)0x45); assertEquals(success, false, "failing weakCompareAndSet byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)0x01, "failing weakCompareAndSet byte value"); + assertEquals((byte)0x01, x, "failing weakCompareAndSet byte value"); } // Compare set and get @@ -1176,27 +1174,27 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { vh.set(array, i, (byte)0x01); byte o = (byte) vh.getAndSet(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndSet byte"); + assertEquals((byte)0x01, o, "getAndSet byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)0x23, "getAndSet byte value"); + assertEquals((byte)0x23, x, "getAndSet byte value"); } { vh.set(array, i, (byte)0x01); byte o = (byte) vh.getAndSetAcquire(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndSetAcquire byte"); + assertEquals((byte)0x01, o, "getAndSetAcquire byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)0x23, "getAndSetAcquire byte value"); + assertEquals((byte)0x23, x, "getAndSetAcquire byte value"); } { vh.set(array, i, (byte)0x01); byte o = (byte) vh.getAndSetRelease(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndSetRelease byte"); + assertEquals((byte)0x01, o, "getAndSetRelease byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)0x23, "getAndSetRelease byte value"); + assertEquals((byte)0x23, x, "getAndSetRelease byte value"); } // get and add, add and get @@ -1204,27 +1202,27 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { vh.set(array, i, (byte)0x01); byte o = (byte) vh.getAndAdd(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndAdd byte"); + assertEquals((byte)0x01, o, "getAndAdd byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)((byte)0x01 + (byte)0x23), "getAndAdd byte value"); + assertEquals((byte)((byte)0x01 + (byte)0x23), x, "getAndAdd byte value"); } { vh.set(array, i, (byte)0x01); byte o = (byte) vh.getAndAddAcquire(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndAddAcquire byte"); + assertEquals((byte)0x01, o, "getAndAddAcquire byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)((byte)0x01 + (byte)0x23), "getAndAddAcquire byte value"); + assertEquals((byte)((byte)0x01 + (byte)0x23), x, "getAndAddAcquire byte value"); } { vh.set(array, i, (byte)0x01); byte o = (byte) vh.getAndAddRelease(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndAddReleasebyte"); + assertEquals((byte)0x01, o, "getAndAddReleasebyte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)((byte)0x01 + (byte)0x23), "getAndAddRelease byte value"); + assertEquals((byte)((byte)0x01 + (byte)0x23), x, "getAndAddRelease byte value"); } // get and bitwise or @@ -1232,27 +1230,27 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { vh.set(array, i, (byte)0x01); byte o = (byte) vh.getAndBitwiseOr(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseOr byte"); + assertEquals((byte)0x01, o, "getAndBitwiseOr byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)((byte)0x01 | (byte)0x23), "getAndBitwiseOr byte value"); + assertEquals((byte)((byte)0x01 | (byte)0x23), x, "getAndBitwiseOr byte value"); } { vh.set(array, i, (byte)0x01); byte o = (byte) vh.getAndBitwiseOrAcquire(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseOrAcquire byte"); + assertEquals((byte)0x01, o, "getAndBitwiseOrAcquire byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)((byte)0x01 | (byte)0x23), "getAndBitwiseOrAcquire byte value"); + assertEquals((byte)((byte)0x01 | (byte)0x23), x, "getAndBitwiseOrAcquire byte value"); } { vh.set(array, i, (byte)0x01); byte o = (byte) vh.getAndBitwiseOrRelease(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseOrRelease byte"); + assertEquals((byte)0x01, o, "getAndBitwiseOrRelease byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)((byte)0x01 | (byte)0x23), "getAndBitwiseOrRelease byte value"); + assertEquals((byte)((byte)0x01 | (byte)0x23), x, "getAndBitwiseOrRelease byte value"); } // get and bitwise and @@ -1260,27 +1258,27 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { vh.set(array, i, (byte)0x01); byte o = (byte) vh.getAndBitwiseAnd(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseAnd byte"); + assertEquals((byte)0x01, o, "getAndBitwiseAnd byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)((byte)0x01 & (byte)0x23), "getAndBitwiseAnd byte value"); + assertEquals((byte)((byte)0x01 & (byte)0x23), x, "getAndBitwiseAnd byte value"); } { vh.set(array, i, (byte)0x01); byte o = (byte) vh.getAndBitwiseAndAcquire(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseAndAcquire byte"); + assertEquals((byte)0x01, o, "getAndBitwiseAndAcquire byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)((byte)0x01 & (byte)0x23), "getAndBitwiseAndAcquire byte value"); + assertEquals((byte)((byte)0x01 & (byte)0x23), x, "getAndBitwiseAndAcquire byte value"); } { vh.set(array, i, (byte)0x01); byte o = (byte) vh.getAndBitwiseAndRelease(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseAndRelease byte"); + assertEquals((byte)0x01, o, "getAndBitwiseAndRelease byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)((byte)0x01 & (byte)0x23), "getAndBitwiseAndRelease byte value"); + assertEquals((byte)((byte)0x01 & (byte)0x23), x, "getAndBitwiseAndRelease byte value"); } // get and bitwise xor @@ -1288,27 +1286,27 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { vh.set(array, i, (byte)0x01); byte o = (byte) vh.getAndBitwiseXor(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseXor byte"); + assertEquals((byte)0x01, o, "getAndBitwiseXor byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)((byte)0x01 ^ (byte)0x23), "getAndBitwiseXor byte value"); + assertEquals((byte)((byte)0x01 ^ (byte)0x23), x, "getAndBitwiseXor byte value"); } { vh.set(array, i, (byte)0x01); byte o = (byte) vh.getAndBitwiseXorAcquire(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseXorAcquire byte"); + assertEquals((byte)0x01, o, "getAndBitwiseXorAcquire byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)((byte)0x01 ^ (byte)0x23), "getAndBitwiseXorAcquire byte value"); + assertEquals((byte)((byte)0x01 ^ (byte)0x23), x, "getAndBitwiseXorAcquire byte value"); } { vh.set(array, i, (byte)0x01); byte o = (byte) vh.getAndBitwiseXorRelease(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseXorRelease byte"); + assertEquals((byte)0x01, o, "getAndBitwiseXorRelease byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)((byte)0x01 ^ (byte)0x23), "getAndBitwiseXorRelease byte value"); + assertEquals((byte)((byte)0x01 ^ (byte)0x23), x, "getAndBitwiseXorRelease byte value"); } } } diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java index bafde057167..e17e7616609 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,28 +23,30 @@ /* * @test - * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessChar + * @run junit/othervm -Diters=10 -Xint VarHandleTestAccessChar * * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations * to hit compilation thresholds * - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestAccessChar - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestAccessChar - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestAccessChar + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestAccessChar + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestAccessChar + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestAccessChar */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestAccessChar extends VarHandleBaseTest { static final char static_final_v = '\u0123'; @@ -108,7 +110,7 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { return vhs.toArray(new VarHandle[0]); } - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestAccessChar.class, "final_v", char.class); @@ -125,8 +127,6 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { vhArray = MethodHandles.arrayElementVarHandle(char[].class); } - - @DataProvider public Object[][] varHandlesProvider() throws Exception { List vhs = new ArrayList<>(); vhs.add(vhField); @@ -156,7 +156,8 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { } } - @Test(dataProvider = "varHandlesProvider") + @ParameterizedTest + @MethodSource("varHandlesProvider") public void testIsAccessModeSupported(VarHandle vh) { assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET)); @@ -194,8 +195,6 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE)); } - - @DataProvider public Object[][] typesProvider() throws Exception { List types = new ArrayList<>(); types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessChar.class)}); @@ -205,16 +204,16 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { return types.stream().toArray(Object[][]::new); } - @Test(dataProvider = "typesProvider") + @ParameterizedTest + @MethodSource("typesProvider") public void testTypes(VarHandle vh, List> pts) { - assertEquals(vh.varType(), char.class); + assertEquals(char.class, vh.varType()); - assertEquals(vh.coordinateTypes(), pts); + assertEquals(pts, vh.coordinateTypes()); testTypes(vh); } - @Test public void testLookupInstanceToStatic() { checkIAE("Lookup of static final field to instance final field", () -> { @@ -241,8 +240,6 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { }); } - - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -284,7 +281,8 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -297,26 +295,26 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { // Plain { char x = (char) vh.get(recv); - assertEquals(x, '\u0123', "get char value"); + assertEquals('\u0123', x, "get char value"); } // Volatile { char x = (char) vh.getVolatile(recv); - assertEquals(x, '\u0123', "getVolatile char value"); + assertEquals('\u0123', x, "getVolatile char value"); } // Lazy { char x = (char) vh.getAcquire(recv); - assertEquals(x, '\u0123', "getRelease char value"); + assertEquals('\u0123', x, "getRelease char value"); } // Opaque { char x = (char) vh.getOpaque(recv); - assertEquals(x, '\u0123', "getOpaque char value"); + assertEquals('\u0123', x, "getOpaque char value"); } } @@ -346,26 +344,26 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { // Plain { char x = (char) vh.get(); - assertEquals(x, '\u0123', "get char value"); + assertEquals('\u0123', x, "get char value"); } // Volatile { char x = (char) vh.getVolatile(); - assertEquals(x, '\u0123', "getVolatile char value"); + assertEquals('\u0123', x, "getVolatile char value"); } // Lazy { char x = (char) vh.getAcquire(); - assertEquals(x, '\u0123', "getRelease char value"); + assertEquals('\u0123', x, "getRelease char value"); } // Opaque { char x = (char) vh.getOpaque(); - assertEquals(x, '\u0123', "getOpaque char value"); + assertEquals('\u0123', x, "getOpaque char value"); } } @@ -396,7 +394,7 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { { vh.set(recv, '\u0123'); char x = (char) vh.get(recv); - assertEquals(x, '\u0123', "set char value"); + assertEquals('\u0123', x, "set char value"); } @@ -404,21 +402,21 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { { vh.setVolatile(recv, '\u4567'); char x = (char) vh.getVolatile(recv); - assertEquals(x, '\u4567', "setVolatile char value"); + assertEquals('\u4567', x, "setVolatile char value"); } // Lazy { vh.setRelease(recv, '\u0123'); char x = (char) vh.getAcquire(recv); - assertEquals(x, '\u0123', "setRelease char value"); + assertEquals('\u0123', x, "setRelease char value"); } // Opaque { vh.setOpaque(recv, '\u4567'); char x = (char) vh.getOpaque(recv); - assertEquals(x, '\u4567', "setOpaque char value"); + assertEquals('\u4567', x, "setOpaque char value"); } vh.set(recv, '\u0123'); @@ -428,56 +426,56 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { boolean r = vh.compareAndSet(recv, '\u0123', '\u4567'); assertEquals(r, true, "success compareAndSet char"); char x = (char) vh.get(recv); - assertEquals(x, '\u4567', "success compareAndSet char value"); + assertEquals('\u4567', x, "success compareAndSet char value"); } { boolean r = vh.compareAndSet(recv, '\u0123', '\u89AB'); assertEquals(r, false, "failing compareAndSet char"); char x = (char) vh.get(recv); - assertEquals(x, '\u4567', "failing compareAndSet char value"); + assertEquals('\u4567', x, "failing compareAndSet char value"); } { char r = (char) vh.compareAndExchange(recv, '\u4567', '\u0123'); assertEquals(r, '\u4567', "success compareAndExchange char"); char x = (char) vh.get(recv); - assertEquals(x, '\u0123', "success compareAndExchange char value"); + assertEquals('\u0123', x, "success compareAndExchange char value"); } { char r = (char) vh.compareAndExchange(recv, '\u4567', '\u89AB'); assertEquals(r, '\u0123', "failing compareAndExchange char"); char x = (char) vh.get(recv); - assertEquals(x, '\u0123', "failing compareAndExchange char value"); + assertEquals('\u0123', x, "failing compareAndExchange char value"); } { char r = (char) vh.compareAndExchangeAcquire(recv, '\u0123', '\u4567'); assertEquals(r, '\u0123', "success compareAndExchangeAcquire char"); char x = (char) vh.get(recv); - assertEquals(x, '\u4567', "success compareAndExchangeAcquire char value"); + assertEquals('\u4567', x, "success compareAndExchangeAcquire char value"); } { char r = (char) vh.compareAndExchangeAcquire(recv, '\u0123', '\u89AB'); assertEquals(r, '\u4567', "failing compareAndExchangeAcquire char"); char x = (char) vh.get(recv); - assertEquals(x, '\u4567', "failing compareAndExchangeAcquire char value"); + assertEquals('\u4567', x, "failing compareAndExchangeAcquire char value"); } { char r = (char) vh.compareAndExchangeRelease(recv, '\u4567', '\u0123'); assertEquals(r, '\u4567', "success compareAndExchangeRelease char"); char x = (char) vh.get(recv); - assertEquals(x, '\u0123', "success compareAndExchangeRelease char value"); + assertEquals('\u0123', x, "success compareAndExchangeRelease char value"); } { char r = (char) vh.compareAndExchangeRelease(recv, '\u4567', '\u89AB'); assertEquals(r, '\u0123', "failing compareAndExchangeRelease char"); char x = (char) vh.get(recv); - assertEquals(x, '\u0123', "failing compareAndExchangeRelease char value"); + assertEquals('\u0123', x, "failing compareAndExchangeRelease char value"); } { @@ -488,14 +486,14 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain char"); char x = (char) vh.get(recv); - assertEquals(x, '\u4567', "success weakCompareAndSetPlain char value"); + assertEquals('\u4567', x, "success weakCompareAndSetPlain char value"); } { boolean success = vh.weakCompareAndSetPlain(recv, '\u0123', '\u89AB'); assertEquals(success, false, "failing weakCompareAndSetPlain char"); char x = (char) vh.get(recv); - assertEquals(x, '\u4567', "failing weakCompareAndSetPlain char value"); + assertEquals('\u4567', x, "failing weakCompareAndSetPlain char value"); } { @@ -506,14 +504,14 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire char"); char x = (char) vh.get(recv); - assertEquals(x, '\u0123', "success weakCompareAndSetAcquire char"); + assertEquals('\u0123', x, "success weakCompareAndSetAcquire char"); } { boolean success = vh.weakCompareAndSetAcquire(recv, '\u4567', '\u89AB'); assertEquals(success, false, "failing weakCompareAndSetAcquire char"); char x = (char) vh.get(recv); - assertEquals(x, '\u0123', "failing weakCompareAndSetAcquire char value"); + assertEquals('\u0123', x, "failing weakCompareAndSetAcquire char value"); } { @@ -524,14 +522,14 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease char"); char x = (char) vh.get(recv); - assertEquals(x, '\u4567', "success weakCompareAndSetRelease char"); + assertEquals('\u4567', x, "success weakCompareAndSetRelease char"); } { boolean success = vh.weakCompareAndSetRelease(recv, '\u0123', '\u89AB'); assertEquals(success, false, "failing weakCompareAndSetRelease char"); char x = (char) vh.get(recv); - assertEquals(x, '\u4567', "failing weakCompareAndSetRelease char value"); + assertEquals('\u4567', x, "failing weakCompareAndSetRelease char value"); } { @@ -542,14 +540,14 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet char"); char x = (char) vh.get(recv); - assertEquals(x, '\u0123', "success weakCompareAndSet char value"); + assertEquals('\u0123', x, "success weakCompareAndSet char value"); } { boolean success = vh.weakCompareAndSet(recv, '\u4567', '\u89AB'); assertEquals(success, false, "failing weakCompareAndSet char"); char x = (char) vh.get(recv); - assertEquals(x, '\u0123', "failing weakCompareAndSet char value"); + assertEquals('\u0123', x, "failing weakCompareAndSet char value"); } // Compare set and get @@ -557,27 +555,27 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { vh.set(recv, '\u0123'); char o = (char) vh.getAndSet(recv, '\u4567'); - assertEquals(o, '\u0123', "getAndSet char"); + assertEquals('\u0123', o, "getAndSet char"); char x = (char) vh.get(recv); - assertEquals(x, '\u4567', "getAndSet char value"); + assertEquals('\u4567', x, "getAndSet char value"); } { vh.set(recv, '\u0123'); char o = (char) vh.getAndSetAcquire(recv, '\u4567'); - assertEquals(o, '\u0123', "getAndSetAcquire char"); + assertEquals('\u0123', o, "getAndSetAcquire char"); char x = (char) vh.get(recv); - assertEquals(x, '\u4567', "getAndSetAcquire char value"); + assertEquals('\u4567', x, "getAndSetAcquire char value"); } { vh.set(recv, '\u0123'); char o = (char) vh.getAndSetRelease(recv, '\u4567'); - assertEquals(o, '\u0123', "getAndSetRelease char"); + assertEquals('\u0123', o, "getAndSetRelease char"); char x = (char) vh.get(recv); - assertEquals(x, '\u4567', "getAndSetRelease char value"); + assertEquals('\u4567', x, "getAndSetRelease char value"); } // get and add, add and get @@ -585,27 +583,27 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { vh.set(recv, '\u0123'); char o = (char) vh.getAndAdd(recv, '\u4567'); - assertEquals(o, '\u0123', "getAndAdd char"); + assertEquals('\u0123', o, "getAndAdd char"); char x = (char) vh.get(recv); - assertEquals(x, (char)('\u0123' + '\u4567'), "getAndAdd char value"); + assertEquals((char)('\u0123' + '\u4567'), x, "getAndAdd char value"); } { vh.set(recv, '\u0123'); char o = (char) vh.getAndAddAcquire(recv, '\u4567'); - assertEquals(o, '\u0123', "getAndAddAcquire char"); + assertEquals('\u0123', o, "getAndAddAcquire char"); char x = (char) vh.get(recv); - assertEquals(x, (char)('\u0123' + '\u4567'), "getAndAddAcquire char value"); + assertEquals((char)('\u0123' + '\u4567'), x, "getAndAddAcquire char value"); } { vh.set(recv, '\u0123'); char o = (char) vh.getAndAddRelease(recv, '\u4567'); - assertEquals(o, '\u0123', "getAndAddReleasechar"); + assertEquals('\u0123', o, "getAndAddReleasechar"); char x = (char) vh.get(recv); - assertEquals(x, (char)('\u0123' + '\u4567'), "getAndAddRelease char value"); + assertEquals((char)('\u0123' + '\u4567'), x, "getAndAddRelease char value"); } // get and bitwise or @@ -613,27 +611,27 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { vh.set(recv, '\u0123'); char o = (char) vh.getAndBitwiseOr(recv, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseOr char"); + assertEquals('\u0123', o, "getAndBitwiseOr char"); char x = (char) vh.get(recv); - assertEquals(x, (char)('\u0123' | '\u4567'), "getAndBitwiseOr char value"); + assertEquals((char)('\u0123' | '\u4567'), x, "getAndBitwiseOr char value"); } { vh.set(recv, '\u0123'); char o = (char) vh.getAndBitwiseOrAcquire(recv, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseOrAcquire char"); + assertEquals('\u0123', o, "getAndBitwiseOrAcquire char"); char x = (char) vh.get(recv); - assertEquals(x, (char)('\u0123' | '\u4567'), "getAndBitwiseOrAcquire char value"); + assertEquals((char)('\u0123' | '\u4567'), x, "getAndBitwiseOrAcquire char value"); } { vh.set(recv, '\u0123'); char o = (char) vh.getAndBitwiseOrRelease(recv, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseOrRelease char"); + assertEquals('\u0123', o, "getAndBitwiseOrRelease char"); char x = (char) vh.get(recv); - assertEquals(x, (char)('\u0123' | '\u4567'), "getAndBitwiseOrRelease char value"); + assertEquals((char)('\u0123' | '\u4567'), x, "getAndBitwiseOrRelease char value"); } // get and bitwise and @@ -641,27 +639,27 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { vh.set(recv, '\u0123'); char o = (char) vh.getAndBitwiseAnd(recv, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseAnd char"); + assertEquals('\u0123', o, "getAndBitwiseAnd char"); char x = (char) vh.get(recv); - assertEquals(x, (char)('\u0123' & '\u4567'), "getAndBitwiseAnd char value"); + assertEquals((char)('\u0123' & '\u4567'), x, "getAndBitwiseAnd char value"); } { vh.set(recv, '\u0123'); char o = (char) vh.getAndBitwiseAndAcquire(recv, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseAndAcquire char"); + assertEquals('\u0123', o, "getAndBitwiseAndAcquire char"); char x = (char) vh.get(recv); - assertEquals(x, (char)('\u0123' & '\u4567'), "getAndBitwiseAndAcquire char value"); + assertEquals((char)('\u0123' & '\u4567'), x, "getAndBitwiseAndAcquire char value"); } { vh.set(recv, '\u0123'); char o = (char) vh.getAndBitwiseAndRelease(recv, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseAndRelease char"); + assertEquals('\u0123', o, "getAndBitwiseAndRelease char"); char x = (char) vh.get(recv); - assertEquals(x, (char)('\u0123' & '\u4567'), "getAndBitwiseAndRelease char value"); + assertEquals((char)('\u0123' & '\u4567'), x, "getAndBitwiseAndRelease char value"); } // get and bitwise xor @@ -669,27 +667,27 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { vh.set(recv, '\u0123'); char o = (char) vh.getAndBitwiseXor(recv, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseXor char"); + assertEquals('\u0123', o, "getAndBitwiseXor char"); char x = (char) vh.get(recv); - assertEquals(x, (char)('\u0123' ^ '\u4567'), "getAndBitwiseXor char value"); + assertEquals((char)('\u0123' ^ '\u4567'), x, "getAndBitwiseXor char value"); } { vh.set(recv, '\u0123'); char o = (char) vh.getAndBitwiseXorAcquire(recv, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseXorAcquire char"); + assertEquals('\u0123', o, "getAndBitwiseXorAcquire char"); char x = (char) vh.get(recv); - assertEquals(x, (char)('\u0123' ^ '\u4567'), "getAndBitwiseXorAcquire char value"); + assertEquals((char)('\u0123' ^ '\u4567'), x, "getAndBitwiseXorAcquire char value"); } { vh.set(recv, '\u0123'); char o = (char) vh.getAndBitwiseXorRelease(recv, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseXorRelease char"); + assertEquals('\u0123', o, "getAndBitwiseXorRelease char"); char x = (char) vh.get(recv); - assertEquals(x, (char)('\u0123' ^ '\u4567'), "getAndBitwiseXorRelease char value"); + assertEquals((char)('\u0123' ^ '\u4567'), x, "getAndBitwiseXorRelease char value"); } } @@ -704,7 +702,7 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { { vh.set('\u0123'); char x = (char) vh.get(); - assertEquals(x, '\u0123', "set char value"); + assertEquals('\u0123', x, "set char value"); } @@ -712,21 +710,21 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { { vh.setVolatile('\u4567'); char x = (char) vh.getVolatile(); - assertEquals(x, '\u4567', "setVolatile char value"); + assertEquals('\u4567', x, "setVolatile char value"); } // Lazy { vh.setRelease('\u0123'); char x = (char) vh.getAcquire(); - assertEquals(x, '\u0123', "setRelease char value"); + assertEquals('\u0123', x, "setRelease char value"); } // Opaque { vh.setOpaque('\u4567'); char x = (char) vh.getOpaque(); - assertEquals(x, '\u4567', "setOpaque char value"); + assertEquals('\u4567', x, "setOpaque char value"); } vh.set('\u0123'); @@ -736,56 +734,56 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { boolean r = vh.compareAndSet('\u0123', '\u4567'); assertEquals(r, true, "success compareAndSet char"); char x = (char) vh.get(); - assertEquals(x, '\u4567', "success compareAndSet char value"); + assertEquals('\u4567', x, "success compareAndSet char value"); } { boolean r = vh.compareAndSet('\u0123', '\u89AB'); assertEquals(r, false, "failing compareAndSet char"); char x = (char) vh.get(); - assertEquals(x, '\u4567', "failing compareAndSet char value"); + assertEquals('\u4567', x, "failing compareAndSet char value"); } { char r = (char) vh.compareAndExchange('\u4567', '\u0123'); assertEquals(r, '\u4567', "success compareAndExchange char"); char x = (char) vh.get(); - assertEquals(x, '\u0123', "success compareAndExchange char value"); + assertEquals('\u0123', x, "success compareAndExchange char value"); } { char r = (char) vh.compareAndExchange('\u4567', '\u89AB'); assertEquals(r, '\u0123', "failing compareAndExchange char"); char x = (char) vh.get(); - assertEquals(x, '\u0123', "failing compareAndExchange char value"); + assertEquals('\u0123', x, "failing compareAndExchange char value"); } { char r = (char) vh.compareAndExchangeAcquire('\u0123', '\u4567'); assertEquals(r, '\u0123', "success compareAndExchangeAcquire char"); char x = (char) vh.get(); - assertEquals(x, '\u4567', "success compareAndExchangeAcquire char value"); + assertEquals('\u4567', x, "success compareAndExchangeAcquire char value"); } { char r = (char) vh.compareAndExchangeAcquire('\u0123', '\u89AB'); assertEquals(r, '\u4567', "failing compareAndExchangeAcquire char"); char x = (char) vh.get(); - assertEquals(x, '\u4567', "failing compareAndExchangeAcquire char value"); + assertEquals('\u4567', x, "failing compareAndExchangeAcquire char value"); } { char r = (char) vh.compareAndExchangeRelease('\u4567', '\u0123'); assertEquals(r, '\u4567', "success compareAndExchangeRelease char"); char x = (char) vh.get(); - assertEquals(x, '\u0123', "success compareAndExchangeRelease char value"); + assertEquals('\u0123', x, "success compareAndExchangeRelease char value"); } { char r = (char) vh.compareAndExchangeRelease('\u4567', '\u89AB'); assertEquals(r, '\u0123', "failing compareAndExchangeRelease char"); char x = (char) vh.get(); - assertEquals(x, '\u0123', "failing compareAndExchangeRelease char value"); + assertEquals('\u0123', x, "failing compareAndExchangeRelease char value"); } { @@ -796,14 +794,14 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain char"); char x = (char) vh.get(); - assertEquals(x, '\u4567', "success weakCompareAndSetPlain char value"); + assertEquals('\u4567', x, "success weakCompareAndSetPlain char value"); } { boolean success = vh.weakCompareAndSetPlain('\u0123', '\u89AB'); assertEquals(success, false, "failing weakCompareAndSetPlain char"); char x = (char) vh.get(); - assertEquals(x, '\u4567', "failing weakCompareAndSetPlain char value"); + assertEquals('\u4567', x, "failing weakCompareAndSetPlain char value"); } { @@ -814,14 +812,14 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire char"); char x = (char) vh.get(); - assertEquals(x, '\u0123', "success weakCompareAndSetAcquire char"); + assertEquals('\u0123', x, "success weakCompareAndSetAcquire char"); } { boolean success = vh.weakCompareAndSetAcquire('\u4567', '\u89AB'); assertEquals(success, false, "failing weakCompareAndSetAcquire char"); char x = (char) vh.get(); - assertEquals(x, '\u0123', "failing weakCompareAndSetAcquire char value"); + assertEquals('\u0123', x, "failing weakCompareAndSetAcquire char value"); } { @@ -832,14 +830,14 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease char"); char x = (char) vh.get(); - assertEquals(x, '\u4567', "success weakCompareAndSetRelease char"); + assertEquals('\u4567', x, "success weakCompareAndSetRelease char"); } { boolean success = vh.weakCompareAndSetRelease('\u0123', '\u89AB'); assertEquals(success, false, "failing weakCompareAndSetRelease char"); char x = (char) vh.get(); - assertEquals(x, '\u4567', "failing weakCompareAndSetRelease char value"); + assertEquals('\u4567', x, "failing weakCompareAndSetRelease char value"); } { @@ -850,14 +848,14 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet char"); char x = (char) vh.get(); - assertEquals(x, '\u0123', "success weakCompareAndSet char"); + assertEquals('\u0123', x, "success weakCompareAndSet char"); } { boolean success = vh.weakCompareAndSet('\u4567', '\u89AB'); assertEquals(success, false, "failing weakCompareAndSet char"); char x = (char) vh.get(); - assertEquals(x, '\u0123', "failing weakCompareAndSet char value"); + assertEquals('\u0123', x, "failing weakCompareAndSet char value"); } // Compare set and get @@ -865,27 +863,27 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { vh.set('\u0123'); char o = (char) vh.getAndSet('\u4567'); - assertEquals(o, '\u0123', "getAndSet char"); + assertEquals('\u0123', o, "getAndSet char"); char x = (char) vh.get(); - assertEquals(x, '\u4567', "getAndSet char value"); + assertEquals('\u4567', x, "getAndSet char value"); } { vh.set('\u0123'); char o = (char) vh.getAndSetAcquire('\u4567'); - assertEquals(o, '\u0123', "getAndSetAcquire char"); + assertEquals('\u0123', o, "getAndSetAcquire char"); char x = (char) vh.get(); - assertEquals(x, '\u4567', "getAndSetAcquire char value"); + assertEquals('\u4567', x, "getAndSetAcquire char value"); } { vh.set('\u0123'); char o = (char) vh.getAndSetRelease('\u4567'); - assertEquals(o, '\u0123', "getAndSetRelease char"); + assertEquals('\u0123', o, "getAndSetRelease char"); char x = (char) vh.get(); - assertEquals(x, '\u4567', "getAndSetRelease char value"); + assertEquals('\u4567', x, "getAndSetRelease char value"); } // get and add, add and get @@ -893,27 +891,27 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { vh.set('\u0123'); char o = (char) vh.getAndAdd('\u4567'); - assertEquals(o, '\u0123', "getAndAdd char"); + assertEquals('\u0123', o, "getAndAdd char"); char x = (char) vh.get(); - assertEquals(x, (char)('\u0123' + '\u4567'), "getAndAdd char value"); + assertEquals((char)('\u0123' + '\u4567'), x, "getAndAdd char value"); } { vh.set('\u0123'); char o = (char) vh.getAndAddAcquire('\u4567'); - assertEquals(o, '\u0123', "getAndAddAcquire char"); + assertEquals('\u0123', o, "getAndAddAcquire char"); char x = (char) vh.get(); - assertEquals(x, (char)('\u0123' + '\u4567'), "getAndAddAcquire char value"); + assertEquals((char)('\u0123' + '\u4567'), x, "getAndAddAcquire char value"); } { vh.set('\u0123'); char o = (char) vh.getAndAddRelease('\u4567'); - assertEquals(o, '\u0123', "getAndAddReleasechar"); + assertEquals('\u0123', o, "getAndAddReleasechar"); char x = (char) vh.get(); - assertEquals(x, (char)('\u0123' + '\u4567'), "getAndAddRelease char value"); + assertEquals((char)('\u0123' + '\u4567'), x, "getAndAddRelease char value"); } // get and bitwise or @@ -921,27 +919,27 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { vh.set('\u0123'); char o = (char) vh.getAndBitwiseOr('\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseOr char"); + assertEquals('\u0123', o, "getAndBitwiseOr char"); char x = (char) vh.get(); - assertEquals(x, (char)('\u0123' | '\u4567'), "getAndBitwiseOr char value"); + assertEquals((char)('\u0123' | '\u4567'), x, "getAndBitwiseOr char value"); } { vh.set('\u0123'); char o = (char) vh.getAndBitwiseOrAcquire('\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseOrAcquire char"); + assertEquals('\u0123', o, "getAndBitwiseOrAcquire char"); char x = (char) vh.get(); - assertEquals(x, (char)('\u0123' | '\u4567'), "getAndBitwiseOrAcquire char value"); + assertEquals((char)('\u0123' | '\u4567'), x, "getAndBitwiseOrAcquire char value"); } { vh.set('\u0123'); char o = (char) vh.getAndBitwiseOrRelease('\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseOrRelease char"); + assertEquals('\u0123', o, "getAndBitwiseOrRelease char"); char x = (char) vh.get(); - assertEquals(x, (char)('\u0123' | '\u4567'), "getAndBitwiseOrRelease char value"); + assertEquals((char)('\u0123' | '\u4567'), x, "getAndBitwiseOrRelease char value"); } // get and bitwise and @@ -949,27 +947,27 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { vh.set('\u0123'); char o = (char) vh.getAndBitwiseAnd('\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseAnd char"); + assertEquals('\u0123', o, "getAndBitwiseAnd char"); char x = (char) vh.get(); - assertEquals(x, (char)('\u0123' & '\u4567'), "getAndBitwiseAnd char value"); + assertEquals((char)('\u0123' & '\u4567'), x, "getAndBitwiseAnd char value"); } { vh.set('\u0123'); char o = (char) vh.getAndBitwiseAndAcquire('\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseAndAcquire char"); + assertEquals('\u0123', o, "getAndBitwiseAndAcquire char"); char x = (char) vh.get(); - assertEquals(x, (char)('\u0123' & '\u4567'), "getAndBitwiseAndAcquire char value"); + assertEquals((char)('\u0123' & '\u4567'), x, "getAndBitwiseAndAcquire char value"); } { vh.set('\u0123'); char o = (char) vh.getAndBitwiseAndRelease('\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseAndRelease char"); + assertEquals('\u0123', o, "getAndBitwiseAndRelease char"); char x = (char) vh.get(); - assertEquals(x, (char)('\u0123' & '\u4567'), "getAndBitwiseAndRelease char value"); + assertEquals((char)('\u0123' & '\u4567'), x, "getAndBitwiseAndRelease char value"); } // get and bitwise xor @@ -977,27 +975,27 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { vh.set('\u0123'); char o = (char) vh.getAndBitwiseXor('\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseXor char"); + assertEquals('\u0123', o, "getAndBitwiseXor char"); char x = (char) vh.get(); - assertEquals(x, (char)('\u0123' ^ '\u4567'), "getAndBitwiseXor char value"); + assertEquals((char)('\u0123' ^ '\u4567'), x, "getAndBitwiseXor char value"); } { vh.set('\u0123'); char o = (char) vh.getAndBitwiseXorAcquire('\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseXorAcquire char"); + assertEquals('\u0123', o, "getAndBitwiseXorAcquire char"); char x = (char) vh.get(); - assertEquals(x, (char)('\u0123' ^ '\u4567'), "getAndBitwiseXorAcquire char value"); + assertEquals((char)('\u0123' ^ '\u4567'), x, "getAndBitwiseXorAcquire char value"); } { vh.set('\u0123'); char o = (char) vh.getAndBitwiseXorRelease('\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseXorRelease char"); + assertEquals('\u0123', o, "getAndBitwiseXorRelease char"); char x = (char) vh.get(); - assertEquals(x, (char)('\u0123' ^ '\u4567'), "getAndBitwiseXorRelease char value"); + assertEquals((char)('\u0123' ^ '\u4567'), x, "getAndBitwiseXorRelease char value"); } } @@ -1015,7 +1013,7 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { { vh.set(array, i, '\u0123'); char x = (char) vh.get(array, i); - assertEquals(x, '\u0123', "get char value"); + assertEquals('\u0123', x, "get char value"); } @@ -1023,21 +1021,21 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { { vh.setVolatile(array, i, '\u4567'); char x = (char) vh.getVolatile(array, i); - assertEquals(x, '\u4567', "setVolatile char value"); + assertEquals('\u4567', x, "setVolatile char value"); } // Lazy { vh.setRelease(array, i, '\u0123'); char x = (char) vh.getAcquire(array, i); - assertEquals(x, '\u0123', "setRelease char value"); + assertEquals('\u0123', x, "setRelease char value"); } // Opaque { vh.setOpaque(array, i, '\u4567'); char x = (char) vh.getOpaque(array, i); - assertEquals(x, '\u4567', "setOpaque char value"); + assertEquals('\u4567', x, "setOpaque char value"); } vh.set(array, i, '\u0123'); @@ -1047,56 +1045,56 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { boolean r = vh.compareAndSet(array, i, '\u0123', '\u4567'); assertEquals(r, true, "success compareAndSet char"); char x = (char) vh.get(array, i); - assertEquals(x, '\u4567', "success compareAndSet char value"); + assertEquals('\u4567', x, "success compareAndSet char value"); } { boolean r = vh.compareAndSet(array, i, '\u0123', '\u89AB'); assertEquals(r, false, "failing compareAndSet char"); char x = (char) vh.get(array, i); - assertEquals(x, '\u4567', "failing compareAndSet char value"); + assertEquals('\u4567', x, "failing compareAndSet char value"); } { char r = (char) vh.compareAndExchange(array, i, '\u4567', '\u0123'); assertEquals(r, '\u4567', "success compareAndExchange char"); char x = (char) vh.get(array, i); - assertEquals(x, '\u0123', "success compareAndExchange char value"); + assertEquals('\u0123', x, "success compareAndExchange char value"); } { char r = (char) vh.compareAndExchange(array, i, '\u4567', '\u89AB'); assertEquals(r, '\u0123', "failing compareAndExchange char"); char x = (char) vh.get(array, i); - assertEquals(x, '\u0123', "failing compareAndExchange char value"); + assertEquals('\u0123', x, "failing compareAndExchange char value"); } { char r = (char) vh.compareAndExchangeAcquire(array, i, '\u0123', '\u4567'); assertEquals(r, '\u0123', "success compareAndExchangeAcquire char"); char x = (char) vh.get(array, i); - assertEquals(x, '\u4567', "success compareAndExchangeAcquire char value"); + assertEquals('\u4567', x, "success compareAndExchangeAcquire char value"); } { char r = (char) vh.compareAndExchangeAcquire(array, i, '\u0123', '\u89AB'); assertEquals(r, '\u4567', "failing compareAndExchangeAcquire char"); char x = (char) vh.get(array, i); - assertEquals(x, '\u4567', "failing compareAndExchangeAcquire char value"); + assertEquals('\u4567', x, "failing compareAndExchangeAcquire char value"); } { char r = (char) vh.compareAndExchangeRelease(array, i, '\u4567', '\u0123'); assertEquals(r, '\u4567', "success compareAndExchangeRelease char"); char x = (char) vh.get(array, i); - assertEquals(x, '\u0123', "success compareAndExchangeRelease char value"); + assertEquals('\u0123', x, "success compareAndExchangeRelease char value"); } { char r = (char) vh.compareAndExchangeRelease(array, i, '\u4567', '\u89AB'); assertEquals(r, '\u0123', "failing compareAndExchangeRelease char"); char x = (char) vh.get(array, i); - assertEquals(x, '\u0123', "failing compareAndExchangeRelease char value"); + assertEquals('\u0123', x, "failing compareAndExchangeRelease char value"); } { @@ -1107,14 +1105,14 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain char"); char x = (char) vh.get(array, i); - assertEquals(x, '\u4567', "success weakCompareAndSetPlain char value"); + assertEquals('\u4567', x, "success weakCompareAndSetPlain char value"); } { boolean success = vh.weakCompareAndSetPlain(array, i, '\u0123', '\u89AB'); assertEquals(success, false, "failing weakCompareAndSetPlain char"); char x = (char) vh.get(array, i); - assertEquals(x, '\u4567', "failing weakCompareAndSetPlain char value"); + assertEquals('\u4567', x, "failing weakCompareAndSetPlain char value"); } { @@ -1125,14 +1123,14 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire char"); char x = (char) vh.get(array, i); - assertEquals(x, '\u0123', "success weakCompareAndSetAcquire char"); + assertEquals('\u0123', x, "success weakCompareAndSetAcquire char"); } { boolean success = vh.weakCompareAndSetAcquire(array, i, '\u4567', '\u89AB'); assertEquals(success, false, "failing weakCompareAndSetAcquire char"); char x = (char) vh.get(array, i); - assertEquals(x, '\u0123', "failing weakCompareAndSetAcquire char value"); + assertEquals('\u0123', x, "failing weakCompareAndSetAcquire char value"); } { @@ -1143,14 +1141,14 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease char"); char x = (char) vh.get(array, i); - assertEquals(x, '\u4567', "success weakCompareAndSetRelease char"); + assertEquals('\u4567', x, "success weakCompareAndSetRelease char"); } { boolean success = vh.weakCompareAndSetRelease(array, i, '\u0123', '\u89AB'); assertEquals(success, false, "failing weakCompareAndSetRelease char"); char x = (char) vh.get(array, i); - assertEquals(x, '\u4567', "failing weakCompareAndSetRelease char value"); + assertEquals('\u4567', x, "failing weakCompareAndSetRelease char value"); } { @@ -1161,14 +1159,14 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet char"); char x = (char) vh.get(array, i); - assertEquals(x, '\u0123', "success weakCompareAndSet char"); + assertEquals('\u0123', x, "success weakCompareAndSet char"); } { boolean success = vh.weakCompareAndSet(array, i, '\u4567', '\u89AB'); assertEquals(success, false, "failing weakCompareAndSet char"); char x = (char) vh.get(array, i); - assertEquals(x, '\u0123', "failing weakCompareAndSet char value"); + assertEquals('\u0123', x, "failing weakCompareAndSet char value"); } // Compare set and get @@ -1176,27 +1174,27 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { vh.set(array, i, '\u0123'); char o = (char) vh.getAndSet(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndSet char"); + assertEquals('\u0123', o, "getAndSet char"); char x = (char) vh.get(array, i); - assertEquals(x, '\u4567', "getAndSet char value"); + assertEquals('\u4567', x, "getAndSet char value"); } { vh.set(array, i, '\u0123'); char o = (char) vh.getAndSetAcquire(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndSetAcquire char"); + assertEquals('\u0123', o, "getAndSetAcquire char"); char x = (char) vh.get(array, i); - assertEquals(x, '\u4567', "getAndSetAcquire char value"); + assertEquals('\u4567', x, "getAndSetAcquire char value"); } { vh.set(array, i, '\u0123'); char o = (char) vh.getAndSetRelease(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndSetRelease char"); + assertEquals('\u0123', o, "getAndSetRelease char"); char x = (char) vh.get(array, i); - assertEquals(x, '\u4567', "getAndSetRelease char value"); + assertEquals('\u4567', x, "getAndSetRelease char value"); } // get and add, add and get @@ -1204,27 +1202,27 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { vh.set(array, i, '\u0123'); char o = (char) vh.getAndAdd(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndAdd char"); + assertEquals('\u0123', o, "getAndAdd char"); char x = (char) vh.get(array, i); - assertEquals(x, (char)('\u0123' + '\u4567'), "getAndAdd char value"); + assertEquals((char)('\u0123' + '\u4567'), x, "getAndAdd char value"); } { vh.set(array, i, '\u0123'); char o = (char) vh.getAndAddAcquire(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndAddAcquire char"); + assertEquals('\u0123', o, "getAndAddAcquire char"); char x = (char) vh.get(array, i); - assertEquals(x, (char)('\u0123' + '\u4567'), "getAndAddAcquire char value"); + assertEquals((char)('\u0123' + '\u4567'), x, "getAndAddAcquire char value"); } { vh.set(array, i, '\u0123'); char o = (char) vh.getAndAddRelease(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndAddReleasechar"); + assertEquals('\u0123', o, "getAndAddReleasechar"); char x = (char) vh.get(array, i); - assertEquals(x, (char)('\u0123' + '\u4567'), "getAndAddRelease char value"); + assertEquals((char)('\u0123' + '\u4567'), x, "getAndAddRelease char value"); } // get and bitwise or @@ -1232,27 +1230,27 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { vh.set(array, i, '\u0123'); char o = (char) vh.getAndBitwiseOr(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseOr char"); + assertEquals('\u0123', o, "getAndBitwiseOr char"); char x = (char) vh.get(array, i); - assertEquals(x, (char)('\u0123' | '\u4567'), "getAndBitwiseOr char value"); + assertEquals((char)('\u0123' | '\u4567'), x, "getAndBitwiseOr char value"); } { vh.set(array, i, '\u0123'); char o = (char) vh.getAndBitwiseOrAcquire(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseOrAcquire char"); + assertEquals('\u0123', o, "getAndBitwiseOrAcquire char"); char x = (char) vh.get(array, i); - assertEquals(x, (char)('\u0123' | '\u4567'), "getAndBitwiseOrAcquire char value"); + assertEquals((char)('\u0123' | '\u4567'), x, "getAndBitwiseOrAcquire char value"); } { vh.set(array, i, '\u0123'); char o = (char) vh.getAndBitwiseOrRelease(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseOrRelease char"); + assertEquals('\u0123', o, "getAndBitwiseOrRelease char"); char x = (char) vh.get(array, i); - assertEquals(x, (char)('\u0123' | '\u4567'), "getAndBitwiseOrRelease char value"); + assertEquals((char)('\u0123' | '\u4567'), x, "getAndBitwiseOrRelease char value"); } // get and bitwise and @@ -1260,27 +1258,27 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { vh.set(array, i, '\u0123'); char o = (char) vh.getAndBitwiseAnd(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseAnd char"); + assertEquals('\u0123', o, "getAndBitwiseAnd char"); char x = (char) vh.get(array, i); - assertEquals(x, (char)('\u0123' & '\u4567'), "getAndBitwiseAnd char value"); + assertEquals((char)('\u0123' & '\u4567'), x, "getAndBitwiseAnd char value"); } { vh.set(array, i, '\u0123'); char o = (char) vh.getAndBitwiseAndAcquire(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseAndAcquire char"); + assertEquals('\u0123', o, "getAndBitwiseAndAcquire char"); char x = (char) vh.get(array, i); - assertEquals(x, (char)('\u0123' & '\u4567'), "getAndBitwiseAndAcquire char value"); + assertEquals((char)('\u0123' & '\u4567'), x, "getAndBitwiseAndAcquire char value"); } { vh.set(array, i, '\u0123'); char o = (char) vh.getAndBitwiseAndRelease(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseAndRelease char"); + assertEquals('\u0123', o, "getAndBitwiseAndRelease char"); char x = (char) vh.get(array, i); - assertEquals(x, (char)('\u0123' & '\u4567'), "getAndBitwiseAndRelease char value"); + assertEquals((char)('\u0123' & '\u4567'), x, "getAndBitwiseAndRelease char value"); } // get and bitwise xor @@ -1288,27 +1286,27 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { vh.set(array, i, '\u0123'); char o = (char) vh.getAndBitwiseXor(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseXor char"); + assertEquals('\u0123', o, "getAndBitwiseXor char"); char x = (char) vh.get(array, i); - assertEquals(x, (char)('\u0123' ^ '\u4567'), "getAndBitwiseXor char value"); + assertEquals((char)('\u0123' ^ '\u4567'), x, "getAndBitwiseXor char value"); } { vh.set(array, i, '\u0123'); char o = (char) vh.getAndBitwiseXorAcquire(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseXorAcquire char"); + assertEquals('\u0123', o, "getAndBitwiseXorAcquire char"); char x = (char) vh.get(array, i); - assertEquals(x, (char)('\u0123' ^ '\u4567'), "getAndBitwiseXorAcquire char value"); + assertEquals((char)('\u0123' ^ '\u4567'), x, "getAndBitwiseXorAcquire char value"); } { vh.set(array, i, '\u0123'); char o = (char) vh.getAndBitwiseXorRelease(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseXorRelease char"); + assertEquals('\u0123', o, "getAndBitwiseXorRelease char"); char x = (char) vh.get(array, i); - assertEquals(x, (char)('\u0123' ^ '\u4567'), "getAndBitwiseXorRelease char value"); + assertEquals((char)('\u0123' ^ '\u4567'), x, "getAndBitwiseXorRelease char value"); } } } diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java index 0edb196076c..29fa6c2886d 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,28 +23,30 @@ /* * @test - * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessDouble + * @run junit/othervm -Diters=10 -Xint VarHandleTestAccessDouble * * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations * to hit compilation thresholds * - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestAccessDouble - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestAccessDouble - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestAccessDouble + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestAccessDouble + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestAccessDouble + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestAccessDouble */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestAccessDouble extends VarHandleBaseTest { static final double static_final_v = 1.0d; @@ -108,7 +110,7 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { return vhs.toArray(new VarHandle[0]); } - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestAccessDouble.class, "final_v", double.class); @@ -125,8 +127,6 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { vhArray = MethodHandles.arrayElementVarHandle(double[].class); } - - @DataProvider public Object[][] varHandlesProvider() throws Exception { List vhs = new ArrayList<>(); vhs.add(vhField); @@ -156,7 +156,8 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { } } - @Test(dataProvider = "varHandlesProvider") + @ParameterizedTest + @MethodSource("varHandlesProvider") public void testIsAccessModeSupported(VarHandle vh) { assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET)); @@ -194,8 +195,6 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE)); } - - @DataProvider public Object[][] typesProvider() throws Exception { List types = new ArrayList<>(); types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessDouble.class)}); @@ -205,16 +204,16 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { return types.stream().toArray(Object[][]::new); } - @Test(dataProvider = "typesProvider") + @ParameterizedTest + @MethodSource("typesProvider") public void testTypes(VarHandle vh, List> pts) { - assertEquals(vh.varType(), double.class); + assertEquals(double.class, vh.varType()); - assertEquals(vh.coordinateTypes(), pts); + assertEquals(pts, vh.coordinateTypes()); testTypes(vh); } - @Test public void testLookupInstanceToStatic() { checkIAE("Lookup of static final field to instance final field", () -> { @@ -241,8 +240,6 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { }); } - - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -284,7 +281,8 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -297,26 +295,26 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { // Plain { double x = (double) vh.get(recv); - assertEquals(x, 1.0d, "get double value"); + assertEquals(1.0d, x, "get double value"); } // Volatile { double x = (double) vh.getVolatile(recv); - assertEquals(x, 1.0d, "getVolatile double value"); + assertEquals(1.0d, x, "getVolatile double value"); } // Lazy { double x = (double) vh.getAcquire(recv); - assertEquals(x, 1.0d, "getRelease double value"); + assertEquals(1.0d, x, "getRelease double value"); } // Opaque { double x = (double) vh.getOpaque(recv); - assertEquals(x, 1.0d, "getOpaque double value"); + assertEquals(1.0d, x, "getOpaque double value"); } } @@ -381,26 +379,26 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { // Plain { double x = (double) vh.get(); - assertEquals(x, 1.0d, "get double value"); + assertEquals(1.0d, x, "get double value"); } // Volatile { double x = (double) vh.getVolatile(); - assertEquals(x, 1.0d, "getVolatile double value"); + assertEquals(1.0d, x, "getVolatile double value"); } // Lazy { double x = (double) vh.getAcquire(); - assertEquals(x, 1.0d, "getRelease double value"); + assertEquals(1.0d, x, "getRelease double value"); } // Opaque { double x = (double) vh.getOpaque(); - assertEquals(x, 1.0d, "getOpaque double value"); + assertEquals(1.0d, x, "getOpaque double value"); } } @@ -466,7 +464,7 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { { vh.set(recv, 1.0d); double x = (double) vh.get(recv); - assertEquals(x, 1.0d, "set double value"); + assertEquals(1.0d, x, "set double value"); } @@ -474,21 +472,21 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { { vh.setVolatile(recv, 2.0d); double x = (double) vh.getVolatile(recv); - assertEquals(x, 2.0d, "setVolatile double value"); + assertEquals(2.0d, x, "setVolatile double value"); } // Lazy { vh.setRelease(recv, 1.0d); double x = (double) vh.getAcquire(recv); - assertEquals(x, 1.0d, "setRelease double value"); + assertEquals(1.0d, x, "setRelease double value"); } // Opaque { vh.setOpaque(recv, 2.0d); double x = (double) vh.getOpaque(recv); - assertEquals(x, 2.0d, "setOpaque double value"); + assertEquals(2.0d, x, "setOpaque double value"); } vh.set(recv, 1.0d); @@ -498,56 +496,56 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { boolean r = vh.compareAndSet(recv, 1.0d, 2.0d); assertEquals(r, true, "success compareAndSet double"); double x = (double) vh.get(recv); - assertEquals(x, 2.0d, "success compareAndSet double value"); + assertEquals(2.0d, x, "success compareAndSet double value"); } { boolean r = vh.compareAndSet(recv, 1.0d, 3.0d); assertEquals(r, false, "failing compareAndSet double"); double x = (double) vh.get(recv); - assertEquals(x, 2.0d, "failing compareAndSet double value"); + assertEquals(2.0d, x, "failing compareAndSet double value"); } { double r = (double) vh.compareAndExchange(recv, 2.0d, 1.0d); assertEquals(r, 2.0d, "success compareAndExchange double"); double x = (double) vh.get(recv); - assertEquals(x, 1.0d, "success compareAndExchange double value"); + assertEquals(1.0d, x, "success compareAndExchange double value"); } { double r = (double) vh.compareAndExchange(recv, 2.0d, 3.0d); assertEquals(r, 1.0d, "failing compareAndExchange double"); double x = (double) vh.get(recv); - assertEquals(x, 1.0d, "failing compareAndExchange double value"); + assertEquals(1.0d, x, "failing compareAndExchange double value"); } { double r = (double) vh.compareAndExchangeAcquire(recv, 1.0d, 2.0d); assertEquals(r, 1.0d, "success compareAndExchangeAcquire double"); double x = (double) vh.get(recv); - assertEquals(x, 2.0d, "success compareAndExchangeAcquire double value"); + assertEquals(2.0d, x, "success compareAndExchangeAcquire double value"); } { double r = (double) vh.compareAndExchangeAcquire(recv, 1.0d, 3.0d); assertEquals(r, 2.0d, "failing compareAndExchangeAcquire double"); double x = (double) vh.get(recv); - assertEquals(x, 2.0d, "failing compareAndExchangeAcquire double value"); + assertEquals(2.0d, x, "failing compareAndExchangeAcquire double value"); } { double r = (double) vh.compareAndExchangeRelease(recv, 2.0d, 1.0d); assertEquals(r, 2.0d, "success compareAndExchangeRelease double"); double x = (double) vh.get(recv); - assertEquals(x, 1.0d, "success compareAndExchangeRelease double value"); + assertEquals(1.0d, x, "success compareAndExchangeRelease double value"); } { double r = (double) vh.compareAndExchangeRelease(recv, 2.0d, 3.0d); assertEquals(r, 1.0d, "failing compareAndExchangeRelease double"); double x = (double) vh.get(recv); - assertEquals(x, 1.0d, "failing compareAndExchangeRelease double value"); + assertEquals(1.0d, x, "failing compareAndExchangeRelease double value"); } { @@ -558,14 +556,14 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain double"); double x = (double) vh.get(recv); - assertEquals(x, 2.0d, "success weakCompareAndSetPlain double value"); + assertEquals(2.0d, x, "success weakCompareAndSetPlain double value"); } { boolean success = vh.weakCompareAndSetPlain(recv, 1.0d, 3.0d); assertEquals(success, false, "failing weakCompareAndSetPlain double"); double x = (double) vh.get(recv); - assertEquals(x, 2.0d, "failing weakCompareAndSetPlain double value"); + assertEquals(2.0d, x, "failing weakCompareAndSetPlain double value"); } { @@ -576,14 +574,14 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire double"); double x = (double) vh.get(recv); - assertEquals(x, 1.0d, "success weakCompareAndSetAcquire double"); + assertEquals(1.0d, x, "success weakCompareAndSetAcquire double"); } { boolean success = vh.weakCompareAndSetAcquire(recv, 2.0d, 3.0d); assertEquals(success, false, "failing weakCompareAndSetAcquire double"); double x = (double) vh.get(recv); - assertEquals(x, 1.0d, "failing weakCompareAndSetAcquire double value"); + assertEquals(1.0d, x, "failing weakCompareAndSetAcquire double value"); } { @@ -594,14 +592,14 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease double"); double x = (double) vh.get(recv); - assertEquals(x, 2.0d, "success weakCompareAndSetRelease double"); + assertEquals(2.0d, x, "success weakCompareAndSetRelease double"); } { boolean success = vh.weakCompareAndSetRelease(recv, 1.0d, 3.0d); assertEquals(success, false, "failing weakCompareAndSetRelease double"); double x = (double) vh.get(recv); - assertEquals(x, 2.0d, "failing weakCompareAndSetRelease double value"); + assertEquals(2.0d, x, "failing weakCompareAndSetRelease double value"); } { @@ -612,14 +610,14 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet double"); double x = (double) vh.get(recv); - assertEquals(x, 1.0d, "success weakCompareAndSet double value"); + assertEquals(1.0d, x, "success weakCompareAndSet double value"); } { boolean success = vh.weakCompareAndSet(recv, 2.0d, 3.0d); assertEquals(success, false, "failing weakCompareAndSet double"); double x = (double) vh.get(recv); - assertEquals(x, 1.0d, "failing weakCompareAndSet double value"); + assertEquals(1.0d, x, "failing weakCompareAndSet double value"); } // Compare set and get @@ -627,27 +625,27 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { vh.set(recv, 1.0d); double o = (double) vh.getAndSet(recv, 2.0d); - assertEquals(o, 1.0d, "getAndSet double"); + assertEquals(1.0d, o, "getAndSet double"); double x = (double) vh.get(recv); - assertEquals(x, 2.0d, "getAndSet double value"); + assertEquals(2.0d, x, "getAndSet double value"); } { vh.set(recv, 1.0d); double o = (double) vh.getAndSetAcquire(recv, 2.0d); - assertEquals(o, 1.0d, "getAndSetAcquire double"); + assertEquals(1.0d, o, "getAndSetAcquire double"); double x = (double) vh.get(recv); - assertEquals(x, 2.0d, "getAndSetAcquire double value"); + assertEquals(2.0d, x, "getAndSetAcquire double value"); } { vh.set(recv, 1.0d); double o = (double) vh.getAndSetRelease(recv, 2.0d); - assertEquals(o, 1.0d, "getAndSetRelease double"); + assertEquals(1.0d, o, "getAndSetRelease double"); double x = (double) vh.get(recv); - assertEquals(x, 2.0d, "getAndSetRelease double value"); + assertEquals(2.0d, x, "getAndSetRelease double value"); } // get and add, add and get @@ -655,27 +653,27 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { vh.set(recv, 1.0d); double o = (double) vh.getAndAdd(recv, 2.0d); - assertEquals(o, 1.0d, "getAndAdd double"); + assertEquals(1.0d, o, "getAndAdd double"); double x = (double) vh.get(recv); - assertEquals(x, (double)(1.0d + 2.0d), "getAndAdd double value"); + assertEquals((double)(1.0d + 2.0d), x, "getAndAdd double value"); } { vh.set(recv, 1.0d); double o = (double) vh.getAndAddAcquire(recv, 2.0d); - assertEquals(o, 1.0d, "getAndAddAcquire double"); + assertEquals(1.0d, o, "getAndAddAcquire double"); double x = (double) vh.get(recv); - assertEquals(x, (double)(1.0d + 2.0d), "getAndAddAcquire double value"); + assertEquals((double)(1.0d + 2.0d), x, "getAndAddAcquire double value"); } { vh.set(recv, 1.0d); double o = (double) vh.getAndAddRelease(recv, 2.0d); - assertEquals(o, 1.0d, "getAndAddReleasedouble"); + assertEquals(1.0d, o, "getAndAddReleasedouble"); double x = (double) vh.get(recv); - assertEquals(x, (double)(1.0d + 2.0d), "getAndAddRelease double value"); + assertEquals((double)(1.0d + 2.0d), x, "getAndAddRelease double value"); } } @@ -726,7 +724,7 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { { vh.set(1.0d); double x = (double) vh.get(); - assertEquals(x, 1.0d, "set double value"); + assertEquals(1.0d, x, "set double value"); } @@ -734,21 +732,21 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { { vh.setVolatile(2.0d); double x = (double) vh.getVolatile(); - assertEquals(x, 2.0d, "setVolatile double value"); + assertEquals(2.0d, x, "setVolatile double value"); } // Lazy { vh.setRelease(1.0d); double x = (double) vh.getAcquire(); - assertEquals(x, 1.0d, "setRelease double value"); + assertEquals(1.0d, x, "setRelease double value"); } // Opaque { vh.setOpaque(2.0d); double x = (double) vh.getOpaque(); - assertEquals(x, 2.0d, "setOpaque double value"); + assertEquals(2.0d, x, "setOpaque double value"); } vh.set(1.0d); @@ -758,56 +756,56 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { boolean r = vh.compareAndSet(1.0d, 2.0d); assertEquals(r, true, "success compareAndSet double"); double x = (double) vh.get(); - assertEquals(x, 2.0d, "success compareAndSet double value"); + assertEquals(2.0d, x, "success compareAndSet double value"); } { boolean r = vh.compareAndSet(1.0d, 3.0d); assertEquals(r, false, "failing compareAndSet double"); double x = (double) vh.get(); - assertEquals(x, 2.0d, "failing compareAndSet double value"); + assertEquals(2.0d, x, "failing compareAndSet double value"); } { double r = (double) vh.compareAndExchange(2.0d, 1.0d); assertEquals(r, 2.0d, "success compareAndExchange double"); double x = (double) vh.get(); - assertEquals(x, 1.0d, "success compareAndExchange double value"); + assertEquals(1.0d, x, "success compareAndExchange double value"); } { double r = (double) vh.compareAndExchange(2.0d, 3.0d); assertEquals(r, 1.0d, "failing compareAndExchange double"); double x = (double) vh.get(); - assertEquals(x, 1.0d, "failing compareAndExchange double value"); + assertEquals(1.0d, x, "failing compareAndExchange double value"); } { double r = (double) vh.compareAndExchangeAcquire(1.0d, 2.0d); assertEquals(r, 1.0d, "success compareAndExchangeAcquire double"); double x = (double) vh.get(); - assertEquals(x, 2.0d, "success compareAndExchangeAcquire double value"); + assertEquals(2.0d, x, "success compareAndExchangeAcquire double value"); } { double r = (double) vh.compareAndExchangeAcquire(1.0d, 3.0d); assertEquals(r, 2.0d, "failing compareAndExchangeAcquire double"); double x = (double) vh.get(); - assertEquals(x, 2.0d, "failing compareAndExchangeAcquire double value"); + assertEquals(2.0d, x, "failing compareAndExchangeAcquire double value"); } { double r = (double) vh.compareAndExchangeRelease(2.0d, 1.0d); assertEquals(r, 2.0d, "success compareAndExchangeRelease double"); double x = (double) vh.get(); - assertEquals(x, 1.0d, "success compareAndExchangeRelease double value"); + assertEquals(1.0d, x, "success compareAndExchangeRelease double value"); } { double r = (double) vh.compareAndExchangeRelease(2.0d, 3.0d); assertEquals(r, 1.0d, "failing compareAndExchangeRelease double"); double x = (double) vh.get(); - assertEquals(x, 1.0d, "failing compareAndExchangeRelease double value"); + assertEquals(1.0d, x, "failing compareAndExchangeRelease double value"); } { @@ -818,14 +816,14 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain double"); double x = (double) vh.get(); - assertEquals(x, 2.0d, "success weakCompareAndSetPlain double value"); + assertEquals(2.0d, x, "success weakCompareAndSetPlain double value"); } { boolean success = vh.weakCompareAndSetPlain(1.0d, 3.0d); assertEquals(success, false, "failing weakCompareAndSetPlain double"); double x = (double) vh.get(); - assertEquals(x, 2.0d, "failing weakCompareAndSetPlain double value"); + assertEquals(2.0d, x, "failing weakCompareAndSetPlain double value"); } { @@ -836,14 +834,14 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire double"); double x = (double) vh.get(); - assertEquals(x, 1.0d, "success weakCompareAndSetAcquire double"); + assertEquals(1.0d, x, "success weakCompareAndSetAcquire double"); } { boolean success = vh.weakCompareAndSetAcquire(2.0d, 3.0d); assertEquals(success, false, "failing weakCompareAndSetAcquire double"); double x = (double) vh.get(); - assertEquals(x, 1.0d, "failing weakCompareAndSetAcquire double value"); + assertEquals(1.0d, x, "failing weakCompareAndSetAcquire double value"); } { @@ -854,14 +852,14 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease double"); double x = (double) vh.get(); - assertEquals(x, 2.0d, "success weakCompareAndSetRelease double"); + assertEquals(2.0d, x, "success weakCompareAndSetRelease double"); } { boolean success = vh.weakCompareAndSetRelease(1.0d, 3.0d); assertEquals(success, false, "failing weakCompareAndSetRelease double"); double x = (double) vh.get(); - assertEquals(x, 2.0d, "failing weakCompareAndSetRelease double value"); + assertEquals(2.0d, x, "failing weakCompareAndSetRelease double value"); } { @@ -872,14 +870,14 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet double"); double x = (double) vh.get(); - assertEquals(x, 1.0d, "success weakCompareAndSet double"); + assertEquals(1.0d, x, "success weakCompareAndSet double"); } { boolean success = vh.weakCompareAndSet(2.0d, 3.0d); assertEquals(success, false, "failing weakCompareAndSet double"); double x = (double) vh.get(); - assertEquals(x, 1.0d, "failing weakCompareAndSet double value"); + assertEquals(1.0d, x, "failing weakCompareAndSet double value"); } // Compare set and get @@ -887,27 +885,27 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { vh.set(1.0d); double o = (double) vh.getAndSet(2.0d); - assertEquals(o, 1.0d, "getAndSet double"); + assertEquals(1.0d, o, "getAndSet double"); double x = (double) vh.get(); - assertEquals(x, 2.0d, "getAndSet double value"); + assertEquals(2.0d, x, "getAndSet double value"); } { vh.set(1.0d); double o = (double) vh.getAndSetAcquire(2.0d); - assertEquals(o, 1.0d, "getAndSetAcquire double"); + assertEquals(1.0d, o, "getAndSetAcquire double"); double x = (double) vh.get(); - assertEquals(x, 2.0d, "getAndSetAcquire double value"); + assertEquals(2.0d, x, "getAndSetAcquire double value"); } { vh.set(1.0d); double o = (double) vh.getAndSetRelease(2.0d); - assertEquals(o, 1.0d, "getAndSetRelease double"); + assertEquals(1.0d, o, "getAndSetRelease double"); double x = (double) vh.get(); - assertEquals(x, 2.0d, "getAndSetRelease double value"); + assertEquals(2.0d, x, "getAndSetRelease double value"); } // get and add, add and get @@ -915,27 +913,27 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { vh.set(1.0d); double o = (double) vh.getAndAdd(2.0d); - assertEquals(o, 1.0d, "getAndAdd double"); + assertEquals(1.0d, o, "getAndAdd double"); double x = (double) vh.get(); - assertEquals(x, (double)(1.0d + 2.0d), "getAndAdd double value"); + assertEquals((double)(1.0d + 2.0d), x, "getAndAdd double value"); } { vh.set(1.0d); double o = (double) vh.getAndAddAcquire(2.0d); - assertEquals(o, 1.0d, "getAndAddAcquire double"); + assertEquals(1.0d, o, "getAndAddAcquire double"); double x = (double) vh.get(); - assertEquals(x, (double)(1.0d + 2.0d), "getAndAddAcquire double value"); + assertEquals((double)(1.0d + 2.0d), x, "getAndAddAcquire double value"); } { vh.set(1.0d); double o = (double) vh.getAndAddRelease(2.0d); - assertEquals(o, 1.0d, "getAndAddReleasedouble"); + assertEquals(1.0d, o, "getAndAddReleasedouble"); double x = (double) vh.get(); - assertEquals(x, (double)(1.0d + 2.0d), "getAndAddRelease double value"); + assertEquals((double)(1.0d + 2.0d), x, "getAndAddRelease double value"); } } @@ -989,7 +987,7 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { { vh.set(array, i, 1.0d); double x = (double) vh.get(array, i); - assertEquals(x, 1.0d, "get double value"); + assertEquals(1.0d, x, "get double value"); } @@ -997,21 +995,21 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { { vh.setVolatile(array, i, 2.0d); double x = (double) vh.getVolatile(array, i); - assertEquals(x, 2.0d, "setVolatile double value"); + assertEquals(2.0d, x, "setVolatile double value"); } // Lazy { vh.setRelease(array, i, 1.0d); double x = (double) vh.getAcquire(array, i); - assertEquals(x, 1.0d, "setRelease double value"); + assertEquals(1.0d, x, "setRelease double value"); } // Opaque { vh.setOpaque(array, i, 2.0d); double x = (double) vh.getOpaque(array, i); - assertEquals(x, 2.0d, "setOpaque double value"); + assertEquals(2.0d, x, "setOpaque double value"); } vh.set(array, i, 1.0d); @@ -1021,56 +1019,56 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { boolean r = vh.compareAndSet(array, i, 1.0d, 2.0d); assertEquals(r, true, "success compareAndSet double"); double x = (double) vh.get(array, i); - assertEquals(x, 2.0d, "success compareAndSet double value"); + assertEquals(2.0d, x, "success compareAndSet double value"); } { boolean r = vh.compareAndSet(array, i, 1.0d, 3.0d); assertEquals(r, false, "failing compareAndSet double"); double x = (double) vh.get(array, i); - assertEquals(x, 2.0d, "failing compareAndSet double value"); + assertEquals(2.0d, x, "failing compareAndSet double value"); } { double r = (double) vh.compareAndExchange(array, i, 2.0d, 1.0d); assertEquals(r, 2.0d, "success compareAndExchange double"); double x = (double) vh.get(array, i); - assertEquals(x, 1.0d, "success compareAndExchange double value"); + assertEquals(1.0d, x, "success compareAndExchange double value"); } { double r = (double) vh.compareAndExchange(array, i, 2.0d, 3.0d); assertEquals(r, 1.0d, "failing compareAndExchange double"); double x = (double) vh.get(array, i); - assertEquals(x, 1.0d, "failing compareAndExchange double value"); + assertEquals(1.0d, x, "failing compareAndExchange double value"); } { double r = (double) vh.compareAndExchangeAcquire(array, i, 1.0d, 2.0d); assertEquals(r, 1.0d, "success compareAndExchangeAcquire double"); double x = (double) vh.get(array, i); - assertEquals(x, 2.0d, "success compareAndExchangeAcquire double value"); + assertEquals(2.0d, x, "success compareAndExchangeAcquire double value"); } { double r = (double) vh.compareAndExchangeAcquire(array, i, 1.0d, 3.0d); assertEquals(r, 2.0d, "failing compareAndExchangeAcquire double"); double x = (double) vh.get(array, i); - assertEquals(x, 2.0d, "failing compareAndExchangeAcquire double value"); + assertEquals(2.0d, x, "failing compareAndExchangeAcquire double value"); } { double r = (double) vh.compareAndExchangeRelease(array, i, 2.0d, 1.0d); assertEquals(r, 2.0d, "success compareAndExchangeRelease double"); double x = (double) vh.get(array, i); - assertEquals(x, 1.0d, "success compareAndExchangeRelease double value"); + assertEquals(1.0d, x, "success compareAndExchangeRelease double value"); } { double r = (double) vh.compareAndExchangeRelease(array, i, 2.0d, 3.0d); assertEquals(r, 1.0d, "failing compareAndExchangeRelease double"); double x = (double) vh.get(array, i); - assertEquals(x, 1.0d, "failing compareAndExchangeRelease double value"); + assertEquals(1.0d, x, "failing compareAndExchangeRelease double value"); } { @@ -1081,14 +1079,14 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain double"); double x = (double) vh.get(array, i); - assertEquals(x, 2.0d, "success weakCompareAndSetPlain double value"); + assertEquals(2.0d, x, "success weakCompareAndSetPlain double value"); } { boolean success = vh.weakCompareAndSetPlain(array, i, 1.0d, 3.0d); assertEquals(success, false, "failing weakCompareAndSetPlain double"); double x = (double) vh.get(array, i); - assertEquals(x, 2.0d, "failing weakCompareAndSetPlain double value"); + assertEquals(2.0d, x, "failing weakCompareAndSetPlain double value"); } { @@ -1099,14 +1097,14 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire double"); double x = (double) vh.get(array, i); - assertEquals(x, 1.0d, "success weakCompareAndSetAcquire double"); + assertEquals(1.0d, x, "success weakCompareAndSetAcquire double"); } { boolean success = vh.weakCompareAndSetAcquire(array, i, 2.0d, 3.0d); assertEquals(success, false, "failing weakCompareAndSetAcquire double"); double x = (double) vh.get(array, i); - assertEquals(x, 1.0d, "failing weakCompareAndSetAcquire double value"); + assertEquals(1.0d, x, "failing weakCompareAndSetAcquire double value"); } { @@ -1117,14 +1115,14 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease double"); double x = (double) vh.get(array, i); - assertEquals(x, 2.0d, "success weakCompareAndSetRelease double"); + assertEquals(2.0d, x, "success weakCompareAndSetRelease double"); } { boolean success = vh.weakCompareAndSetRelease(array, i, 1.0d, 3.0d); assertEquals(success, false, "failing weakCompareAndSetRelease double"); double x = (double) vh.get(array, i); - assertEquals(x, 2.0d, "failing weakCompareAndSetRelease double value"); + assertEquals(2.0d, x, "failing weakCompareAndSetRelease double value"); } { @@ -1135,14 +1133,14 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet double"); double x = (double) vh.get(array, i); - assertEquals(x, 1.0d, "success weakCompareAndSet double"); + assertEquals(1.0d, x, "success weakCompareAndSet double"); } { boolean success = vh.weakCompareAndSet(array, i, 2.0d, 3.0d); assertEquals(success, false, "failing weakCompareAndSet double"); double x = (double) vh.get(array, i); - assertEquals(x, 1.0d, "failing weakCompareAndSet double value"); + assertEquals(1.0d, x, "failing weakCompareAndSet double value"); } // Compare set and get @@ -1150,27 +1148,27 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { vh.set(array, i, 1.0d); double o = (double) vh.getAndSet(array, i, 2.0d); - assertEquals(o, 1.0d, "getAndSet double"); + assertEquals(1.0d, o, "getAndSet double"); double x = (double) vh.get(array, i); - assertEquals(x, 2.0d, "getAndSet double value"); + assertEquals(2.0d, x, "getAndSet double value"); } { vh.set(array, i, 1.0d); double o = (double) vh.getAndSetAcquire(array, i, 2.0d); - assertEquals(o, 1.0d, "getAndSetAcquire double"); + assertEquals(1.0d, o, "getAndSetAcquire double"); double x = (double) vh.get(array, i); - assertEquals(x, 2.0d, "getAndSetAcquire double value"); + assertEquals(2.0d, x, "getAndSetAcquire double value"); } { vh.set(array, i, 1.0d); double o = (double) vh.getAndSetRelease(array, i, 2.0d); - assertEquals(o, 1.0d, "getAndSetRelease double"); + assertEquals(1.0d, o, "getAndSetRelease double"); double x = (double) vh.get(array, i); - assertEquals(x, 2.0d, "getAndSetRelease double value"); + assertEquals(2.0d, x, "getAndSetRelease double value"); } // get and add, add and get @@ -1178,27 +1176,27 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { vh.set(array, i, 1.0d); double o = (double) vh.getAndAdd(array, i, 2.0d); - assertEquals(o, 1.0d, "getAndAdd double"); + assertEquals(1.0d, o, "getAndAdd double"); double x = (double) vh.get(array, i); - assertEquals(x, (double)(1.0d + 2.0d), "getAndAdd double value"); + assertEquals((double)(1.0d + 2.0d), x, "getAndAdd double value"); } { vh.set(array, i, 1.0d); double o = (double) vh.getAndAddAcquire(array, i, 2.0d); - assertEquals(o, 1.0d, "getAndAddAcquire double"); + assertEquals(1.0d, o, "getAndAddAcquire double"); double x = (double) vh.get(array, i); - assertEquals(x, (double)(1.0d + 2.0d), "getAndAddAcquire double value"); + assertEquals((double)(1.0d + 2.0d), x, "getAndAddAcquire double value"); } { vh.set(array, i, 1.0d); double o = (double) vh.getAndAddRelease(array, i, 2.0d); - assertEquals(o, 1.0d, "getAndAddReleasedouble"); + assertEquals(1.0d, o, "getAndAddReleasedouble"); double x = (double) vh.get(array, i); - assertEquals(x, (double)(1.0d + 2.0d), "getAndAddRelease double value"); + assertEquals((double)(1.0d + 2.0d), x, "getAndAddRelease double value"); } } diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java index c77a8d68008..750a1bbc408 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,28 +23,30 @@ /* * @test - * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessFloat + * @run junit/othervm -Diters=10 -Xint VarHandleTestAccessFloat * * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations * to hit compilation thresholds * - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestAccessFloat - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestAccessFloat - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestAccessFloat + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestAccessFloat + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestAccessFloat + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestAccessFloat */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestAccessFloat extends VarHandleBaseTest { static final float static_final_v = 1.0f; @@ -108,7 +110,7 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { return vhs.toArray(new VarHandle[0]); } - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestAccessFloat.class, "final_v", float.class); @@ -125,8 +127,6 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { vhArray = MethodHandles.arrayElementVarHandle(float[].class); } - - @DataProvider public Object[][] varHandlesProvider() throws Exception { List vhs = new ArrayList<>(); vhs.add(vhField); @@ -156,7 +156,8 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { } } - @Test(dataProvider = "varHandlesProvider") + @ParameterizedTest + @MethodSource("varHandlesProvider") public void testIsAccessModeSupported(VarHandle vh) { assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET)); @@ -194,8 +195,6 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE)); } - - @DataProvider public Object[][] typesProvider() throws Exception { List types = new ArrayList<>(); types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessFloat.class)}); @@ -205,16 +204,16 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { return types.stream().toArray(Object[][]::new); } - @Test(dataProvider = "typesProvider") + @ParameterizedTest + @MethodSource("typesProvider") public void testTypes(VarHandle vh, List> pts) { - assertEquals(vh.varType(), float.class); + assertEquals(float.class, vh.varType()); - assertEquals(vh.coordinateTypes(), pts); + assertEquals(pts, vh.coordinateTypes()); testTypes(vh); } - @Test public void testLookupInstanceToStatic() { checkIAE("Lookup of static final field to instance final field", () -> { @@ -241,8 +240,6 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { }); } - - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -284,7 +281,8 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -297,26 +295,26 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { // Plain { float x = (float) vh.get(recv); - assertEquals(x, 1.0f, "get float value"); + assertEquals(1.0f, x, "get float value"); } // Volatile { float x = (float) vh.getVolatile(recv); - assertEquals(x, 1.0f, "getVolatile float value"); + assertEquals(1.0f, x, "getVolatile float value"); } // Lazy { float x = (float) vh.getAcquire(recv); - assertEquals(x, 1.0f, "getRelease float value"); + assertEquals(1.0f, x, "getRelease float value"); } // Opaque { float x = (float) vh.getOpaque(recv); - assertEquals(x, 1.0f, "getOpaque float value"); + assertEquals(1.0f, x, "getOpaque float value"); } } @@ -381,26 +379,26 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { // Plain { float x = (float) vh.get(); - assertEquals(x, 1.0f, "get float value"); + assertEquals(1.0f, x, "get float value"); } // Volatile { float x = (float) vh.getVolatile(); - assertEquals(x, 1.0f, "getVolatile float value"); + assertEquals(1.0f, x, "getVolatile float value"); } // Lazy { float x = (float) vh.getAcquire(); - assertEquals(x, 1.0f, "getRelease float value"); + assertEquals(1.0f, x, "getRelease float value"); } // Opaque { float x = (float) vh.getOpaque(); - assertEquals(x, 1.0f, "getOpaque float value"); + assertEquals(1.0f, x, "getOpaque float value"); } } @@ -466,7 +464,7 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { { vh.set(recv, 1.0f); float x = (float) vh.get(recv); - assertEquals(x, 1.0f, "set float value"); + assertEquals(1.0f, x, "set float value"); } @@ -474,21 +472,21 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { { vh.setVolatile(recv, 2.0f); float x = (float) vh.getVolatile(recv); - assertEquals(x, 2.0f, "setVolatile float value"); + assertEquals(2.0f, x, "setVolatile float value"); } // Lazy { vh.setRelease(recv, 1.0f); float x = (float) vh.getAcquire(recv); - assertEquals(x, 1.0f, "setRelease float value"); + assertEquals(1.0f, x, "setRelease float value"); } // Opaque { vh.setOpaque(recv, 2.0f); float x = (float) vh.getOpaque(recv); - assertEquals(x, 2.0f, "setOpaque float value"); + assertEquals(2.0f, x, "setOpaque float value"); } vh.set(recv, 1.0f); @@ -498,56 +496,56 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { boolean r = vh.compareAndSet(recv, 1.0f, 2.0f); assertEquals(r, true, "success compareAndSet float"); float x = (float) vh.get(recv); - assertEquals(x, 2.0f, "success compareAndSet float value"); + assertEquals(2.0f, x, "success compareAndSet float value"); } { boolean r = vh.compareAndSet(recv, 1.0f, 3.0f); assertEquals(r, false, "failing compareAndSet float"); float x = (float) vh.get(recv); - assertEquals(x, 2.0f, "failing compareAndSet float value"); + assertEquals(2.0f, x, "failing compareAndSet float value"); } { float r = (float) vh.compareAndExchange(recv, 2.0f, 1.0f); assertEquals(r, 2.0f, "success compareAndExchange float"); float x = (float) vh.get(recv); - assertEquals(x, 1.0f, "success compareAndExchange float value"); + assertEquals(1.0f, x, "success compareAndExchange float value"); } { float r = (float) vh.compareAndExchange(recv, 2.0f, 3.0f); assertEquals(r, 1.0f, "failing compareAndExchange float"); float x = (float) vh.get(recv); - assertEquals(x, 1.0f, "failing compareAndExchange float value"); + assertEquals(1.0f, x, "failing compareAndExchange float value"); } { float r = (float) vh.compareAndExchangeAcquire(recv, 1.0f, 2.0f); assertEquals(r, 1.0f, "success compareAndExchangeAcquire float"); float x = (float) vh.get(recv); - assertEquals(x, 2.0f, "success compareAndExchangeAcquire float value"); + assertEquals(2.0f, x, "success compareAndExchangeAcquire float value"); } { float r = (float) vh.compareAndExchangeAcquire(recv, 1.0f, 3.0f); assertEquals(r, 2.0f, "failing compareAndExchangeAcquire float"); float x = (float) vh.get(recv); - assertEquals(x, 2.0f, "failing compareAndExchangeAcquire float value"); + assertEquals(2.0f, x, "failing compareAndExchangeAcquire float value"); } { float r = (float) vh.compareAndExchangeRelease(recv, 2.0f, 1.0f); assertEquals(r, 2.0f, "success compareAndExchangeRelease float"); float x = (float) vh.get(recv); - assertEquals(x, 1.0f, "success compareAndExchangeRelease float value"); + assertEquals(1.0f, x, "success compareAndExchangeRelease float value"); } { float r = (float) vh.compareAndExchangeRelease(recv, 2.0f, 3.0f); assertEquals(r, 1.0f, "failing compareAndExchangeRelease float"); float x = (float) vh.get(recv); - assertEquals(x, 1.0f, "failing compareAndExchangeRelease float value"); + assertEquals(1.0f, x, "failing compareAndExchangeRelease float value"); } { @@ -558,14 +556,14 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain float"); float x = (float) vh.get(recv); - assertEquals(x, 2.0f, "success weakCompareAndSetPlain float value"); + assertEquals(2.0f, x, "success weakCompareAndSetPlain float value"); } { boolean success = vh.weakCompareAndSetPlain(recv, 1.0f, 3.0f); assertEquals(success, false, "failing weakCompareAndSetPlain float"); float x = (float) vh.get(recv); - assertEquals(x, 2.0f, "failing weakCompareAndSetPlain float value"); + assertEquals(2.0f, x, "failing weakCompareAndSetPlain float value"); } { @@ -576,14 +574,14 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire float"); float x = (float) vh.get(recv); - assertEquals(x, 1.0f, "success weakCompareAndSetAcquire float"); + assertEquals(1.0f, x, "success weakCompareAndSetAcquire float"); } { boolean success = vh.weakCompareAndSetAcquire(recv, 2.0f, 3.0f); assertEquals(success, false, "failing weakCompareAndSetAcquire float"); float x = (float) vh.get(recv); - assertEquals(x, 1.0f, "failing weakCompareAndSetAcquire float value"); + assertEquals(1.0f, x, "failing weakCompareAndSetAcquire float value"); } { @@ -594,14 +592,14 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease float"); float x = (float) vh.get(recv); - assertEquals(x, 2.0f, "success weakCompareAndSetRelease float"); + assertEquals(2.0f, x, "success weakCompareAndSetRelease float"); } { boolean success = vh.weakCompareAndSetRelease(recv, 1.0f, 3.0f); assertEquals(success, false, "failing weakCompareAndSetRelease float"); float x = (float) vh.get(recv); - assertEquals(x, 2.0f, "failing weakCompareAndSetRelease float value"); + assertEquals(2.0f, x, "failing weakCompareAndSetRelease float value"); } { @@ -612,14 +610,14 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet float"); float x = (float) vh.get(recv); - assertEquals(x, 1.0f, "success weakCompareAndSet float value"); + assertEquals(1.0f, x, "success weakCompareAndSet float value"); } { boolean success = vh.weakCompareAndSet(recv, 2.0f, 3.0f); assertEquals(success, false, "failing weakCompareAndSet float"); float x = (float) vh.get(recv); - assertEquals(x, 1.0f, "failing weakCompareAndSet float value"); + assertEquals(1.0f, x, "failing weakCompareAndSet float value"); } // Compare set and get @@ -627,27 +625,27 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { vh.set(recv, 1.0f); float o = (float) vh.getAndSet(recv, 2.0f); - assertEquals(o, 1.0f, "getAndSet float"); + assertEquals(1.0f, o, "getAndSet float"); float x = (float) vh.get(recv); - assertEquals(x, 2.0f, "getAndSet float value"); + assertEquals(2.0f, x, "getAndSet float value"); } { vh.set(recv, 1.0f); float o = (float) vh.getAndSetAcquire(recv, 2.0f); - assertEquals(o, 1.0f, "getAndSetAcquire float"); + assertEquals(1.0f, o, "getAndSetAcquire float"); float x = (float) vh.get(recv); - assertEquals(x, 2.0f, "getAndSetAcquire float value"); + assertEquals(2.0f, x, "getAndSetAcquire float value"); } { vh.set(recv, 1.0f); float o = (float) vh.getAndSetRelease(recv, 2.0f); - assertEquals(o, 1.0f, "getAndSetRelease float"); + assertEquals(1.0f, o, "getAndSetRelease float"); float x = (float) vh.get(recv); - assertEquals(x, 2.0f, "getAndSetRelease float value"); + assertEquals(2.0f, x, "getAndSetRelease float value"); } // get and add, add and get @@ -655,27 +653,27 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { vh.set(recv, 1.0f); float o = (float) vh.getAndAdd(recv, 2.0f); - assertEquals(o, 1.0f, "getAndAdd float"); + assertEquals(1.0f, o, "getAndAdd float"); float x = (float) vh.get(recv); - assertEquals(x, (float)(1.0f + 2.0f), "getAndAdd float value"); + assertEquals((float)(1.0f + 2.0f), x, "getAndAdd float value"); } { vh.set(recv, 1.0f); float o = (float) vh.getAndAddAcquire(recv, 2.0f); - assertEquals(o, 1.0f, "getAndAddAcquire float"); + assertEquals(1.0f, o, "getAndAddAcquire float"); float x = (float) vh.get(recv); - assertEquals(x, (float)(1.0f + 2.0f), "getAndAddAcquire float value"); + assertEquals((float)(1.0f + 2.0f), x, "getAndAddAcquire float value"); } { vh.set(recv, 1.0f); float o = (float) vh.getAndAddRelease(recv, 2.0f); - assertEquals(o, 1.0f, "getAndAddReleasefloat"); + assertEquals(1.0f, o, "getAndAddReleasefloat"); float x = (float) vh.get(recv); - assertEquals(x, (float)(1.0f + 2.0f), "getAndAddRelease float value"); + assertEquals((float)(1.0f + 2.0f), x, "getAndAddRelease float value"); } } @@ -726,7 +724,7 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { { vh.set(1.0f); float x = (float) vh.get(); - assertEquals(x, 1.0f, "set float value"); + assertEquals(1.0f, x, "set float value"); } @@ -734,21 +732,21 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { { vh.setVolatile(2.0f); float x = (float) vh.getVolatile(); - assertEquals(x, 2.0f, "setVolatile float value"); + assertEquals(2.0f, x, "setVolatile float value"); } // Lazy { vh.setRelease(1.0f); float x = (float) vh.getAcquire(); - assertEquals(x, 1.0f, "setRelease float value"); + assertEquals(1.0f, x, "setRelease float value"); } // Opaque { vh.setOpaque(2.0f); float x = (float) vh.getOpaque(); - assertEquals(x, 2.0f, "setOpaque float value"); + assertEquals(2.0f, x, "setOpaque float value"); } vh.set(1.0f); @@ -758,56 +756,56 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { boolean r = vh.compareAndSet(1.0f, 2.0f); assertEquals(r, true, "success compareAndSet float"); float x = (float) vh.get(); - assertEquals(x, 2.0f, "success compareAndSet float value"); + assertEquals(2.0f, x, "success compareAndSet float value"); } { boolean r = vh.compareAndSet(1.0f, 3.0f); assertEquals(r, false, "failing compareAndSet float"); float x = (float) vh.get(); - assertEquals(x, 2.0f, "failing compareAndSet float value"); + assertEquals(2.0f, x, "failing compareAndSet float value"); } { float r = (float) vh.compareAndExchange(2.0f, 1.0f); assertEquals(r, 2.0f, "success compareAndExchange float"); float x = (float) vh.get(); - assertEquals(x, 1.0f, "success compareAndExchange float value"); + assertEquals(1.0f, x, "success compareAndExchange float value"); } { float r = (float) vh.compareAndExchange(2.0f, 3.0f); assertEquals(r, 1.0f, "failing compareAndExchange float"); float x = (float) vh.get(); - assertEquals(x, 1.0f, "failing compareAndExchange float value"); + assertEquals(1.0f, x, "failing compareAndExchange float value"); } { float r = (float) vh.compareAndExchangeAcquire(1.0f, 2.0f); assertEquals(r, 1.0f, "success compareAndExchangeAcquire float"); float x = (float) vh.get(); - assertEquals(x, 2.0f, "success compareAndExchangeAcquire float value"); + assertEquals(2.0f, x, "success compareAndExchangeAcquire float value"); } { float r = (float) vh.compareAndExchangeAcquire(1.0f, 3.0f); assertEquals(r, 2.0f, "failing compareAndExchangeAcquire float"); float x = (float) vh.get(); - assertEquals(x, 2.0f, "failing compareAndExchangeAcquire float value"); + assertEquals(2.0f, x, "failing compareAndExchangeAcquire float value"); } { float r = (float) vh.compareAndExchangeRelease(2.0f, 1.0f); assertEquals(r, 2.0f, "success compareAndExchangeRelease float"); float x = (float) vh.get(); - assertEquals(x, 1.0f, "success compareAndExchangeRelease float value"); + assertEquals(1.0f, x, "success compareAndExchangeRelease float value"); } { float r = (float) vh.compareAndExchangeRelease(2.0f, 3.0f); assertEquals(r, 1.0f, "failing compareAndExchangeRelease float"); float x = (float) vh.get(); - assertEquals(x, 1.0f, "failing compareAndExchangeRelease float value"); + assertEquals(1.0f, x, "failing compareAndExchangeRelease float value"); } { @@ -818,14 +816,14 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain float"); float x = (float) vh.get(); - assertEquals(x, 2.0f, "success weakCompareAndSetPlain float value"); + assertEquals(2.0f, x, "success weakCompareAndSetPlain float value"); } { boolean success = vh.weakCompareAndSetPlain(1.0f, 3.0f); assertEquals(success, false, "failing weakCompareAndSetPlain float"); float x = (float) vh.get(); - assertEquals(x, 2.0f, "failing weakCompareAndSetPlain float value"); + assertEquals(2.0f, x, "failing weakCompareAndSetPlain float value"); } { @@ -836,14 +834,14 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire float"); float x = (float) vh.get(); - assertEquals(x, 1.0f, "success weakCompareAndSetAcquire float"); + assertEquals(1.0f, x, "success weakCompareAndSetAcquire float"); } { boolean success = vh.weakCompareAndSetAcquire(2.0f, 3.0f); assertEquals(success, false, "failing weakCompareAndSetAcquire float"); float x = (float) vh.get(); - assertEquals(x, 1.0f, "failing weakCompareAndSetAcquire float value"); + assertEquals(1.0f, x, "failing weakCompareAndSetAcquire float value"); } { @@ -854,14 +852,14 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease float"); float x = (float) vh.get(); - assertEquals(x, 2.0f, "success weakCompareAndSetRelease float"); + assertEquals(2.0f, x, "success weakCompareAndSetRelease float"); } { boolean success = vh.weakCompareAndSetRelease(1.0f, 3.0f); assertEquals(success, false, "failing weakCompareAndSetRelease float"); float x = (float) vh.get(); - assertEquals(x, 2.0f, "failing weakCompareAndSetRelease float value"); + assertEquals(2.0f, x, "failing weakCompareAndSetRelease float value"); } { @@ -872,14 +870,14 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet float"); float x = (float) vh.get(); - assertEquals(x, 1.0f, "success weakCompareAndSet float"); + assertEquals(1.0f, x, "success weakCompareAndSet float"); } { boolean success = vh.weakCompareAndSet(2.0f, 3.0f); assertEquals(success, false, "failing weakCompareAndSet float"); float x = (float) vh.get(); - assertEquals(x, 1.0f, "failing weakCompareAndSet float value"); + assertEquals(1.0f, x, "failing weakCompareAndSet float value"); } // Compare set and get @@ -887,27 +885,27 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { vh.set(1.0f); float o = (float) vh.getAndSet(2.0f); - assertEquals(o, 1.0f, "getAndSet float"); + assertEquals(1.0f, o, "getAndSet float"); float x = (float) vh.get(); - assertEquals(x, 2.0f, "getAndSet float value"); + assertEquals(2.0f, x, "getAndSet float value"); } { vh.set(1.0f); float o = (float) vh.getAndSetAcquire(2.0f); - assertEquals(o, 1.0f, "getAndSetAcquire float"); + assertEquals(1.0f, o, "getAndSetAcquire float"); float x = (float) vh.get(); - assertEquals(x, 2.0f, "getAndSetAcquire float value"); + assertEquals(2.0f, x, "getAndSetAcquire float value"); } { vh.set(1.0f); float o = (float) vh.getAndSetRelease(2.0f); - assertEquals(o, 1.0f, "getAndSetRelease float"); + assertEquals(1.0f, o, "getAndSetRelease float"); float x = (float) vh.get(); - assertEquals(x, 2.0f, "getAndSetRelease float value"); + assertEquals(2.0f, x, "getAndSetRelease float value"); } // get and add, add and get @@ -915,27 +913,27 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { vh.set(1.0f); float o = (float) vh.getAndAdd(2.0f); - assertEquals(o, 1.0f, "getAndAdd float"); + assertEquals(1.0f, o, "getAndAdd float"); float x = (float) vh.get(); - assertEquals(x, (float)(1.0f + 2.0f), "getAndAdd float value"); + assertEquals((float)(1.0f + 2.0f), x, "getAndAdd float value"); } { vh.set(1.0f); float o = (float) vh.getAndAddAcquire(2.0f); - assertEquals(o, 1.0f, "getAndAddAcquire float"); + assertEquals(1.0f, o, "getAndAddAcquire float"); float x = (float) vh.get(); - assertEquals(x, (float)(1.0f + 2.0f), "getAndAddAcquire float value"); + assertEquals((float)(1.0f + 2.0f), x, "getAndAddAcquire float value"); } { vh.set(1.0f); float o = (float) vh.getAndAddRelease(2.0f); - assertEquals(o, 1.0f, "getAndAddReleasefloat"); + assertEquals(1.0f, o, "getAndAddReleasefloat"); float x = (float) vh.get(); - assertEquals(x, (float)(1.0f + 2.0f), "getAndAddRelease float value"); + assertEquals((float)(1.0f + 2.0f), x, "getAndAddRelease float value"); } } @@ -989,7 +987,7 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { { vh.set(array, i, 1.0f); float x = (float) vh.get(array, i); - assertEquals(x, 1.0f, "get float value"); + assertEquals(1.0f, x, "get float value"); } @@ -997,21 +995,21 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { { vh.setVolatile(array, i, 2.0f); float x = (float) vh.getVolatile(array, i); - assertEquals(x, 2.0f, "setVolatile float value"); + assertEquals(2.0f, x, "setVolatile float value"); } // Lazy { vh.setRelease(array, i, 1.0f); float x = (float) vh.getAcquire(array, i); - assertEquals(x, 1.0f, "setRelease float value"); + assertEquals(1.0f, x, "setRelease float value"); } // Opaque { vh.setOpaque(array, i, 2.0f); float x = (float) vh.getOpaque(array, i); - assertEquals(x, 2.0f, "setOpaque float value"); + assertEquals(2.0f, x, "setOpaque float value"); } vh.set(array, i, 1.0f); @@ -1021,56 +1019,56 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { boolean r = vh.compareAndSet(array, i, 1.0f, 2.0f); assertEquals(r, true, "success compareAndSet float"); float x = (float) vh.get(array, i); - assertEquals(x, 2.0f, "success compareAndSet float value"); + assertEquals(2.0f, x, "success compareAndSet float value"); } { boolean r = vh.compareAndSet(array, i, 1.0f, 3.0f); assertEquals(r, false, "failing compareAndSet float"); float x = (float) vh.get(array, i); - assertEquals(x, 2.0f, "failing compareAndSet float value"); + assertEquals(2.0f, x, "failing compareAndSet float value"); } { float r = (float) vh.compareAndExchange(array, i, 2.0f, 1.0f); assertEquals(r, 2.0f, "success compareAndExchange float"); float x = (float) vh.get(array, i); - assertEquals(x, 1.0f, "success compareAndExchange float value"); + assertEquals(1.0f, x, "success compareAndExchange float value"); } { float r = (float) vh.compareAndExchange(array, i, 2.0f, 3.0f); assertEquals(r, 1.0f, "failing compareAndExchange float"); float x = (float) vh.get(array, i); - assertEquals(x, 1.0f, "failing compareAndExchange float value"); + assertEquals(1.0f, x, "failing compareAndExchange float value"); } { float r = (float) vh.compareAndExchangeAcquire(array, i, 1.0f, 2.0f); assertEquals(r, 1.0f, "success compareAndExchangeAcquire float"); float x = (float) vh.get(array, i); - assertEquals(x, 2.0f, "success compareAndExchangeAcquire float value"); + assertEquals(2.0f, x, "success compareAndExchangeAcquire float value"); } { float r = (float) vh.compareAndExchangeAcquire(array, i, 1.0f, 3.0f); assertEquals(r, 2.0f, "failing compareAndExchangeAcquire float"); float x = (float) vh.get(array, i); - assertEquals(x, 2.0f, "failing compareAndExchangeAcquire float value"); + assertEquals(2.0f, x, "failing compareAndExchangeAcquire float value"); } { float r = (float) vh.compareAndExchangeRelease(array, i, 2.0f, 1.0f); assertEquals(r, 2.0f, "success compareAndExchangeRelease float"); float x = (float) vh.get(array, i); - assertEquals(x, 1.0f, "success compareAndExchangeRelease float value"); + assertEquals(1.0f, x, "success compareAndExchangeRelease float value"); } { float r = (float) vh.compareAndExchangeRelease(array, i, 2.0f, 3.0f); assertEquals(r, 1.0f, "failing compareAndExchangeRelease float"); float x = (float) vh.get(array, i); - assertEquals(x, 1.0f, "failing compareAndExchangeRelease float value"); + assertEquals(1.0f, x, "failing compareAndExchangeRelease float value"); } { @@ -1081,14 +1079,14 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain float"); float x = (float) vh.get(array, i); - assertEquals(x, 2.0f, "success weakCompareAndSetPlain float value"); + assertEquals(2.0f, x, "success weakCompareAndSetPlain float value"); } { boolean success = vh.weakCompareAndSetPlain(array, i, 1.0f, 3.0f); assertEquals(success, false, "failing weakCompareAndSetPlain float"); float x = (float) vh.get(array, i); - assertEquals(x, 2.0f, "failing weakCompareAndSetPlain float value"); + assertEquals(2.0f, x, "failing weakCompareAndSetPlain float value"); } { @@ -1099,14 +1097,14 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire float"); float x = (float) vh.get(array, i); - assertEquals(x, 1.0f, "success weakCompareAndSetAcquire float"); + assertEquals(1.0f, x, "success weakCompareAndSetAcquire float"); } { boolean success = vh.weakCompareAndSetAcquire(array, i, 2.0f, 3.0f); assertEquals(success, false, "failing weakCompareAndSetAcquire float"); float x = (float) vh.get(array, i); - assertEquals(x, 1.0f, "failing weakCompareAndSetAcquire float value"); + assertEquals(1.0f, x, "failing weakCompareAndSetAcquire float value"); } { @@ -1117,14 +1115,14 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease float"); float x = (float) vh.get(array, i); - assertEquals(x, 2.0f, "success weakCompareAndSetRelease float"); + assertEquals(2.0f, x, "success weakCompareAndSetRelease float"); } { boolean success = vh.weakCompareAndSetRelease(array, i, 1.0f, 3.0f); assertEquals(success, false, "failing weakCompareAndSetRelease float"); float x = (float) vh.get(array, i); - assertEquals(x, 2.0f, "failing weakCompareAndSetRelease float value"); + assertEquals(2.0f, x, "failing weakCompareAndSetRelease float value"); } { @@ -1135,14 +1133,14 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet float"); float x = (float) vh.get(array, i); - assertEquals(x, 1.0f, "success weakCompareAndSet float"); + assertEquals(1.0f, x, "success weakCompareAndSet float"); } { boolean success = vh.weakCompareAndSet(array, i, 2.0f, 3.0f); assertEquals(success, false, "failing weakCompareAndSet float"); float x = (float) vh.get(array, i); - assertEquals(x, 1.0f, "failing weakCompareAndSet float value"); + assertEquals(1.0f, x, "failing weakCompareAndSet float value"); } // Compare set and get @@ -1150,27 +1148,27 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { vh.set(array, i, 1.0f); float o = (float) vh.getAndSet(array, i, 2.0f); - assertEquals(o, 1.0f, "getAndSet float"); + assertEquals(1.0f, o, "getAndSet float"); float x = (float) vh.get(array, i); - assertEquals(x, 2.0f, "getAndSet float value"); + assertEquals(2.0f, x, "getAndSet float value"); } { vh.set(array, i, 1.0f); float o = (float) vh.getAndSetAcquire(array, i, 2.0f); - assertEquals(o, 1.0f, "getAndSetAcquire float"); + assertEquals(1.0f, o, "getAndSetAcquire float"); float x = (float) vh.get(array, i); - assertEquals(x, 2.0f, "getAndSetAcquire float value"); + assertEquals(2.0f, x, "getAndSetAcquire float value"); } { vh.set(array, i, 1.0f); float o = (float) vh.getAndSetRelease(array, i, 2.0f); - assertEquals(o, 1.0f, "getAndSetRelease float"); + assertEquals(1.0f, o, "getAndSetRelease float"); float x = (float) vh.get(array, i); - assertEquals(x, 2.0f, "getAndSetRelease float value"); + assertEquals(2.0f, x, "getAndSetRelease float value"); } // get and add, add and get @@ -1178,27 +1176,27 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { vh.set(array, i, 1.0f); float o = (float) vh.getAndAdd(array, i, 2.0f); - assertEquals(o, 1.0f, "getAndAdd float"); + assertEquals(1.0f, o, "getAndAdd float"); float x = (float) vh.get(array, i); - assertEquals(x, (float)(1.0f + 2.0f), "getAndAdd float value"); + assertEquals((float)(1.0f + 2.0f), x, "getAndAdd float value"); } { vh.set(array, i, 1.0f); float o = (float) vh.getAndAddAcquire(array, i, 2.0f); - assertEquals(o, 1.0f, "getAndAddAcquire float"); + assertEquals(1.0f, o, "getAndAddAcquire float"); float x = (float) vh.get(array, i); - assertEquals(x, (float)(1.0f + 2.0f), "getAndAddAcquire float value"); + assertEquals((float)(1.0f + 2.0f), x, "getAndAddAcquire float value"); } { vh.set(array, i, 1.0f); float o = (float) vh.getAndAddRelease(array, i, 2.0f); - assertEquals(o, 1.0f, "getAndAddReleasefloat"); + assertEquals(1.0f, o, "getAndAddReleasefloat"); float x = (float) vh.get(array, i); - assertEquals(x, (float)(1.0f + 2.0f), "getAndAddRelease float value"); + assertEquals((float)(1.0f + 2.0f), x, "getAndAddRelease float value"); } } diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java index d5dfaa4e1c6..4748d699555 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,28 +23,30 @@ /* * @test - * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessInt + * @run junit/othervm -Diters=10 -Xint VarHandleTestAccessInt * * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations * to hit compilation thresholds * - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestAccessInt - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestAccessInt - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestAccessInt + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestAccessInt + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestAccessInt + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestAccessInt */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestAccessInt extends VarHandleBaseTest { static final int static_final_v = 0x01234567; @@ -108,7 +110,7 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { return vhs.toArray(new VarHandle[0]); } - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestAccessInt.class, "final_v", int.class); @@ -125,8 +127,6 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { vhArray = MethodHandles.arrayElementVarHandle(int[].class); } - - @DataProvider public Object[][] varHandlesProvider() throws Exception { List vhs = new ArrayList<>(); vhs.add(vhField); @@ -156,7 +156,8 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { } } - @Test(dataProvider = "varHandlesProvider") + @ParameterizedTest + @MethodSource("varHandlesProvider") public void testIsAccessModeSupported(VarHandle vh) { assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET)); @@ -194,8 +195,6 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE)); } - - @DataProvider public Object[][] typesProvider() throws Exception { List types = new ArrayList<>(); types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessInt.class)}); @@ -205,16 +204,16 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { return types.stream().toArray(Object[][]::new); } - @Test(dataProvider = "typesProvider") + @ParameterizedTest + @MethodSource("typesProvider") public void testTypes(VarHandle vh, List> pts) { - assertEquals(vh.varType(), int.class); + assertEquals(int.class, vh.varType()); - assertEquals(vh.coordinateTypes(), pts); + assertEquals(pts, vh.coordinateTypes()); testTypes(vh); } - @Test public void testLookupInstanceToStatic() { checkIAE("Lookup of static final field to instance final field", () -> { @@ -241,8 +240,6 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { }); } - - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -284,7 +281,8 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -297,26 +295,26 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { // Plain { int x = (int) vh.get(recv); - assertEquals(x, 0x01234567, "get int value"); + assertEquals(0x01234567, x, "get int value"); } // Volatile { int x = (int) vh.getVolatile(recv); - assertEquals(x, 0x01234567, "getVolatile int value"); + assertEquals(0x01234567, x, "getVolatile int value"); } // Lazy { int x = (int) vh.getAcquire(recv); - assertEquals(x, 0x01234567, "getRelease int value"); + assertEquals(0x01234567, x, "getRelease int value"); } // Opaque { int x = (int) vh.getOpaque(recv); - assertEquals(x, 0x01234567, "getOpaque int value"); + assertEquals(0x01234567, x, "getOpaque int value"); } } @@ -346,26 +344,26 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { // Plain { int x = (int) vh.get(); - assertEquals(x, 0x01234567, "get int value"); + assertEquals(0x01234567, x, "get int value"); } // Volatile { int x = (int) vh.getVolatile(); - assertEquals(x, 0x01234567, "getVolatile int value"); + assertEquals(0x01234567, x, "getVolatile int value"); } // Lazy { int x = (int) vh.getAcquire(); - assertEquals(x, 0x01234567, "getRelease int value"); + assertEquals(0x01234567, x, "getRelease int value"); } // Opaque { int x = (int) vh.getOpaque(); - assertEquals(x, 0x01234567, "getOpaque int value"); + assertEquals(0x01234567, x, "getOpaque int value"); } } @@ -396,7 +394,7 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { { vh.set(recv, 0x01234567); int x = (int) vh.get(recv); - assertEquals(x, 0x01234567, "set int value"); + assertEquals(0x01234567, x, "set int value"); } @@ -404,21 +402,21 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { { vh.setVolatile(recv, 0x89ABCDEF); int x = (int) vh.getVolatile(recv); - assertEquals(x, 0x89ABCDEF, "setVolatile int value"); + assertEquals(0x89ABCDEF, x, "setVolatile int value"); } // Lazy { vh.setRelease(recv, 0x01234567); int x = (int) vh.getAcquire(recv); - assertEquals(x, 0x01234567, "setRelease int value"); + assertEquals(0x01234567, x, "setRelease int value"); } // Opaque { vh.setOpaque(recv, 0x89ABCDEF); int x = (int) vh.getOpaque(recv); - assertEquals(x, 0x89ABCDEF, "setOpaque int value"); + assertEquals(0x89ABCDEF, x, "setOpaque int value"); } vh.set(recv, 0x01234567); @@ -428,56 +426,56 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { boolean r = vh.compareAndSet(recv, 0x01234567, 0x89ABCDEF); assertEquals(r, true, "success compareAndSet int"); int x = (int) vh.get(recv); - assertEquals(x, 0x89ABCDEF, "success compareAndSet int value"); + assertEquals(0x89ABCDEF, x, "success compareAndSet int value"); } { boolean r = vh.compareAndSet(recv, 0x01234567, 0xCAFEBABE); assertEquals(r, false, "failing compareAndSet int"); int x = (int) vh.get(recv); - assertEquals(x, 0x89ABCDEF, "failing compareAndSet int value"); + assertEquals(0x89ABCDEF, x, "failing compareAndSet int value"); } { int r = (int) vh.compareAndExchange(recv, 0x89ABCDEF, 0x01234567); assertEquals(r, 0x89ABCDEF, "success compareAndExchange int"); int x = (int) vh.get(recv); - assertEquals(x, 0x01234567, "success compareAndExchange int value"); + assertEquals(0x01234567, x, "success compareAndExchange int value"); } { int r = (int) vh.compareAndExchange(recv, 0x89ABCDEF, 0xCAFEBABE); assertEquals(r, 0x01234567, "failing compareAndExchange int"); int x = (int) vh.get(recv); - assertEquals(x, 0x01234567, "failing compareAndExchange int value"); + assertEquals(0x01234567, x, "failing compareAndExchange int value"); } { int r = (int) vh.compareAndExchangeAcquire(recv, 0x01234567, 0x89ABCDEF); assertEquals(r, 0x01234567, "success compareAndExchangeAcquire int"); int x = (int) vh.get(recv); - assertEquals(x, 0x89ABCDEF, "success compareAndExchangeAcquire int value"); + assertEquals(0x89ABCDEF, x, "success compareAndExchangeAcquire int value"); } { int r = (int) vh.compareAndExchangeAcquire(recv, 0x01234567, 0xCAFEBABE); assertEquals(r, 0x89ABCDEF, "failing compareAndExchangeAcquire int"); int x = (int) vh.get(recv); - assertEquals(x, 0x89ABCDEF, "failing compareAndExchangeAcquire int value"); + assertEquals(0x89ABCDEF, x, "failing compareAndExchangeAcquire int value"); } { int r = (int) vh.compareAndExchangeRelease(recv, 0x89ABCDEF, 0x01234567); assertEquals(r, 0x89ABCDEF, "success compareAndExchangeRelease int"); int x = (int) vh.get(recv); - assertEquals(x, 0x01234567, "success compareAndExchangeRelease int value"); + assertEquals(0x01234567, x, "success compareAndExchangeRelease int value"); } { int r = (int) vh.compareAndExchangeRelease(recv, 0x89ABCDEF, 0xCAFEBABE); assertEquals(r, 0x01234567, "failing compareAndExchangeRelease int"); int x = (int) vh.get(recv); - assertEquals(x, 0x01234567, "failing compareAndExchangeRelease int value"); + assertEquals(0x01234567, x, "failing compareAndExchangeRelease int value"); } { @@ -488,14 +486,14 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain int"); int x = (int) vh.get(recv); - assertEquals(x, 0x89ABCDEF, "success weakCompareAndSetPlain int value"); + assertEquals(0x89ABCDEF, x, "success weakCompareAndSetPlain int value"); } { boolean success = vh.weakCompareAndSetPlain(recv, 0x01234567, 0xCAFEBABE); assertEquals(success, false, "failing weakCompareAndSetPlain int"); int x = (int) vh.get(recv); - assertEquals(x, 0x89ABCDEF, "failing weakCompareAndSetPlain int value"); + assertEquals(0x89ABCDEF, x, "failing weakCompareAndSetPlain int value"); } { @@ -506,14 +504,14 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire int"); int x = (int) vh.get(recv); - assertEquals(x, 0x01234567, "success weakCompareAndSetAcquire int"); + assertEquals(0x01234567, x, "success weakCompareAndSetAcquire int"); } { boolean success = vh.weakCompareAndSetAcquire(recv, 0x89ABCDEF, 0xCAFEBABE); assertEquals(success, false, "failing weakCompareAndSetAcquire int"); int x = (int) vh.get(recv); - assertEquals(x, 0x01234567, "failing weakCompareAndSetAcquire int value"); + assertEquals(0x01234567, x, "failing weakCompareAndSetAcquire int value"); } { @@ -524,14 +522,14 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease int"); int x = (int) vh.get(recv); - assertEquals(x, 0x89ABCDEF, "success weakCompareAndSetRelease int"); + assertEquals(0x89ABCDEF, x, "success weakCompareAndSetRelease int"); } { boolean success = vh.weakCompareAndSetRelease(recv, 0x01234567, 0xCAFEBABE); assertEquals(success, false, "failing weakCompareAndSetRelease int"); int x = (int) vh.get(recv); - assertEquals(x, 0x89ABCDEF, "failing weakCompareAndSetRelease int value"); + assertEquals(0x89ABCDEF, x, "failing weakCompareAndSetRelease int value"); } { @@ -542,14 +540,14 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet int"); int x = (int) vh.get(recv); - assertEquals(x, 0x01234567, "success weakCompareAndSet int value"); + assertEquals(0x01234567, x, "success weakCompareAndSet int value"); } { boolean success = vh.weakCompareAndSet(recv, 0x89ABCDEF, 0xCAFEBABE); assertEquals(success, false, "failing weakCompareAndSet int"); int x = (int) vh.get(recv); - assertEquals(x, 0x01234567, "failing weakCompareAndSet int value"); + assertEquals(0x01234567, x, "failing weakCompareAndSet int value"); } // Compare set and get @@ -557,27 +555,27 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { vh.set(recv, 0x01234567); int o = (int) vh.getAndSet(recv, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndSet int"); + assertEquals(0x01234567, o, "getAndSet int"); int x = (int) vh.get(recv); - assertEquals(x, 0x89ABCDEF, "getAndSet int value"); + assertEquals(0x89ABCDEF, x, "getAndSet int value"); } { vh.set(recv, 0x01234567); int o = (int) vh.getAndSetAcquire(recv, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndSetAcquire int"); + assertEquals(0x01234567, o, "getAndSetAcquire int"); int x = (int) vh.get(recv); - assertEquals(x, 0x89ABCDEF, "getAndSetAcquire int value"); + assertEquals(0x89ABCDEF, x, "getAndSetAcquire int value"); } { vh.set(recv, 0x01234567); int o = (int) vh.getAndSetRelease(recv, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndSetRelease int"); + assertEquals(0x01234567, o, "getAndSetRelease int"); int x = (int) vh.get(recv); - assertEquals(x, 0x89ABCDEF, "getAndSetRelease int value"); + assertEquals(0x89ABCDEF, x, "getAndSetRelease int value"); } // get and add, add and get @@ -585,27 +583,27 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { vh.set(recv, 0x01234567); int o = (int) vh.getAndAdd(recv, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndAdd int"); + assertEquals(0x01234567, o, "getAndAdd int"); int x = (int) vh.get(recv); - assertEquals(x, (int)(0x01234567 + 0x89ABCDEF), "getAndAdd int value"); + assertEquals((int)(0x01234567 + 0x89ABCDEF), x, "getAndAdd int value"); } { vh.set(recv, 0x01234567); int o = (int) vh.getAndAddAcquire(recv, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndAddAcquire int"); + assertEquals(0x01234567, o, "getAndAddAcquire int"); int x = (int) vh.get(recv); - assertEquals(x, (int)(0x01234567 + 0x89ABCDEF), "getAndAddAcquire int value"); + assertEquals((int)(0x01234567 + 0x89ABCDEF), x, "getAndAddAcquire int value"); } { vh.set(recv, 0x01234567); int o = (int) vh.getAndAddRelease(recv, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndAddReleaseint"); + assertEquals(0x01234567, o, "getAndAddReleaseint"); int x = (int) vh.get(recv); - assertEquals(x, (int)(0x01234567 + 0x89ABCDEF), "getAndAddRelease int value"); + assertEquals((int)(0x01234567 + 0x89ABCDEF), x, "getAndAddRelease int value"); } // get and bitwise or @@ -613,27 +611,27 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { vh.set(recv, 0x01234567); int o = (int) vh.getAndBitwiseOr(recv, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseOr int"); + assertEquals(0x01234567, o, "getAndBitwiseOr int"); int x = (int) vh.get(recv); - assertEquals(x, (int)(0x01234567 | 0x89ABCDEF), "getAndBitwiseOr int value"); + assertEquals((int)(0x01234567 | 0x89ABCDEF), x, "getAndBitwiseOr int value"); } { vh.set(recv, 0x01234567); int o = (int) vh.getAndBitwiseOrAcquire(recv, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseOrAcquire int"); + assertEquals(0x01234567, o, "getAndBitwiseOrAcquire int"); int x = (int) vh.get(recv); - assertEquals(x, (int)(0x01234567 | 0x89ABCDEF), "getAndBitwiseOrAcquire int value"); + assertEquals((int)(0x01234567 | 0x89ABCDEF), x, "getAndBitwiseOrAcquire int value"); } { vh.set(recv, 0x01234567); int o = (int) vh.getAndBitwiseOrRelease(recv, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseOrRelease int"); + assertEquals(0x01234567, o, "getAndBitwiseOrRelease int"); int x = (int) vh.get(recv); - assertEquals(x, (int)(0x01234567 | 0x89ABCDEF), "getAndBitwiseOrRelease int value"); + assertEquals((int)(0x01234567 | 0x89ABCDEF), x, "getAndBitwiseOrRelease int value"); } // get and bitwise and @@ -641,27 +639,27 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { vh.set(recv, 0x01234567); int o = (int) vh.getAndBitwiseAnd(recv, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseAnd int"); + assertEquals(0x01234567, o, "getAndBitwiseAnd int"); int x = (int) vh.get(recv); - assertEquals(x, (int)(0x01234567 & 0x89ABCDEF), "getAndBitwiseAnd int value"); + assertEquals((int)(0x01234567 & 0x89ABCDEF), x, "getAndBitwiseAnd int value"); } { vh.set(recv, 0x01234567); int o = (int) vh.getAndBitwiseAndAcquire(recv, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseAndAcquire int"); + assertEquals(0x01234567, o, "getAndBitwiseAndAcquire int"); int x = (int) vh.get(recv); - assertEquals(x, (int)(0x01234567 & 0x89ABCDEF), "getAndBitwiseAndAcquire int value"); + assertEquals((int)(0x01234567 & 0x89ABCDEF), x, "getAndBitwiseAndAcquire int value"); } { vh.set(recv, 0x01234567); int o = (int) vh.getAndBitwiseAndRelease(recv, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseAndRelease int"); + assertEquals(0x01234567, o, "getAndBitwiseAndRelease int"); int x = (int) vh.get(recv); - assertEquals(x, (int)(0x01234567 & 0x89ABCDEF), "getAndBitwiseAndRelease int value"); + assertEquals((int)(0x01234567 & 0x89ABCDEF), x, "getAndBitwiseAndRelease int value"); } // get and bitwise xor @@ -669,27 +667,27 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { vh.set(recv, 0x01234567); int o = (int) vh.getAndBitwiseXor(recv, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseXor int"); + assertEquals(0x01234567, o, "getAndBitwiseXor int"); int x = (int) vh.get(recv); - assertEquals(x, (int)(0x01234567 ^ 0x89ABCDEF), "getAndBitwiseXor int value"); + assertEquals((int)(0x01234567 ^ 0x89ABCDEF), x, "getAndBitwiseXor int value"); } { vh.set(recv, 0x01234567); int o = (int) vh.getAndBitwiseXorAcquire(recv, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseXorAcquire int"); + assertEquals(0x01234567, o, "getAndBitwiseXorAcquire int"); int x = (int) vh.get(recv); - assertEquals(x, (int)(0x01234567 ^ 0x89ABCDEF), "getAndBitwiseXorAcquire int value"); + assertEquals((int)(0x01234567 ^ 0x89ABCDEF), x, "getAndBitwiseXorAcquire int value"); } { vh.set(recv, 0x01234567); int o = (int) vh.getAndBitwiseXorRelease(recv, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseXorRelease int"); + assertEquals(0x01234567, o, "getAndBitwiseXorRelease int"); int x = (int) vh.get(recv); - assertEquals(x, (int)(0x01234567 ^ 0x89ABCDEF), "getAndBitwiseXorRelease int value"); + assertEquals((int)(0x01234567 ^ 0x89ABCDEF), x, "getAndBitwiseXorRelease int value"); } } @@ -704,7 +702,7 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { { vh.set(0x01234567); int x = (int) vh.get(); - assertEquals(x, 0x01234567, "set int value"); + assertEquals(0x01234567, x, "set int value"); } @@ -712,21 +710,21 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { { vh.setVolatile(0x89ABCDEF); int x = (int) vh.getVolatile(); - assertEquals(x, 0x89ABCDEF, "setVolatile int value"); + assertEquals(0x89ABCDEF, x, "setVolatile int value"); } // Lazy { vh.setRelease(0x01234567); int x = (int) vh.getAcquire(); - assertEquals(x, 0x01234567, "setRelease int value"); + assertEquals(0x01234567, x, "setRelease int value"); } // Opaque { vh.setOpaque(0x89ABCDEF); int x = (int) vh.getOpaque(); - assertEquals(x, 0x89ABCDEF, "setOpaque int value"); + assertEquals(0x89ABCDEF, x, "setOpaque int value"); } vh.set(0x01234567); @@ -736,56 +734,56 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { boolean r = vh.compareAndSet(0x01234567, 0x89ABCDEF); assertEquals(r, true, "success compareAndSet int"); int x = (int) vh.get(); - assertEquals(x, 0x89ABCDEF, "success compareAndSet int value"); + assertEquals(0x89ABCDEF, x, "success compareAndSet int value"); } { boolean r = vh.compareAndSet(0x01234567, 0xCAFEBABE); assertEquals(r, false, "failing compareAndSet int"); int x = (int) vh.get(); - assertEquals(x, 0x89ABCDEF, "failing compareAndSet int value"); + assertEquals(0x89ABCDEF, x, "failing compareAndSet int value"); } { int r = (int) vh.compareAndExchange(0x89ABCDEF, 0x01234567); assertEquals(r, 0x89ABCDEF, "success compareAndExchange int"); int x = (int) vh.get(); - assertEquals(x, 0x01234567, "success compareAndExchange int value"); + assertEquals(0x01234567, x, "success compareAndExchange int value"); } { int r = (int) vh.compareAndExchange(0x89ABCDEF, 0xCAFEBABE); assertEquals(r, 0x01234567, "failing compareAndExchange int"); int x = (int) vh.get(); - assertEquals(x, 0x01234567, "failing compareAndExchange int value"); + assertEquals(0x01234567, x, "failing compareAndExchange int value"); } { int r = (int) vh.compareAndExchangeAcquire(0x01234567, 0x89ABCDEF); assertEquals(r, 0x01234567, "success compareAndExchangeAcquire int"); int x = (int) vh.get(); - assertEquals(x, 0x89ABCDEF, "success compareAndExchangeAcquire int value"); + assertEquals(0x89ABCDEF, x, "success compareAndExchangeAcquire int value"); } { int r = (int) vh.compareAndExchangeAcquire(0x01234567, 0xCAFEBABE); assertEquals(r, 0x89ABCDEF, "failing compareAndExchangeAcquire int"); int x = (int) vh.get(); - assertEquals(x, 0x89ABCDEF, "failing compareAndExchangeAcquire int value"); + assertEquals(0x89ABCDEF, x, "failing compareAndExchangeAcquire int value"); } { int r = (int) vh.compareAndExchangeRelease(0x89ABCDEF, 0x01234567); assertEquals(r, 0x89ABCDEF, "success compareAndExchangeRelease int"); int x = (int) vh.get(); - assertEquals(x, 0x01234567, "success compareAndExchangeRelease int value"); + assertEquals(0x01234567, x, "success compareAndExchangeRelease int value"); } { int r = (int) vh.compareAndExchangeRelease(0x89ABCDEF, 0xCAFEBABE); assertEquals(r, 0x01234567, "failing compareAndExchangeRelease int"); int x = (int) vh.get(); - assertEquals(x, 0x01234567, "failing compareAndExchangeRelease int value"); + assertEquals(0x01234567, x, "failing compareAndExchangeRelease int value"); } { @@ -796,14 +794,14 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain int"); int x = (int) vh.get(); - assertEquals(x, 0x89ABCDEF, "success weakCompareAndSetPlain int value"); + assertEquals(0x89ABCDEF, x, "success weakCompareAndSetPlain int value"); } { boolean success = vh.weakCompareAndSetPlain(0x01234567, 0xCAFEBABE); assertEquals(success, false, "failing weakCompareAndSetPlain int"); int x = (int) vh.get(); - assertEquals(x, 0x89ABCDEF, "failing weakCompareAndSetPlain int value"); + assertEquals(0x89ABCDEF, x, "failing weakCompareAndSetPlain int value"); } { @@ -814,14 +812,14 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire int"); int x = (int) vh.get(); - assertEquals(x, 0x01234567, "success weakCompareAndSetAcquire int"); + assertEquals(0x01234567, x, "success weakCompareAndSetAcquire int"); } { boolean success = vh.weakCompareAndSetAcquire(0x89ABCDEF, 0xCAFEBABE); assertEquals(success, false, "failing weakCompareAndSetAcquire int"); int x = (int) vh.get(); - assertEquals(x, 0x01234567, "failing weakCompareAndSetAcquire int value"); + assertEquals(0x01234567, x, "failing weakCompareAndSetAcquire int value"); } { @@ -832,14 +830,14 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease int"); int x = (int) vh.get(); - assertEquals(x, 0x89ABCDEF, "success weakCompareAndSetRelease int"); + assertEquals(0x89ABCDEF, x, "success weakCompareAndSetRelease int"); } { boolean success = vh.weakCompareAndSetRelease(0x01234567, 0xCAFEBABE); assertEquals(success, false, "failing weakCompareAndSetRelease int"); int x = (int) vh.get(); - assertEquals(x, 0x89ABCDEF, "failing weakCompareAndSetRelease int value"); + assertEquals(0x89ABCDEF, x, "failing weakCompareAndSetRelease int value"); } { @@ -850,14 +848,14 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet int"); int x = (int) vh.get(); - assertEquals(x, 0x01234567, "success weakCompareAndSet int"); + assertEquals(0x01234567, x, "success weakCompareAndSet int"); } { boolean success = vh.weakCompareAndSet(0x89ABCDEF, 0xCAFEBABE); assertEquals(success, false, "failing weakCompareAndSet int"); int x = (int) vh.get(); - assertEquals(x, 0x01234567, "failing weakCompareAndSet int value"); + assertEquals(0x01234567, x, "failing weakCompareAndSet int value"); } // Compare set and get @@ -865,27 +863,27 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { vh.set(0x01234567); int o = (int) vh.getAndSet(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndSet int"); + assertEquals(0x01234567, o, "getAndSet int"); int x = (int) vh.get(); - assertEquals(x, 0x89ABCDEF, "getAndSet int value"); + assertEquals(0x89ABCDEF, x, "getAndSet int value"); } { vh.set(0x01234567); int o = (int) vh.getAndSetAcquire(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndSetAcquire int"); + assertEquals(0x01234567, o, "getAndSetAcquire int"); int x = (int) vh.get(); - assertEquals(x, 0x89ABCDEF, "getAndSetAcquire int value"); + assertEquals(0x89ABCDEF, x, "getAndSetAcquire int value"); } { vh.set(0x01234567); int o = (int) vh.getAndSetRelease(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndSetRelease int"); + assertEquals(0x01234567, o, "getAndSetRelease int"); int x = (int) vh.get(); - assertEquals(x, 0x89ABCDEF, "getAndSetRelease int value"); + assertEquals(0x89ABCDEF, x, "getAndSetRelease int value"); } // get and add, add and get @@ -893,27 +891,27 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { vh.set(0x01234567); int o = (int) vh.getAndAdd(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndAdd int"); + assertEquals(0x01234567, o, "getAndAdd int"); int x = (int) vh.get(); - assertEquals(x, (int)(0x01234567 + 0x89ABCDEF), "getAndAdd int value"); + assertEquals((int)(0x01234567 + 0x89ABCDEF), x, "getAndAdd int value"); } { vh.set(0x01234567); int o = (int) vh.getAndAddAcquire(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndAddAcquire int"); + assertEquals(0x01234567, o, "getAndAddAcquire int"); int x = (int) vh.get(); - assertEquals(x, (int)(0x01234567 + 0x89ABCDEF), "getAndAddAcquire int value"); + assertEquals((int)(0x01234567 + 0x89ABCDEF), x, "getAndAddAcquire int value"); } { vh.set(0x01234567); int o = (int) vh.getAndAddRelease(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndAddReleaseint"); + assertEquals(0x01234567, o, "getAndAddReleaseint"); int x = (int) vh.get(); - assertEquals(x, (int)(0x01234567 + 0x89ABCDEF), "getAndAddRelease int value"); + assertEquals((int)(0x01234567 + 0x89ABCDEF), x, "getAndAddRelease int value"); } // get and bitwise or @@ -921,27 +919,27 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { vh.set(0x01234567); int o = (int) vh.getAndBitwiseOr(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseOr int"); + assertEquals(0x01234567, o, "getAndBitwiseOr int"); int x = (int) vh.get(); - assertEquals(x, (int)(0x01234567 | 0x89ABCDEF), "getAndBitwiseOr int value"); + assertEquals((int)(0x01234567 | 0x89ABCDEF), x, "getAndBitwiseOr int value"); } { vh.set(0x01234567); int o = (int) vh.getAndBitwiseOrAcquire(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseOrAcquire int"); + assertEquals(0x01234567, o, "getAndBitwiseOrAcquire int"); int x = (int) vh.get(); - assertEquals(x, (int)(0x01234567 | 0x89ABCDEF), "getAndBitwiseOrAcquire int value"); + assertEquals((int)(0x01234567 | 0x89ABCDEF), x, "getAndBitwiseOrAcquire int value"); } { vh.set(0x01234567); int o = (int) vh.getAndBitwiseOrRelease(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseOrRelease int"); + assertEquals(0x01234567, o, "getAndBitwiseOrRelease int"); int x = (int) vh.get(); - assertEquals(x, (int)(0x01234567 | 0x89ABCDEF), "getAndBitwiseOrRelease int value"); + assertEquals((int)(0x01234567 | 0x89ABCDEF), x, "getAndBitwiseOrRelease int value"); } // get and bitwise and @@ -949,27 +947,27 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { vh.set(0x01234567); int o = (int) vh.getAndBitwiseAnd(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseAnd int"); + assertEquals(0x01234567, o, "getAndBitwiseAnd int"); int x = (int) vh.get(); - assertEquals(x, (int)(0x01234567 & 0x89ABCDEF), "getAndBitwiseAnd int value"); + assertEquals((int)(0x01234567 & 0x89ABCDEF), x, "getAndBitwiseAnd int value"); } { vh.set(0x01234567); int o = (int) vh.getAndBitwiseAndAcquire(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseAndAcquire int"); + assertEquals(0x01234567, o, "getAndBitwiseAndAcquire int"); int x = (int) vh.get(); - assertEquals(x, (int)(0x01234567 & 0x89ABCDEF), "getAndBitwiseAndAcquire int value"); + assertEquals((int)(0x01234567 & 0x89ABCDEF), x, "getAndBitwiseAndAcquire int value"); } { vh.set(0x01234567); int o = (int) vh.getAndBitwiseAndRelease(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseAndRelease int"); + assertEquals(0x01234567, o, "getAndBitwiseAndRelease int"); int x = (int) vh.get(); - assertEquals(x, (int)(0x01234567 & 0x89ABCDEF), "getAndBitwiseAndRelease int value"); + assertEquals((int)(0x01234567 & 0x89ABCDEF), x, "getAndBitwiseAndRelease int value"); } // get and bitwise xor @@ -977,27 +975,27 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { vh.set(0x01234567); int o = (int) vh.getAndBitwiseXor(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseXor int"); + assertEquals(0x01234567, o, "getAndBitwiseXor int"); int x = (int) vh.get(); - assertEquals(x, (int)(0x01234567 ^ 0x89ABCDEF), "getAndBitwiseXor int value"); + assertEquals((int)(0x01234567 ^ 0x89ABCDEF), x, "getAndBitwiseXor int value"); } { vh.set(0x01234567); int o = (int) vh.getAndBitwiseXorAcquire(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseXorAcquire int"); + assertEquals(0x01234567, o, "getAndBitwiseXorAcquire int"); int x = (int) vh.get(); - assertEquals(x, (int)(0x01234567 ^ 0x89ABCDEF), "getAndBitwiseXorAcquire int value"); + assertEquals((int)(0x01234567 ^ 0x89ABCDEF), x, "getAndBitwiseXorAcquire int value"); } { vh.set(0x01234567); int o = (int) vh.getAndBitwiseXorRelease(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseXorRelease int"); + assertEquals(0x01234567, o, "getAndBitwiseXorRelease int"); int x = (int) vh.get(); - assertEquals(x, (int)(0x01234567 ^ 0x89ABCDEF), "getAndBitwiseXorRelease int value"); + assertEquals((int)(0x01234567 ^ 0x89ABCDEF), x, "getAndBitwiseXorRelease int value"); } } @@ -1015,7 +1013,7 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { { vh.set(array, i, 0x01234567); int x = (int) vh.get(array, i); - assertEquals(x, 0x01234567, "get int value"); + assertEquals(0x01234567, x, "get int value"); } @@ -1023,21 +1021,21 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { { vh.setVolatile(array, i, 0x89ABCDEF); int x = (int) vh.getVolatile(array, i); - assertEquals(x, 0x89ABCDEF, "setVolatile int value"); + assertEquals(0x89ABCDEF, x, "setVolatile int value"); } // Lazy { vh.setRelease(array, i, 0x01234567); int x = (int) vh.getAcquire(array, i); - assertEquals(x, 0x01234567, "setRelease int value"); + assertEquals(0x01234567, x, "setRelease int value"); } // Opaque { vh.setOpaque(array, i, 0x89ABCDEF); int x = (int) vh.getOpaque(array, i); - assertEquals(x, 0x89ABCDEF, "setOpaque int value"); + assertEquals(0x89ABCDEF, x, "setOpaque int value"); } vh.set(array, i, 0x01234567); @@ -1047,56 +1045,56 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { boolean r = vh.compareAndSet(array, i, 0x01234567, 0x89ABCDEF); assertEquals(r, true, "success compareAndSet int"); int x = (int) vh.get(array, i); - assertEquals(x, 0x89ABCDEF, "success compareAndSet int value"); + assertEquals(0x89ABCDEF, x, "success compareAndSet int value"); } { boolean r = vh.compareAndSet(array, i, 0x01234567, 0xCAFEBABE); assertEquals(r, false, "failing compareAndSet int"); int x = (int) vh.get(array, i); - assertEquals(x, 0x89ABCDEF, "failing compareAndSet int value"); + assertEquals(0x89ABCDEF, x, "failing compareAndSet int value"); } { int r = (int) vh.compareAndExchange(array, i, 0x89ABCDEF, 0x01234567); assertEquals(r, 0x89ABCDEF, "success compareAndExchange int"); int x = (int) vh.get(array, i); - assertEquals(x, 0x01234567, "success compareAndExchange int value"); + assertEquals(0x01234567, x, "success compareAndExchange int value"); } { int r = (int) vh.compareAndExchange(array, i, 0x89ABCDEF, 0xCAFEBABE); assertEquals(r, 0x01234567, "failing compareAndExchange int"); int x = (int) vh.get(array, i); - assertEquals(x, 0x01234567, "failing compareAndExchange int value"); + assertEquals(0x01234567, x, "failing compareAndExchange int value"); } { int r = (int) vh.compareAndExchangeAcquire(array, i, 0x01234567, 0x89ABCDEF); assertEquals(r, 0x01234567, "success compareAndExchangeAcquire int"); int x = (int) vh.get(array, i); - assertEquals(x, 0x89ABCDEF, "success compareAndExchangeAcquire int value"); + assertEquals(0x89ABCDEF, x, "success compareAndExchangeAcquire int value"); } { int r = (int) vh.compareAndExchangeAcquire(array, i, 0x01234567, 0xCAFEBABE); assertEquals(r, 0x89ABCDEF, "failing compareAndExchangeAcquire int"); int x = (int) vh.get(array, i); - assertEquals(x, 0x89ABCDEF, "failing compareAndExchangeAcquire int value"); + assertEquals(0x89ABCDEF, x, "failing compareAndExchangeAcquire int value"); } { int r = (int) vh.compareAndExchangeRelease(array, i, 0x89ABCDEF, 0x01234567); assertEquals(r, 0x89ABCDEF, "success compareAndExchangeRelease int"); int x = (int) vh.get(array, i); - assertEquals(x, 0x01234567, "success compareAndExchangeRelease int value"); + assertEquals(0x01234567, x, "success compareAndExchangeRelease int value"); } { int r = (int) vh.compareAndExchangeRelease(array, i, 0x89ABCDEF, 0xCAFEBABE); assertEquals(r, 0x01234567, "failing compareAndExchangeRelease int"); int x = (int) vh.get(array, i); - assertEquals(x, 0x01234567, "failing compareAndExchangeRelease int value"); + assertEquals(0x01234567, x, "failing compareAndExchangeRelease int value"); } { @@ -1107,14 +1105,14 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain int"); int x = (int) vh.get(array, i); - assertEquals(x, 0x89ABCDEF, "success weakCompareAndSetPlain int value"); + assertEquals(0x89ABCDEF, x, "success weakCompareAndSetPlain int value"); } { boolean success = vh.weakCompareAndSetPlain(array, i, 0x01234567, 0xCAFEBABE); assertEquals(success, false, "failing weakCompareAndSetPlain int"); int x = (int) vh.get(array, i); - assertEquals(x, 0x89ABCDEF, "failing weakCompareAndSetPlain int value"); + assertEquals(0x89ABCDEF, x, "failing weakCompareAndSetPlain int value"); } { @@ -1125,14 +1123,14 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire int"); int x = (int) vh.get(array, i); - assertEquals(x, 0x01234567, "success weakCompareAndSetAcquire int"); + assertEquals(0x01234567, x, "success weakCompareAndSetAcquire int"); } { boolean success = vh.weakCompareAndSetAcquire(array, i, 0x89ABCDEF, 0xCAFEBABE); assertEquals(success, false, "failing weakCompareAndSetAcquire int"); int x = (int) vh.get(array, i); - assertEquals(x, 0x01234567, "failing weakCompareAndSetAcquire int value"); + assertEquals(0x01234567, x, "failing weakCompareAndSetAcquire int value"); } { @@ -1143,14 +1141,14 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease int"); int x = (int) vh.get(array, i); - assertEquals(x, 0x89ABCDEF, "success weakCompareAndSetRelease int"); + assertEquals(0x89ABCDEF, x, "success weakCompareAndSetRelease int"); } { boolean success = vh.weakCompareAndSetRelease(array, i, 0x01234567, 0xCAFEBABE); assertEquals(success, false, "failing weakCompareAndSetRelease int"); int x = (int) vh.get(array, i); - assertEquals(x, 0x89ABCDEF, "failing weakCompareAndSetRelease int value"); + assertEquals(0x89ABCDEF, x, "failing weakCompareAndSetRelease int value"); } { @@ -1161,14 +1159,14 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet int"); int x = (int) vh.get(array, i); - assertEquals(x, 0x01234567, "success weakCompareAndSet int"); + assertEquals(0x01234567, x, "success weakCompareAndSet int"); } { boolean success = vh.weakCompareAndSet(array, i, 0x89ABCDEF, 0xCAFEBABE); assertEquals(success, false, "failing weakCompareAndSet int"); int x = (int) vh.get(array, i); - assertEquals(x, 0x01234567, "failing weakCompareAndSet int value"); + assertEquals(0x01234567, x, "failing weakCompareAndSet int value"); } // Compare set and get @@ -1176,27 +1174,27 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { vh.set(array, i, 0x01234567); int o = (int) vh.getAndSet(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndSet int"); + assertEquals(0x01234567, o, "getAndSet int"); int x = (int) vh.get(array, i); - assertEquals(x, 0x89ABCDEF, "getAndSet int value"); + assertEquals(0x89ABCDEF, x, "getAndSet int value"); } { vh.set(array, i, 0x01234567); int o = (int) vh.getAndSetAcquire(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndSetAcquire int"); + assertEquals(0x01234567, o, "getAndSetAcquire int"); int x = (int) vh.get(array, i); - assertEquals(x, 0x89ABCDEF, "getAndSetAcquire int value"); + assertEquals(0x89ABCDEF, x, "getAndSetAcquire int value"); } { vh.set(array, i, 0x01234567); int o = (int) vh.getAndSetRelease(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndSetRelease int"); + assertEquals(0x01234567, o, "getAndSetRelease int"); int x = (int) vh.get(array, i); - assertEquals(x, 0x89ABCDEF, "getAndSetRelease int value"); + assertEquals(0x89ABCDEF, x, "getAndSetRelease int value"); } // get and add, add and get @@ -1204,27 +1202,27 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { vh.set(array, i, 0x01234567); int o = (int) vh.getAndAdd(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndAdd int"); + assertEquals(0x01234567, o, "getAndAdd int"); int x = (int) vh.get(array, i); - assertEquals(x, (int)(0x01234567 + 0x89ABCDEF), "getAndAdd int value"); + assertEquals((int)(0x01234567 + 0x89ABCDEF), x, "getAndAdd int value"); } { vh.set(array, i, 0x01234567); int o = (int) vh.getAndAddAcquire(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndAddAcquire int"); + assertEquals(0x01234567, o, "getAndAddAcquire int"); int x = (int) vh.get(array, i); - assertEquals(x, (int)(0x01234567 + 0x89ABCDEF), "getAndAddAcquire int value"); + assertEquals((int)(0x01234567 + 0x89ABCDEF), x, "getAndAddAcquire int value"); } { vh.set(array, i, 0x01234567); int o = (int) vh.getAndAddRelease(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndAddReleaseint"); + assertEquals(0x01234567, o, "getAndAddReleaseint"); int x = (int) vh.get(array, i); - assertEquals(x, (int)(0x01234567 + 0x89ABCDEF), "getAndAddRelease int value"); + assertEquals((int)(0x01234567 + 0x89ABCDEF), x, "getAndAddRelease int value"); } // get and bitwise or @@ -1232,27 +1230,27 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { vh.set(array, i, 0x01234567); int o = (int) vh.getAndBitwiseOr(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseOr int"); + assertEquals(0x01234567, o, "getAndBitwiseOr int"); int x = (int) vh.get(array, i); - assertEquals(x, (int)(0x01234567 | 0x89ABCDEF), "getAndBitwiseOr int value"); + assertEquals((int)(0x01234567 | 0x89ABCDEF), x, "getAndBitwiseOr int value"); } { vh.set(array, i, 0x01234567); int o = (int) vh.getAndBitwiseOrAcquire(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseOrAcquire int"); + assertEquals(0x01234567, o, "getAndBitwiseOrAcquire int"); int x = (int) vh.get(array, i); - assertEquals(x, (int)(0x01234567 | 0x89ABCDEF), "getAndBitwiseOrAcquire int value"); + assertEquals((int)(0x01234567 | 0x89ABCDEF), x, "getAndBitwiseOrAcquire int value"); } { vh.set(array, i, 0x01234567); int o = (int) vh.getAndBitwiseOrRelease(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseOrRelease int"); + assertEquals(0x01234567, o, "getAndBitwiseOrRelease int"); int x = (int) vh.get(array, i); - assertEquals(x, (int)(0x01234567 | 0x89ABCDEF), "getAndBitwiseOrRelease int value"); + assertEquals((int)(0x01234567 | 0x89ABCDEF), x, "getAndBitwiseOrRelease int value"); } // get and bitwise and @@ -1260,27 +1258,27 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { vh.set(array, i, 0x01234567); int o = (int) vh.getAndBitwiseAnd(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseAnd int"); + assertEquals(0x01234567, o, "getAndBitwiseAnd int"); int x = (int) vh.get(array, i); - assertEquals(x, (int)(0x01234567 & 0x89ABCDEF), "getAndBitwiseAnd int value"); + assertEquals((int)(0x01234567 & 0x89ABCDEF), x, "getAndBitwiseAnd int value"); } { vh.set(array, i, 0x01234567); int o = (int) vh.getAndBitwiseAndAcquire(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseAndAcquire int"); + assertEquals(0x01234567, o, "getAndBitwiseAndAcquire int"); int x = (int) vh.get(array, i); - assertEquals(x, (int)(0x01234567 & 0x89ABCDEF), "getAndBitwiseAndAcquire int value"); + assertEquals((int)(0x01234567 & 0x89ABCDEF), x, "getAndBitwiseAndAcquire int value"); } { vh.set(array, i, 0x01234567); int o = (int) vh.getAndBitwiseAndRelease(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseAndRelease int"); + assertEquals(0x01234567, o, "getAndBitwiseAndRelease int"); int x = (int) vh.get(array, i); - assertEquals(x, (int)(0x01234567 & 0x89ABCDEF), "getAndBitwiseAndRelease int value"); + assertEquals((int)(0x01234567 & 0x89ABCDEF), x, "getAndBitwiseAndRelease int value"); } // get and bitwise xor @@ -1288,27 +1286,27 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { vh.set(array, i, 0x01234567); int o = (int) vh.getAndBitwiseXor(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseXor int"); + assertEquals(0x01234567, o, "getAndBitwiseXor int"); int x = (int) vh.get(array, i); - assertEquals(x, (int)(0x01234567 ^ 0x89ABCDEF), "getAndBitwiseXor int value"); + assertEquals((int)(0x01234567 ^ 0x89ABCDEF), x, "getAndBitwiseXor int value"); } { vh.set(array, i, 0x01234567); int o = (int) vh.getAndBitwiseXorAcquire(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseXorAcquire int"); + assertEquals(0x01234567, o, "getAndBitwiseXorAcquire int"); int x = (int) vh.get(array, i); - assertEquals(x, (int)(0x01234567 ^ 0x89ABCDEF), "getAndBitwiseXorAcquire int value"); + assertEquals((int)(0x01234567 ^ 0x89ABCDEF), x, "getAndBitwiseXorAcquire int value"); } { vh.set(array, i, 0x01234567); int o = (int) vh.getAndBitwiseXorRelease(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseXorRelease int"); + assertEquals(0x01234567, o, "getAndBitwiseXorRelease int"); int x = (int) vh.get(array, i); - assertEquals(x, (int)(0x01234567 ^ 0x89ABCDEF), "getAndBitwiseXorRelease int value"); + assertEquals((int)(0x01234567 ^ 0x89ABCDEF), x, "getAndBitwiseXorRelease int value"); } } } diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java index e40256a8bd5..8bf997bb9a6 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,28 +23,30 @@ /* * @test - * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessLong + * @run junit/othervm -Diters=10 -Xint VarHandleTestAccessLong * * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations * to hit compilation thresholds * - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestAccessLong - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestAccessLong - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestAccessLong + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestAccessLong + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestAccessLong + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestAccessLong */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestAccessLong extends VarHandleBaseTest { static final long static_final_v = 0x0123456789ABCDEFL; @@ -108,7 +110,7 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { return vhs.toArray(new VarHandle[0]); } - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestAccessLong.class, "final_v", long.class); @@ -125,8 +127,6 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { vhArray = MethodHandles.arrayElementVarHandle(long[].class); } - - @DataProvider public Object[][] varHandlesProvider() throws Exception { List vhs = new ArrayList<>(); vhs.add(vhField); @@ -156,7 +156,8 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { } } - @Test(dataProvider = "varHandlesProvider") + @ParameterizedTest + @MethodSource("varHandlesProvider") public void testIsAccessModeSupported(VarHandle vh) { assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET)); @@ -194,8 +195,6 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE)); } - - @DataProvider public Object[][] typesProvider() throws Exception { List types = new ArrayList<>(); types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessLong.class)}); @@ -205,16 +204,16 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { return types.stream().toArray(Object[][]::new); } - @Test(dataProvider = "typesProvider") + @ParameterizedTest + @MethodSource("typesProvider") public void testTypes(VarHandle vh, List> pts) { - assertEquals(vh.varType(), long.class); + assertEquals(long.class, vh.varType()); - assertEquals(vh.coordinateTypes(), pts); + assertEquals(pts, vh.coordinateTypes()); testTypes(vh); } - @Test public void testLookupInstanceToStatic() { checkIAE("Lookup of static final field to instance final field", () -> { @@ -241,8 +240,6 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { }); } - - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -284,7 +281,8 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -297,26 +295,26 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { // Plain { long x = (long) vh.get(recv); - assertEquals(x, 0x0123456789ABCDEFL, "get long value"); + assertEquals(0x0123456789ABCDEFL, x, "get long value"); } // Volatile { long x = (long) vh.getVolatile(recv); - assertEquals(x, 0x0123456789ABCDEFL, "getVolatile long value"); + assertEquals(0x0123456789ABCDEFL, x, "getVolatile long value"); } // Lazy { long x = (long) vh.getAcquire(recv); - assertEquals(x, 0x0123456789ABCDEFL, "getRelease long value"); + assertEquals(0x0123456789ABCDEFL, x, "getRelease long value"); } // Opaque { long x = (long) vh.getOpaque(recv); - assertEquals(x, 0x0123456789ABCDEFL, "getOpaque long value"); + assertEquals(0x0123456789ABCDEFL, x, "getOpaque long value"); } } @@ -346,26 +344,26 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { // Plain { long x = (long) vh.get(); - assertEquals(x, 0x0123456789ABCDEFL, "get long value"); + assertEquals(0x0123456789ABCDEFL, x, "get long value"); } // Volatile { long x = (long) vh.getVolatile(); - assertEquals(x, 0x0123456789ABCDEFL, "getVolatile long value"); + assertEquals(0x0123456789ABCDEFL, x, "getVolatile long value"); } // Lazy { long x = (long) vh.getAcquire(); - assertEquals(x, 0x0123456789ABCDEFL, "getRelease long value"); + assertEquals(0x0123456789ABCDEFL, x, "getRelease long value"); } // Opaque { long x = (long) vh.getOpaque(); - assertEquals(x, 0x0123456789ABCDEFL, "getOpaque long value"); + assertEquals(0x0123456789ABCDEFL, x, "getOpaque long value"); } } @@ -396,7 +394,7 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { { vh.set(recv, 0x0123456789ABCDEFL); long x = (long) vh.get(recv); - assertEquals(x, 0x0123456789ABCDEFL, "set long value"); + assertEquals(0x0123456789ABCDEFL, x, "set long value"); } @@ -404,21 +402,21 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { { vh.setVolatile(recv, 0xCAFEBABECAFEBABEL); long x = (long) vh.getVolatile(recv); - assertEquals(x, 0xCAFEBABECAFEBABEL, "setVolatile long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "setVolatile long value"); } // Lazy { vh.setRelease(recv, 0x0123456789ABCDEFL); long x = (long) vh.getAcquire(recv); - assertEquals(x, 0x0123456789ABCDEFL, "setRelease long value"); + assertEquals(0x0123456789ABCDEFL, x, "setRelease long value"); } // Opaque { vh.setOpaque(recv, 0xCAFEBABECAFEBABEL); long x = (long) vh.getOpaque(recv); - assertEquals(x, 0xCAFEBABECAFEBABEL, "setOpaque long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "setOpaque long value"); } vh.set(recv, 0x0123456789ABCDEFL); @@ -428,56 +426,56 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { boolean r = vh.compareAndSet(recv, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); assertEquals(r, true, "success compareAndSet long"); long x = (long) vh.get(recv); - assertEquals(x, 0xCAFEBABECAFEBABEL, "success compareAndSet long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "success compareAndSet long value"); } { boolean r = vh.compareAndSet(recv, 0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); assertEquals(r, false, "failing compareAndSet long"); long x = (long) vh.get(recv); - assertEquals(x, 0xCAFEBABECAFEBABEL, "failing compareAndSet long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "failing compareAndSet long value"); } { long r = (long) vh.compareAndExchange(recv, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); assertEquals(r, 0xCAFEBABECAFEBABEL, "success compareAndExchange long"); long x = (long) vh.get(recv); - assertEquals(x, 0x0123456789ABCDEFL, "success compareAndExchange long value"); + assertEquals(0x0123456789ABCDEFL, x, "success compareAndExchange long value"); } { long r = (long) vh.compareAndExchange(recv, 0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); assertEquals(r, 0x0123456789ABCDEFL, "failing compareAndExchange long"); long x = (long) vh.get(recv); - assertEquals(x, 0x0123456789ABCDEFL, "failing compareAndExchange long value"); + assertEquals(0x0123456789ABCDEFL, x, "failing compareAndExchange long value"); } { long r = (long) vh.compareAndExchangeAcquire(recv, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); assertEquals(r, 0x0123456789ABCDEFL, "success compareAndExchangeAcquire long"); long x = (long) vh.get(recv); - assertEquals(x, 0xCAFEBABECAFEBABEL, "success compareAndExchangeAcquire long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "success compareAndExchangeAcquire long value"); } { long r = (long) vh.compareAndExchangeAcquire(recv, 0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); assertEquals(r, 0xCAFEBABECAFEBABEL, "failing compareAndExchangeAcquire long"); long x = (long) vh.get(recv); - assertEquals(x, 0xCAFEBABECAFEBABEL, "failing compareAndExchangeAcquire long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "failing compareAndExchangeAcquire long value"); } { long r = (long) vh.compareAndExchangeRelease(recv, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); assertEquals(r, 0xCAFEBABECAFEBABEL, "success compareAndExchangeRelease long"); long x = (long) vh.get(recv); - assertEquals(x, 0x0123456789ABCDEFL, "success compareAndExchangeRelease long value"); + assertEquals(0x0123456789ABCDEFL, x, "success compareAndExchangeRelease long value"); } { long r = (long) vh.compareAndExchangeRelease(recv, 0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); assertEquals(r, 0x0123456789ABCDEFL, "failing compareAndExchangeRelease long"); long x = (long) vh.get(recv); - assertEquals(x, 0x0123456789ABCDEFL, "failing compareAndExchangeRelease long value"); + assertEquals(0x0123456789ABCDEFL, x, "failing compareAndExchangeRelease long value"); } { @@ -488,14 +486,14 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain long"); long x = (long) vh.get(recv); - assertEquals(x, 0xCAFEBABECAFEBABEL, "success weakCompareAndSetPlain long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "success weakCompareAndSetPlain long value"); } { boolean success = vh.weakCompareAndSetPlain(recv, 0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); assertEquals(success, false, "failing weakCompareAndSetPlain long"); long x = (long) vh.get(recv); - assertEquals(x, 0xCAFEBABECAFEBABEL, "failing weakCompareAndSetPlain long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "failing weakCompareAndSetPlain long value"); } { @@ -506,14 +504,14 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire long"); long x = (long) vh.get(recv); - assertEquals(x, 0x0123456789ABCDEFL, "success weakCompareAndSetAcquire long"); + assertEquals(0x0123456789ABCDEFL, x, "success weakCompareAndSetAcquire long"); } { boolean success = vh.weakCompareAndSetAcquire(recv, 0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); assertEquals(success, false, "failing weakCompareAndSetAcquire long"); long x = (long) vh.get(recv); - assertEquals(x, 0x0123456789ABCDEFL, "failing weakCompareAndSetAcquire long value"); + assertEquals(0x0123456789ABCDEFL, x, "failing weakCompareAndSetAcquire long value"); } { @@ -524,14 +522,14 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease long"); long x = (long) vh.get(recv); - assertEquals(x, 0xCAFEBABECAFEBABEL, "success weakCompareAndSetRelease long"); + assertEquals(0xCAFEBABECAFEBABEL, x, "success weakCompareAndSetRelease long"); } { boolean success = vh.weakCompareAndSetRelease(recv, 0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); assertEquals(success, false, "failing weakCompareAndSetRelease long"); long x = (long) vh.get(recv); - assertEquals(x, 0xCAFEBABECAFEBABEL, "failing weakCompareAndSetRelease long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "failing weakCompareAndSetRelease long value"); } { @@ -542,14 +540,14 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet long"); long x = (long) vh.get(recv); - assertEquals(x, 0x0123456789ABCDEFL, "success weakCompareAndSet long value"); + assertEquals(0x0123456789ABCDEFL, x, "success weakCompareAndSet long value"); } { boolean success = vh.weakCompareAndSet(recv, 0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); assertEquals(success, false, "failing weakCompareAndSet long"); long x = (long) vh.get(recv); - assertEquals(x, 0x0123456789ABCDEFL, "failing weakCompareAndSet long value"); + assertEquals(0x0123456789ABCDEFL, x, "failing weakCompareAndSet long value"); } // Compare set and get @@ -557,27 +555,27 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { vh.set(recv, 0x0123456789ABCDEFL); long o = (long) vh.getAndSet(recv, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndSet long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndSet long"); long x = (long) vh.get(recv); - assertEquals(x, 0xCAFEBABECAFEBABEL, "getAndSet long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "getAndSet long value"); } { vh.set(recv, 0x0123456789ABCDEFL); long o = (long) vh.getAndSetAcquire(recv, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndSetAcquire long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndSetAcquire long"); long x = (long) vh.get(recv); - assertEquals(x, 0xCAFEBABECAFEBABEL, "getAndSetAcquire long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "getAndSetAcquire long value"); } { vh.set(recv, 0x0123456789ABCDEFL); long o = (long) vh.getAndSetRelease(recv, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndSetRelease long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndSetRelease long"); long x = (long) vh.get(recv); - assertEquals(x, 0xCAFEBABECAFEBABEL, "getAndSetRelease long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "getAndSetRelease long value"); } // get and add, add and get @@ -585,27 +583,27 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { vh.set(recv, 0x0123456789ABCDEFL); long o = (long) vh.getAndAdd(recv, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndAdd long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndAdd long"); long x = (long) vh.get(recv); - assertEquals(x, (long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), "getAndAdd long value"); + assertEquals((long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), x, "getAndAdd long value"); } { vh.set(recv, 0x0123456789ABCDEFL); long o = (long) vh.getAndAddAcquire(recv, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndAddAcquire long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndAddAcquire long"); long x = (long) vh.get(recv); - assertEquals(x, (long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), "getAndAddAcquire long value"); + assertEquals((long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), x, "getAndAddAcquire long value"); } { vh.set(recv, 0x0123456789ABCDEFL); long o = (long) vh.getAndAddRelease(recv, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndAddReleaselong"); + assertEquals(0x0123456789ABCDEFL, o, "getAndAddReleaselong"); long x = (long) vh.get(recv); - assertEquals(x, (long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), "getAndAddRelease long value"); + assertEquals((long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), x, "getAndAddRelease long value"); } // get and bitwise or @@ -613,27 +611,27 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { vh.set(recv, 0x0123456789ABCDEFL); long o = (long) vh.getAndBitwiseOr(recv, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseOr long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseOr long"); long x = (long) vh.get(recv); - assertEquals(x, (long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), "getAndBitwiseOr long value"); + assertEquals((long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), x, "getAndBitwiseOr long value"); } { vh.set(recv, 0x0123456789ABCDEFL); long o = (long) vh.getAndBitwiseOrAcquire(recv, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseOrAcquire long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseOrAcquire long"); long x = (long) vh.get(recv); - assertEquals(x, (long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), "getAndBitwiseOrAcquire long value"); + assertEquals((long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), x, "getAndBitwiseOrAcquire long value"); } { vh.set(recv, 0x0123456789ABCDEFL); long o = (long) vh.getAndBitwiseOrRelease(recv, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseOrRelease long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseOrRelease long"); long x = (long) vh.get(recv); - assertEquals(x, (long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), "getAndBitwiseOrRelease long value"); + assertEquals((long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), x, "getAndBitwiseOrRelease long value"); } // get and bitwise and @@ -641,27 +639,27 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { vh.set(recv, 0x0123456789ABCDEFL); long o = (long) vh.getAndBitwiseAnd(recv, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseAnd long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseAnd long"); long x = (long) vh.get(recv); - assertEquals(x, (long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), "getAndBitwiseAnd long value"); + assertEquals((long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), x, "getAndBitwiseAnd long value"); } { vh.set(recv, 0x0123456789ABCDEFL); long o = (long) vh.getAndBitwiseAndAcquire(recv, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseAndAcquire long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseAndAcquire long"); long x = (long) vh.get(recv); - assertEquals(x, (long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), "getAndBitwiseAndAcquire long value"); + assertEquals((long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), x, "getAndBitwiseAndAcquire long value"); } { vh.set(recv, 0x0123456789ABCDEFL); long o = (long) vh.getAndBitwiseAndRelease(recv, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseAndRelease long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseAndRelease long"); long x = (long) vh.get(recv); - assertEquals(x, (long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), "getAndBitwiseAndRelease long value"); + assertEquals((long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), x, "getAndBitwiseAndRelease long value"); } // get and bitwise xor @@ -669,27 +667,27 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { vh.set(recv, 0x0123456789ABCDEFL); long o = (long) vh.getAndBitwiseXor(recv, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseXor long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseXor long"); long x = (long) vh.get(recv); - assertEquals(x, (long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), "getAndBitwiseXor long value"); + assertEquals((long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), x, "getAndBitwiseXor long value"); } { vh.set(recv, 0x0123456789ABCDEFL); long o = (long) vh.getAndBitwiseXorAcquire(recv, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseXorAcquire long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseXorAcquire long"); long x = (long) vh.get(recv); - assertEquals(x, (long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), "getAndBitwiseXorAcquire long value"); + assertEquals((long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), x, "getAndBitwiseXorAcquire long value"); } { vh.set(recv, 0x0123456789ABCDEFL); long o = (long) vh.getAndBitwiseXorRelease(recv, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseXorRelease long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseXorRelease long"); long x = (long) vh.get(recv); - assertEquals(x, (long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), "getAndBitwiseXorRelease long value"); + assertEquals((long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), x, "getAndBitwiseXorRelease long value"); } } @@ -704,7 +702,7 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { { vh.set(0x0123456789ABCDEFL); long x = (long) vh.get(); - assertEquals(x, 0x0123456789ABCDEFL, "set long value"); + assertEquals(0x0123456789ABCDEFL, x, "set long value"); } @@ -712,21 +710,21 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { { vh.setVolatile(0xCAFEBABECAFEBABEL); long x = (long) vh.getVolatile(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "setVolatile long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "setVolatile long value"); } // Lazy { vh.setRelease(0x0123456789ABCDEFL); long x = (long) vh.getAcquire(); - assertEquals(x, 0x0123456789ABCDEFL, "setRelease long value"); + assertEquals(0x0123456789ABCDEFL, x, "setRelease long value"); } // Opaque { vh.setOpaque(0xCAFEBABECAFEBABEL); long x = (long) vh.getOpaque(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "setOpaque long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "setOpaque long value"); } vh.set(0x0123456789ABCDEFL); @@ -736,56 +734,56 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { boolean r = vh.compareAndSet(0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); assertEquals(r, true, "success compareAndSet long"); long x = (long) vh.get(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "success compareAndSet long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "success compareAndSet long value"); } { boolean r = vh.compareAndSet(0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); assertEquals(r, false, "failing compareAndSet long"); long x = (long) vh.get(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "failing compareAndSet long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "failing compareAndSet long value"); } { long r = (long) vh.compareAndExchange(0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); assertEquals(r, 0xCAFEBABECAFEBABEL, "success compareAndExchange long"); long x = (long) vh.get(); - assertEquals(x, 0x0123456789ABCDEFL, "success compareAndExchange long value"); + assertEquals(0x0123456789ABCDEFL, x, "success compareAndExchange long value"); } { long r = (long) vh.compareAndExchange(0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); assertEquals(r, 0x0123456789ABCDEFL, "failing compareAndExchange long"); long x = (long) vh.get(); - assertEquals(x, 0x0123456789ABCDEFL, "failing compareAndExchange long value"); + assertEquals(0x0123456789ABCDEFL, x, "failing compareAndExchange long value"); } { long r = (long) vh.compareAndExchangeAcquire(0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); assertEquals(r, 0x0123456789ABCDEFL, "success compareAndExchangeAcquire long"); long x = (long) vh.get(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "success compareAndExchangeAcquire long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "success compareAndExchangeAcquire long value"); } { long r = (long) vh.compareAndExchangeAcquire(0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); assertEquals(r, 0xCAFEBABECAFEBABEL, "failing compareAndExchangeAcquire long"); long x = (long) vh.get(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "failing compareAndExchangeAcquire long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "failing compareAndExchangeAcquire long value"); } { long r = (long) vh.compareAndExchangeRelease(0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); assertEquals(r, 0xCAFEBABECAFEBABEL, "success compareAndExchangeRelease long"); long x = (long) vh.get(); - assertEquals(x, 0x0123456789ABCDEFL, "success compareAndExchangeRelease long value"); + assertEquals(0x0123456789ABCDEFL, x, "success compareAndExchangeRelease long value"); } { long r = (long) vh.compareAndExchangeRelease(0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); assertEquals(r, 0x0123456789ABCDEFL, "failing compareAndExchangeRelease long"); long x = (long) vh.get(); - assertEquals(x, 0x0123456789ABCDEFL, "failing compareAndExchangeRelease long value"); + assertEquals(0x0123456789ABCDEFL, x, "failing compareAndExchangeRelease long value"); } { @@ -796,14 +794,14 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain long"); long x = (long) vh.get(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "success weakCompareAndSetPlain long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "success weakCompareAndSetPlain long value"); } { boolean success = vh.weakCompareAndSetPlain(0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); assertEquals(success, false, "failing weakCompareAndSetPlain long"); long x = (long) vh.get(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "failing weakCompareAndSetPlain long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "failing weakCompareAndSetPlain long value"); } { @@ -814,14 +812,14 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire long"); long x = (long) vh.get(); - assertEquals(x, 0x0123456789ABCDEFL, "success weakCompareAndSetAcquire long"); + assertEquals(0x0123456789ABCDEFL, x, "success weakCompareAndSetAcquire long"); } { boolean success = vh.weakCompareAndSetAcquire(0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); assertEquals(success, false, "failing weakCompareAndSetAcquire long"); long x = (long) vh.get(); - assertEquals(x, 0x0123456789ABCDEFL, "failing weakCompareAndSetAcquire long value"); + assertEquals(0x0123456789ABCDEFL, x, "failing weakCompareAndSetAcquire long value"); } { @@ -832,14 +830,14 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease long"); long x = (long) vh.get(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "success weakCompareAndSetRelease long"); + assertEquals(0xCAFEBABECAFEBABEL, x, "success weakCompareAndSetRelease long"); } { boolean success = vh.weakCompareAndSetRelease(0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); assertEquals(success, false, "failing weakCompareAndSetRelease long"); long x = (long) vh.get(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "failing weakCompareAndSetRelease long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "failing weakCompareAndSetRelease long value"); } { @@ -850,14 +848,14 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet long"); long x = (long) vh.get(); - assertEquals(x, 0x0123456789ABCDEFL, "success weakCompareAndSet long"); + assertEquals(0x0123456789ABCDEFL, x, "success weakCompareAndSet long"); } { boolean success = vh.weakCompareAndSet(0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); assertEquals(success, false, "failing weakCompareAndSet long"); long x = (long) vh.get(); - assertEquals(x, 0x0123456789ABCDEFL, "failing weakCompareAndSet long value"); + assertEquals(0x0123456789ABCDEFL, x, "failing weakCompareAndSet long value"); } // Compare set and get @@ -865,27 +863,27 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { vh.set(0x0123456789ABCDEFL); long o = (long) vh.getAndSet(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndSet long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndSet long"); long x = (long) vh.get(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "getAndSet long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "getAndSet long value"); } { vh.set(0x0123456789ABCDEFL); long o = (long) vh.getAndSetAcquire(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndSetAcquire long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndSetAcquire long"); long x = (long) vh.get(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "getAndSetAcquire long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "getAndSetAcquire long value"); } { vh.set(0x0123456789ABCDEFL); long o = (long) vh.getAndSetRelease(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndSetRelease long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndSetRelease long"); long x = (long) vh.get(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "getAndSetRelease long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "getAndSetRelease long value"); } // get and add, add and get @@ -893,27 +891,27 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { vh.set(0x0123456789ABCDEFL); long o = (long) vh.getAndAdd(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndAdd long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndAdd long"); long x = (long) vh.get(); - assertEquals(x, (long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), "getAndAdd long value"); + assertEquals((long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), x, "getAndAdd long value"); } { vh.set(0x0123456789ABCDEFL); long o = (long) vh.getAndAddAcquire(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndAddAcquire long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndAddAcquire long"); long x = (long) vh.get(); - assertEquals(x, (long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), "getAndAddAcquire long value"); + assertEquals((long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), x, "getAndAddAcquire long value"); } { vh.set(0x0123456789ABCDEFL); long o = (long) vh.getAndAddRelease(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndAddReleaselong"); + assertEquals(0x0123456789ABCDEFL, o, "getAndAddReleaselong"); long x = (long) vh.get(); - assertEquals(x, (long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), "getAndAddRelease long value"); + assertEquals((long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), x, "getAndAddRelease long value"); } // get and bitwise or @@ -921,27 +919,27 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { vh.set(0x0123456789ABCDEFL); long o = (long) vh.getAndBitwiseOr(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseOr long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseOr long"); long x = (long) vh.get(); - assertEquals(x, (long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), "getAndBitwiseOr long value"); + assertEquals((long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), x, "getAndBitwiseOr long value"); } { vh.set(0x0123456789ABCDEFL); long o = (long) vh.getAndBitwiseOrAcquire(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseOrAcquire long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseOrAcquire long"); long x = (long) vh.get(); - assertEquals(x, (long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), "getAndBitwiseOrAcquire long value"); + assertEquals((long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), x, "getAndBitwiseOrAcquire long value"); } { vh.set(0x0123456789ABCDEFL); long o = (long) vh.getAndBitwiseOrRelease(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseOrRelease long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseOrRelease long"); long x = (long) vh.get(); - assertEquals(x, (long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), "getAndBitwiseOrRelease long value"); + assertEquals((long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), x, "getAndBitwiseOrRelease long value"); } // get and bitwise and @@ -949,27 +947,27 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { vh.set(0x0123456789ABCDEFL); long o = (long) vh.getAndBitwiseAnd(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseAnd long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseAnd long"); long x = (long) vh.get(); - assertEquals(x, (long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), "getAndBitwiseAnd long value"); + assertEquals((long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), x, "getAndBitwiseAnd long value"); } { vh.set(0x0123456789ABCDEFL); long o = (long) vh.getAndBitwiseAndAcquire(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseAndAcquire long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseAndAcquire long"); long x = (long) vh.get(); - assertEquals(x, (long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), "getAndBitwiseAndAcquire long value"); + assertEquals((long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), x, "getAndBitwiseAndAcquire long value"); } { vh.set(0x0123456789ABCDEFL); long o = (long) vh.getAndBitwiseAndRelease(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseAndRelease long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseAndRelease long"); long x = (long) vh.get(); - assertEquals(x, (long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), "getAndBitwiseAndRelease long value"); + assertEquals((long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), x, "getAndBitwiseAndRelease long value"); } // get and bitwise xor @@ -977,27 +975,27 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { vh.set(0x0123456789ABCDEFL); long o = (long) vh.getAndBitwiseXor(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseXor long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseXor long"); long x = (long) vh.get(); - assertEquals(x, (long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), "getAndBitwiseXor long value"); + assertEquals((long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), x, "getAndBitwiseXor long value"); } { vh.set(0x0123456789ABCDEFL); long o = (long) vh.getAndBitwiseXorAcquire(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseXorAcquire long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseXorAcquire long"); long x = (long) vh.get(); - assertEquals(x, (long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), "getAndBitwiseXorAcquire long value"); + assertEquals((long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), x, "getAndBitwiseXorAcquire long value"); } { vh.set(0x0123456789ABCDEFL); long o = (long) vh.getAndBitwiseXorRelease(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseXorRelease long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseXorRelease long"); long x = (long) vh.get(); - assertEquals(x, (long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), "getAndBitwiseXorRelease long value"); + assertEquals((long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), x, "getAndBitwiseXorRelease long value"); } } @@ -1015,7 +1013,7 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { { vh.set(array, i, 0x0123456789ABCDEFL); long x = (long) vh.get(array, i); - assertEquals(x, 0x0123456789ABCDEFL, "get long value"); + assertEquals(0x0123456789ABCDEFL, x, "get long value"); } @@ -1023,21 +1021,21 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { { vh.setVolatile(array, i, 0xCAFEBABECAFEBABEL); long x = (long) vh.getVolatile(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "setVolatile long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "setVolatile long value"); } // Lazy { vh.setRelease(array, i, 0x0123456789ABCDEFL); long x = (long) vh.getAcquire(array, i); - assertEquals(x, 0x0123456789ABCDEFL, "setRelease long value"); + assertEquals(0x0123456789ABCDEFL, x, "setRelease long value"); } // Opaque { vh.setOpaque(array, i, 0xCAFEBABECAFEBABEL); long x = (long) vh.getOpaque(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "setOpaque long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "setOpaque long value"); } vh.set(array, i, 0x0123456789ABCDEFL); @@ -1047,56 +1045,56 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { boolean r = vh.compareAndSet(array, i, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); assertEquals(r, true, "success compareAndSet long"); long x = (long) vh.get(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "success compareAndSet long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "success compareAndSet long value"); } { boolean r = vh.compareAndSet(array, i, 0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); assertEquals(r, false, "failing compareAndSet long"); long x = (long) vh.get(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "failing compareAndSet long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "failing compareAndSet long value"); } { long r = (long) vh.compareAndExchange(array, i, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); assertEquals(r, 0xCAFEBABECAFEBABEL, "success compareAndExchange long"); long x = (long) vh.get(array, i); - assertEquals(x, 0x0123456789ABCDEFL, "success compareAndExchange long value"); + assertEquals(0x0123456789ABCDEFL, x, "success compareAndExchange long value"); } { long r = (long) vh.compareAndExchange(array, i, 0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); assertEquals(r, 0x0123456789ABCDEFL, "failing compareAndExchange long"); long x = (long) vh.get(array, i); - assertEquals(x, 0x0123456789ABCDEFL, "failing compareAndExchange long value"); + assertEquals(0x0123456789ABCDEFL, x, "failing compareAndExchange long value"); } { long r = (long) vh.compareAndExchangeAcquire(array, i, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); assertEquals(r, 0x0123456789ABCDEFL, "success compareAndExchangeAcquire long"); long x = (long) vh.get(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "success compareAndExchangeAcquire long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "success compareAndExchangeAcquire long value"); } { long r = (long) vh.compareAndExchangeAcquire(array, i, 0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); assertEquals(r, 0xCAFEBABECAFEBABEL, "failing compareAndExchangeAcquire long"); long x = (long) vh.get(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "failing compareAndExchangeAcquire long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "failing compareAndExchangeAcquire long value"); } { long r = (long) vh.compareAndExchangeRelease(array, i, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); assertEquals(r, 0xCAFEBABECAFEBABEL, "success compareAndExchangeRelease long"); long x = (long) vh.get(array, i); - assertEquals(x, 0x0123456789ABCDEFL, "success compareAndExchangeRelease long value"); + assertEquals(0x0123456789ABCDEFL, x, "success compareAndExchangeRelease long value"); } { long r = (long) vh.compareAndExchangeRelease(array, i, 0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); assertEquals(r, 0x0123456789ABCDEFL, "failing compareAndExchangeRelease long"); long x = (long) vh.get(array, i); - assertEquals(x, 0x0123456789ABCDEFL, "failing compareAndExchangeRelease long value"); + assertEquals(0x0123456789ABCDEFL, x, "failing compareAndExchangeRelease long value"); } { @@ -1107,14 +1105,14 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain long"); long x = (long) vh.get(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "success weakCompareAndSetPlain long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "success weakCompareAndSetPlain long value"); } { boolean success = vh.weakCompareAndSetPlain(array, i, 0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); assertEquals(success, false, "failing weakCompareAndSetPlain long"); long x = (long) vh.get(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "failing weakCompareAndSetPlain long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "failing weakCompareAndSetPlain long value"); } { @@ -1125,14 +1123,14 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire long"); long x = (long) vh.get(array, i); - assertEquals(x, 0x0123456789ABCDEFL, "success weakCompareAndSetAcquire long"); + assertEquals(0x0123456789ABCDEFL, x, "success weakCompareAndSetAcquire long"); } { boolean success = vh.weakCompareAndSetAcquire(array, i, 0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); assertEquals(success, false, "failing weakCompareAndSetAcquire long"); long x = (long) vh.get(array, i); - assertEquals(x, 0x0123456789ABCDEFL, "failing weakCompareAndSetAcquire long value"); + assertEquals(0x0123456789ABCDEFL, x, "failing weakCompareAndSetAcquire long value"); } { @@ -1143,14 +1141,14 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease long"); long x = (long) vh.get(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "success weakCompareAndSetRelease long"); + assertEquals(0xCAFEBABECAFEBABEL, x, "success weakCompareAndSetRelease long"); } { boolean success = vh.weakCompareAndSetRelease(array, i, 0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); assertEquals(success, false, "failing weakCompareAndSetRelease long"); long x = (long) vh.get(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "failing weakCompareAndSetRelease long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "failing weakCompareAndSetRelease long value"); } { @@ -1161,14 +1159,14 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet long"); long x = (long) vh.get(array, i); - assertEquals(x, 0x0123456789ABCDEFL, "success weakCompareAndSet long"); + assertEquals(0x0123456789ABCDEFL, x, "success weakCompareAndSet long"); } { boolean success = vh.weakCompareAndSet(array, i, 0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); assertEquals(success, false, "failing weakCompareAndSet long"); long x = (long) vh.get(array, i); - assertEquals(x, 0x0123456789ABCDEFL, "failing weakCompareAndSet long value"); + assertEquals(0x0123456789ABCDEFL, x, "failing weakCompareAndSet long value"); } // Compare set and get @@ -1176,27 +1174,27 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { vh.set(array, i, 0x0123456789ABCDEFL); long o = (long) vh.getAndSet(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndSet long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndSet long"); long x = (long) vh.get(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "getAndSet long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "getAndSet long value"); } { vh.set(array, i, 0x0123456789ABCDEFL); long o = (long) vh.getAndSetAcquire(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndSetAcquire long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndSetAcquire long"); long x = (long) vh.get(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "getAndSetAcquire long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "getAndSetAcquire long value"); } { vh.set(array, i, 0x0123456789ABCDEFL); long o = (long) vh.getAndSetRelease(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndSetRelease long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndSetRelease long"); long x = (long) vh.get(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "getAndSetRelease long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "getAndSetRelease long value"); } // get and add, add and get @@ -1204,27 +1202,27 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { vh.set(array, i, 0x0123456789ABCDEFL); long o = (long) vh.getAndAdd(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndAdd long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndAdd long"); long x = (long) vh.get(array, i); - assertEquals(x, (long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), "getAndAdd long value"); + assertEquals((long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), x, "getAndAdd long value"); } { vh.set(array, i, 0x0123456789ABCDEFL); long o = (long) vh.getAndAddAcquire(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndAddAcquire long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndAddAcquire long"); long x = (long) vh.get(array, i); - assertEquals(x, (long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), "getAndAddAcquire long value"); + assertEquals((long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), x, "getAndAddAcquire long value"); } { vh.set(array, i, 0x0123456789ABCDEFL); long o = (long) vh.getAndAddRelease(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndAddReleaselong"); + assertEquals(0x0123456789ABCDEFL, o, "getAndAddReleaselong"); long x = (long) vh.get(array, i); - assertEquals(x, (long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), "getAndAddRelease long value"); + assertEquals((long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), x, "getAndAddRelease long value"); } // get and bitwise or @@ -1232,27 +1230,27 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { vh.set(array, i, 0x0123456789ABCDEFL); long o = (long) vh.getAndBitwiseOr(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseOr long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseOr long"); long x = (long) vh.get(array, i); - assertEquals(x, (long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), "getAndBitwiseOr long value"); + assertEquals((long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), x, "getAndBitwiseOr long value"); } { vh.set(array, i, 0x0123456789ABCDEFL); long o = (long) vh.getAndBitwiseOrAcquire(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseOrAcquire long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseOrAcquire long"); long x = (long) vh.get(array, i); - assertEquals(x, (long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), "getAndBitwiseOrAcquire long value"); + assertEquals((long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), x, "getAndBitwiseOrAcquire long value"); } { vh.set(array, i, 0x0123456789ABCDEFL); long o = (long) vh.getAndBitwiseOrRelease(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseOrRelease long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseOrRelease long"); long x = (long) vh.get(array, i); - assertEquals(x, (long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), "getAndBitwiseOrRelease long value"); + assertEquals((long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), x, "getAndBitwiseOrRelease long value"); } // get and bitwise and @@ -1260,27 +1258,27 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { vh.set(array, i, 0x0123456789ABCDEFL); long o = (long) vh.getAndBitwiseAnd(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseAnd long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseAnd long"); long x = (long) vh.get(array, i); - assertEquals(x, (long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), "getAndBitwiseAnd long value"); + assertEquals((long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), x, "getAndBitwiseAnd long value"); } { vh.set(array, i, 0x0123456789ABCDEFL); long o = (long) vh.getAndBitwiseAndAcquire(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseAndAcquire long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseAndAcquire long"); long x = (long) vh.get(array, i); - assertEquals(x, (long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), "getAndBitwiseAndAcquire long value"); + assertEquals((long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), x, "getAndBitwiseAndAcquire long value"); } { vh.set(array, i, 0x0123456789ABCDEFL); long o = (long) vh.getAndBitwiseAndRelease(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseAndRelease long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseAndRelease long"); long x = (long) vh.get(array, i); - assertEquals(x, (long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), "getAndBitwiseAndRelease long value"); + assertEquals((long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), x, "getAndBitwiseAndRelease long value"); } // get and bitwise xor @@ -1288,27 +1286,27 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { vh.set(array, i, 0x0123456789ABCDEFL); long o = (long) vh.getAndBitwiseXor(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseXor long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseXor long"); long x = (long) vh.get(array, i); - assertEquals(x, (long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), "getAndBitwiseXor long value"); + assertEquals((long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), x, "getAndBitwiseXor long value"); } { vh.set(array, i, 0x0123456789ABCDEFL); long o = (long) vh.getAndBitwiseXorAcquire(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseXorAcquire long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseXorAcquire long"); long x = (long) vh.get(array, i); - assertEquals(x, (long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), "getAndBitwiseXorAcquire long value"); + assertEquals((long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), x, "getAndBitwiseXorAcquire long value"); } { vh.set(array, i, 0x0123456789ABCDEFL); long o = (long) vh.getAndBitwiseXorRelease(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseXorRelease long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseXorRelease long"); long x = (long) vh.get(array, i); - assertEquals(x, (long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), "getAndBitwiseXorRelease long value"); + assertEquals((long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), x, "getAndBitwiseXorRelease long value"); } } } diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessModeMethodNames.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessModeMethodNames.java index 3365bd923bc..61fc8a53fd0 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessModeMethodNames.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessModeMethodNames.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,32 +23,34 @@ /* * @test - * @run testng VarHandleTestAccessModeMethodNames + * @run junit VarHandleTestAccessModeMethodNames * @modules java.base/java.lang.invoke:open */ -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import java.lang.invoke.VarHandle; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.stream.Stream; -import static org.testng.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestAccessModeMethodNames { - @DataProvider public static Object[][] accessModesProvider() { return Stream.of(VarHandle.AccessMode.values()). map(am -> new Object[]{am}). toArray(Object[][]::new); } - @Test(dataProvider = "accessModesProvider") + @ParameterizedTest + @MethodSource("accessModesProvider") public void testMethodName(VarHandle.AccessMode am) { - assertEquals(am.methodName(), toMethodName(am.name())); + assertEquals(toMethodName(am.name()), am.methodName()); } private static String toMethodName(String name) { @@ -62,9 +64,10 @@ public class VarHandleTestAccessModeMethodNames { } - @Test(dataProvider = "accessModesProvider") + @ParameterizedTest + @MethodSource("accessModesProvider") public void testReturnType(VarHandle.AccessMode am) throws Exception { - assertEquals(getReturnType(am.methodName()), getAccessModeReturnType(am)); + assertEquals(getAccessModeReturnType(am), getReturnType(am.methodName())); } private static Class getReturnType(String name) throws Exception { diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java index b9daf4880a0..552672c7372 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,28 +23,30 @@ /* * @test - * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessShort + * @run junit/othervm -Diters=10 -Xint VarHandleTestAccessShort * * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations * to hit compilation thresholds * - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestAccessShort - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestAccessShort - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestAccessShort + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestAccessShort + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestAccessShort + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestAccessShort */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestAccessShort extends VarHandleBaseTest { static final short static_final_v = (short)0x0123; @@ -108,7 +110,7 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { return vhs.toArray(new VarHandle[0]); } - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestAccessShort.class, "final_v", short.class); @@ -125,8 +127,6 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { vhArray = MethodHandles.arrayElementVarHandle(short[].class); } - - @DataProvider public Object[][] varHandlesProvider() throws Exception { List vhs = new ArrayList<>(); vhs.add(vhField); @@ -156,7 +156,8 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { } } - @Test(dataProvider = "varHandlesProvider") + @ParameterizedTest + @MethodSource("varHandlesProvider") public void testIsAccessModeSupported(VarHandle vh) { assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET)); @@ -194,8 +195,6 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE)); } - - @DataProvider public Object[][] typesProvider() throws Exception { List types = new ArrayList<>(); types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessShort.class)}); @@ -205,16 +204,16 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { return types.stream().toArray(Object[][]::new); } - @Test(dataProvider = "typesProvider") + @ParameterizedTest + @MethodSource("typesProvider") public void testTypes(VarHandle vh, List> pts) { - assertEquals(vh.varType(), short.class); + assertEquals(short.class, vh.varType()); - assertEquals(vh.coordinateTypes(), pts); + assertEquals(pts, vh.coordinateTypes()); testTypes(vh); } - @Test public void testLookupInstanceToStatic() { checkIAE("Lookup of static final field to instance final field", () -> { @@ -241,8 +240,6 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { }); } - - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -284,7 +281,8 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -297,26 +295,26 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { // Plain { short x = (short) vh.get(recv); - assertEquals(x, (short)0x0123, "get short value"); + assertEquals((short)0x0123, x, "get short value"); } // Volatile { short x = (short) vh.getVolatile(recv); - assertEquals(x, (short)0x0123, "getVolatile short value"); + assertEquals((short)0x0123, x, "getVolatile short value"); } // Lazy { short x = (short) vh.getAcquire(recv); - assertEquals(x, (short)0x0123, "getRelease short value"); + assertEquals((short)0x0123, x, "getRelease short value"); } // Opaque { short x = (short) vh.getOpaque(recv); - assertEquals(x, (short)0x0123, "getOpaque short value"); + assertEquals((short)0x0123, x, "getOpaque short value"); } } @@ -346,26 +344,26 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { // Plain { short x = (short) vh.get(); - assertEquals(x, (short)0x0123, "get short value"); + assertEquals((short)0x0123, x, "get short value"); } // Volatile { short x = (short) vh.getVolatile(); - assertEquals(x, (short)0x0123, "getVolatile short value"); + assertEquals((short)0x0123, x, "getVolatile short value"); } // Lazy { short x = (short) vh.getAcquire(); - assertEquals(x, (short)0x0123, "getRelease short value"); + assertEquals((short)0x0123, x, "getRelease short value"); } // Opaque { short x = (short) vh.getOpaque(); - assertEquals(x, (short)0x0123, "getOpaque short value"); + assertEquals((short)0x0123, x, "getOpaque short value"); } } @@ -396,7 +394,7 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { { vh.set(recv, (short)0x0123); short x = (short) vh.get(recv); - assertEquals(x, (short)0x0123, "set short value"); + assertEquals((short)0x0123, x, "set short value"); } @@ -404,21 +402,21 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { { vh.setVolatile(recv, (short)0x4567); short x = (short) vh.getVolatile(recv); - assertEquals(x, (short)0x4567, "setVolatile short value"); + assertEquals((short)0x4567, x, "setVolatile short value"); } // Lazy { vh.setRelease(recv, (short)0x0123); short x = (short) vh.getAcquire(recv); - assertEquals(x, (short)0x0123, "setRelease short value"); + assertEquals((short)0x0123, x, "setRelease short value"); } // Opaque { vh.setOpaque(recv, (short)0x4567); short x = (short) vh.getOpaque(recv); - assertEquals(x, (short)0x4567, "setOpaque short value"); + assertEquals((short)0x4567, x, "setOpaque short value"); } vh.set(recv, (short)0x0123); @@ -428,56 +426,56 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { boolean r = vh.compareAndSet(recv, (short)0x0123, (short)0x4567); assertEquals(r, true, "success compareAndSet short"); short x = (short) vh.get(recv); - assertEquals(x, (short)0x4567, "success compareAndSet short value"); + assertEquals((short)0x4567, x, "success compareAndSet short value"); } { boolean r = vh.compareAndSet(recv, (short)0x0123, (short)0x89AB); assertEquals(r, false, "failing compareAndSet short"); short x = (short) vh.get(recv); - assertEquals(x, (short)0x4567, "failing compareAndSet short value"); + assertEquals((short)0x4567, x, "failing compareAndSet short value"); } { short r = (short) vh.compareAndExchange(recv, (short)0x4567, (short)0x0123); assertEquals(r, (short)0x4567, "success compareAndExchange short"); short x = (short) vh.get(recv); - assertEquals(x, (short)0x0123, "success compareAndExchange short value"); + assertEquals((short)0x0123, x, "success compareAndExchange short value"); } { short r = (short) vh.compareAndExchange(recv, (short)0x4567, (short)0x89AB); assertEquals(r, (short)0x0123, "failing compareAndExchange short"); short x = (short) vh.get(recv); - assertEquals(x, (short)0x0123, "failing compareAndExchange short value"); + assertEquals((short)0x0123, x, "failing compareAndExchange short value"); } { short r = (short) vh.compareAndExchangeAcquire(recv, (short)0x0123, (short)0x4567); assertEquals(r, (short)0x0123, "success compareAndExchangeAcquire short"); short x = (short) vh.get(recv); - assertEquals(x, (short)0x4567, "success compareAndExchangeAcquire short value"); + assertEquals((short)0x4567, x, "success compareAndExchangeAcquire short value"); } { short r = (short) vh.compareAndExchangeAcquire(recv, (short)0x0123, (short)0x89AB); assertEquals(r, (short)0x4567, "failing compareAndExchangeAcquire short"); short x = (short) vh.get(recv); - assertEquals(x, (short)0x4567, "failing compareAndExchangeAcquire short value"); + assertEquals((short)0x4567, x, "failing compareAndExchangeAcquire short value"); } { short r = (short) vh.compareAndExchangeRelease(recv, (short)0x4567, (short)0x0123); assertEquals(r, (short)0x4567, "success compareAndExchangeRelease short"); short x = (short) vh.get(recv); - assertEquals(x, (short)0x0123, "success compareAndExchangeRelease short value"); + assertEquals((short)0x0123, x, "success compareAndExchangeRelease short value"); } { short r = (short) vh.compareAndExchangeRelease(recv, (short)0x4567, (short)0x89AB); assertEquals(r, (short)0x0123, "failing compareAndExchangeRelease short"); short x = (short) vh.get(recv); - assertEquals(x, (short)0x0123, "failing compareAndExchangeRelease short value"); + assertEquals((short)0x0123, x, "failing compareAndExchangeRelease short value"); } { @@ -488,14 +486,14 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain short"); short x = (short) vh.get(recv); - assertEquals(x, (short)0x4567, "success weakCompareAndSetPlain short value"); + assertEquals((short)0x4567, x, "success weakCompareAndSetPlain short value"); } { boolean success = vh.weakCompareAndSetPlain(recv, (short)0x0123, (short)0x89AB); assertEquals(success, false, "failing weakCompareAndSetPlain short"); short x = (short) vh.get(recv); - assertEquals(x, (short)0x4567, "failing weakCompareAndSetPlain short value"); + assertEquals((short)0x4567, x, "failing weakCompareAndSetPlain short value"); } { @@ -506,14 +504,14 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire short"); short x = (short) vh.get(recv); - assertEquals(x, (short)0x0123, "success weakCompareAndSetAcquire short"); + assertEquals((short)0x0123, x, "success weakCompareAndSetAcquire short"); } { boolean success = vh.weakCompareAndSetAcquire(recv, (short)0x4567, (short)0x89AB); assertEquals(success, false, "failing weakCompareAndSetAcquire short"); short x = (short) vh.get(recv); - assertEquals(x, (short)0x0123, "failing weakCompareAndSetAcquire short value"); + assertEquals((short)0x0123, x, "failing weakCompareAndSetAcquire short value"); } { @@ -524,14 +522,14 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease short"); short x = (short) vh.get(recv); - assertEquals(x, (short)0x4567, "success weakCompareAndSetRelease short"); + assertEquals((short)0x4567, x, "success weakCompareAndSetRelease short"); } { boolean success = vh.weakCompareAndSetRelease(recv, (short)0x0123, (short)0x89AB); assertEquals(success, false, "failing weakCompareAndSetRelease short"); short x = (short) vh.get(recv); - assertEquals(x, (short)0x4567, "failing weakCompareAndSetRelease short value"); + assertEquals((short)0x4567, x, "failing weakCompareAndSetRelease short value"); } { @@ -542,14 +540,14 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet short"); short x = (short) vh.get(recv); - assertEquals(x, (short)0x0123, "success weakCompareAndSet short value"); + assertEquals((short)0x0123, x, "success weakCompareAndSet short value"); } { boolean success = vh.weakCompareAndSet(recv, (short)0x4567, (short)0x89AB); assertEquals(success, false, "failing weakCompareAndSet short"); short x = (short) vh.get(recv); - assertEquals(x, (short)0x0123, "failing weakCompareAndSet short value"); + assertEquals((short)0x0123, x, "failing weakCompareAndSet short value"); } // Compare set and get @@ -557,27 +555,27 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { vh.set(recv, (short)0x0123); short o = (short) vh.getAndSet(recv, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndSet short"); + assertEquals((short)0x0123, o, "getAndSet short"); short x = (short) vh.get(recv); - assertEquals(x, (short)0x4567, "getAndSet short value"); + assertEquals((short)0x4567, x, "getAndSet short value"); } { vh.set(recv, (short)0x0123); short o = (short) vh.getAndSetAcquire(recv, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndSetAcquire short"); + assertEquals((short)0x0123, o, "getAndSetAcquire short"); short x = (short) vh.get(recv); - assertEquals(x, (short)0x4567, "getAndSetAcquire short value"); + assertEquals((short)0x4567, x, "getAndSetAcquire short value"); } { vh.set(recv, (short)0x0123); short o = (short) vh.getAndSetRelease(recv, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndSetRelease short"); + assertEquals((short)0x0123, o, "getAndSetRelease short"); short x = (short) vh.get(recv); - assertEquals(x, (short)0x4567, "getAndSetRelease short value"); + assertEquals((short)0x4567, x, "getAndSetRelease short value"); } // get and add, add and get @@ -585,27 +583,27 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { vh.set(recv, (short)0x0123); short o = (short) vh.getAndAdd(recv, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndAdd short"); + assertEquals((short)0x0123, o, "getAndAdd short"); short x = (short) vh.get(recv); - assertEquals(x, (short)((short)0x0123 + (short)0x4567), "getAndAdd short value"); + assertEquals((short)((short)0x0123 + (short)0x4567), x, "getAndAdd short value"); } { vh.set(recv, (short)0x0123); short o = (short) vh.getAndAddAcquire(recv, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndAddAcquire short"); + assertEquals((short)0x0123, o, "getAndAddAcquire short"); short x = (short) vh.get(recv); - assertEquals(x, (short)((short)0x0123 + (short)0x4567), "getAndAddAcquire short value"); + assertEquals((short)((short)0x0123 + (short)0x4567), x, "getAndAddAcquire short value"); } { vh.set(recv, (short)0x0123); short o = (short) vh.getAndAddRelease(recv, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndAddReleaseshort"); + assertEquals((short)0x0123, o, "getAndAddReleaseshort"); short x = (short) vh.get(recv); - assertEquals(x, (short)((short)0x0123 + (short)0x4567), "getAndAddRelease short value"); + assertEquals((short)((short)0x0123 + (short)0x4567), x, "getAndAddRelease short value"); } // get and bitwise or @@ -613,27 +611,27 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { vh.set(recv, (short)0x0123); short o = (short) vh.getAndBitwiseOr(recv, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseOr short"); + assertEquals((short)0x0123, o, "getAndBitwiseOr short"); short x = (short) vh.get(recv); - assertEquals(x, (short)((short)0x0123 | (short)0x4567), "getAndBitwiseOr short value"); + assertEquals((short)((short)0x0123 | (short)0x4567), x, "getAndBitwiseOr short value"); } { vh.set(recv, (short)0x0123); short o = (short) vh.getAndBitwiseOrAcquire(recv, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseOrAcquire short"); + assertEquals((short)0x0123, o, "getAndBitwiseOrAcquire short"); short x = (short) vh.get(recv); - assertEquals(x, (short)((short)0x0123 | (short)0x4567), "getAndBitwiseOrAcquire short value"); + assertEquals((short)((short)0x0123 | (short)0x4567), x, "getAndBitwiseOrAcquire short value"); } { vh.set(recv, (short)0x0123); short o = (short) vh.getAndBitwiseOrRelease(recv, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseOrRelease short"); + assertEquals((short)0x0123, o, "getAndBitwiseOrRelease short"); short x = (short) vh.get(recv); - assertEquals(x, (short)((short)0x0123 | (short)0x4567), "getAndBitwiseOrRelease short value"); + assertEquals((short)((short)0x0123 | (short)0x4567), x, "getAndBitwiseOrRelease short value"); } // get and bitwise and @@ -641,27 +639,27 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { vh.set(recv, (short)0x0123); short o = (short) vh.getAndBitwiseAnd(recv, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseAnd short"); + assertEquals((short)0x0123, o, "getAndBitwiseAnd short"); short x = (short) vh.get(recv); - assertEquals(x, (short)((short)0x0123 & (short)0x4567), "getAndBitwiseAnd short value"); + assertEquals((short)((short)0x0123 & (short)0x4567), x, "getAndBitwiseAnd short value"); } { vh.set(recv, (short)0x0123); short o = (short) vh.getAndBitwiseAndAcquire(recv, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseAndAcquire short"); + assertEquals((short)0x0123, o, "getAndBitwiseAndAcquire short"); short x = (short) vh.get(recv); - assertEquals(x, (short)((short)0x0123 & (short)0x4567), "getAndBitwiseAndAcquire short value"); + assertEquals((short)((short)0x0123 & (short)0x4567), x, "getAndBitwiseAndAcquire short value"); } { vh.set(recv, (short)0x0123); short o = (short) vh.getAndBitwiseAndRelease(recv, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseAndRelease short"); + assertEquals((short)0x0123, o, "getAndBitwiseAndRelease short"); short x = (short) vh.get(recv); - assertEquals(x, (short)((short)0x0123 & (short)0x4567), "getAndBitwiseAndRelease short value"); + assertEquals((short)((short)0x0123 & (short)0x4567), x, "getAndBitwiseAndRelease short value"); } // get and bitwise xor @@ -669,27 +667,27 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { vh.set(recv, (short)0x0123); short o = (short) vh.getAndBitwiseXor(recv, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseXor short"); + assertEquals((short)0x0123, o, "getAndBitwiseXor short"); short x = (short) vh.get(recv); - assertEquals(x, (short)((short)0x0123 ^ (short)0x4567), "getAndBitwiseXor short value"); + assertEquals((short)((short)0x0123 ^ (short)0x4567), x, "getAndBitwiseXor short value"); } { vh.set(recv, (short)0x0123); short o = (short) vh.getAndBitwiseXorAcquire(recv, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseXorAcquire short"); + assertEquals((short)0x0123, o, "getAndBitwiseXorAcquire short"); short x = (short) vh.get(recv); - assertEquals(x, (short)((short)0x0123 ^ (short)0x4567), "getAndBitwiseXorAcquire short value"); + assertEquals((short)((short)0x0123 ^ (short)0x4567), x, "getAndBitwiseXorAcquire short value"); } { vh.set(recv, (short)0x0123); short o = (short) vh.getAndBitwiseXorRelease(recv, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseXorRelease short"); + assertEquals((short)0x0123, o, "getAndBitwiseXorRelease short"); short x = (short) vh.get(recv); - assertEquals(x, (short)((short)0x0123 ^ (short)0x4567), "getAndBitwiseXorRelease short value"); + assertEquals((short)((short)0x0123 ^ (short)0x4567), x, "getAndBitwiseXorRelease short value"); } } @@ -704,7 +702,7 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { { vh.set((short)0x0123); short x = (short) vh.get(); - assertEquals(x, (short)0x0123, "set short value"); + assertEquals((short)0x0123, x, "set short value"); } @@ -712,21 +710,21 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { { vh.setVolatile((short)0x4567); short x = (short) vh.getVolatile(); - assertEquals(x, (short)0x4567, "setVolatile short value"); + assertEquals((short)0x4567, x, "setVolatile short value"); } // Lazy { vh.setRelease((short)0x0123); short x = (short) vh.getAcquire(); - assertEquals(x, (short)0x0123, "setRelease short value"); + assertEquals((short)0x0123, x, "setRelease short value"); } // Opaque { vh.setOpaque((short)0x4567); short x = (short) vh.getOpaque(); - assertEquals(x, (short)0x4567, "setOpaque short value"); + assertEquals((short)0x4567, x, "setOpaque short value"); } vh.set((short)0x0123); @@ -736,56 +734,56 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { boolean r = vh.compareAndSet((short)0x0123, (short)0x4567); assertEquals(r, true, "success compareAndSet short"); short x = (short) vh.get(); - assertEquals(x, (short)0x4567, "success compareAndSet short value"); + assertEquals((short)0x4567, x, "success compareAndSet short value"); } { boolean r = vh.compareAndSet((short)0x0123, (short)0x89AB); assertEquals(r, false, "failing compareAndSet short"); short x = (short) vh.get(); - assertEquals(x, (short)0x4567, "failing compareAndSet short value"); + assertEquals((short)0x4567, x, "failing compareAndSet short value"); } { short r = (short) vh.compareAndExchange((short)0x4567, (short)0x0123); assertEquals(r, (short)0x4567, "success compareAndExchange short"); short x = (short) vh.get(); - assertEquals(x, (short)0x0123, "success compareAndExchange short value"); + assertEquals((short)0x0123, x, "success compareAndExchange short value"); } { short r = (short) vh.compareAndExchange((short)0x4567, (short)0x89AB); assertEquals(r, (short)0x0123, "failing compareAndExchange short"); short x = (short) vh.get(); - assertEquals(x, (short)0x0123, "failing compareAndExchange short value"); + assertEquals((short)0x0123, x, "failing compareAndExchange short value"); } { short r = (short) vh.compareAndExchangeAcquire((short)0x0123, (short)0x4567); assertEquals(r, (short)0x0123, "success compareAndExchangeAcquire short"); short x = (short) vh.get(); - assertEquals(x, (short)0x4567, "success compareAndExchangeAcquire short value"); + assertEquals((short)0x4567, x, "success compareAndExchangeAcquire short value"); } { short r = (short) vh.compareAndExchangeAcquire((short)0x0123, (short)0x89AB); assertEquals(r, (short)0x4567, "failing compareAndExchangeAcquire short"); short x = (short) vh.get(); - assertEquals(x, (short)0x4567, "failing compareAndExchangeAcquire short value"); + assertEquals((short)0x4567, x, "failing compareAndExchangeAcquire short value"); } { short r = (short) vh.compareAndExchangeRelease((short)0x4567, (short)0x0123); assertEquals(r, (short)0x4567, "success compareAndExchangeRelease short"); short x = (short) vh.get(); - assertEquals(x, (short)0x0123, "success compareAndExchangeRelease short value"); + assertEquals((short)0x0123, x, "success compareAndExchangeRelease short value"); } { short r = (short) vh.compareAndExchangeRelease((short)0x4567, (short)0x89AB); assertEquals(r, (short)0x0123, "failing compareAndExchangeRelease short"); short x = (short) vh.get(); - assertEquals(x, (short)0x0123, "failing compareAndExchangeRelease short value"); + assertEquals((short)0x0123, x, "failing compareAndExchangeRelease short value"); } { @@ -796,14 +794,14 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain short"); short x = (short) vh.get(); - assertEquals(x, (short)0x4567, "success weakCompareAndSetPlain short value"); + assertEquals((short)0x4567, x, "success weakCompareAndSetPlain short value"); } { boolean success = vh.weakCompareAndSetPlain((short)0x0123, (short)0x89AB); assertEquals(success, false, "failing weakCompareAndSetPlain short"); short x = (short) vh.get(); - assertEquals(x, (short)0x4567, "failing weakCompareAndSetPlain short value"); + assertEquals((short)0x4567, x, "failing weakCompareAndSetPlain short value"); } { @@ -814,14 +812,14 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire short"); short x = (short) vh.get(); - assertEquals(x, (short)0x0123, "success weakCompareAndSetAcquire short"); + assertEquals((short)0x0123, x, "success weakCompareAndSetAcquire short"); } { boolean success = vh.weakCompareAndSetAcquire((short)0x4567, (short)0x89AB); assertEquals(success, false, "failing weakCompareAndSetAcquire short"); short x = (short) vh.get(); - assertEquals(x, (short)0x0123, "failing weakCompareAndSetAcquire short value"); + assertEquals((short)0x0123, x, "failing weakCompareAndSetAcquire short value"); } { @@ -832,14 +830,14 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease short"); short x = (short) vh.get(); - assertEquals(x, (short)0x4567, "success weakCompareAndSetRelease short"); + assertEquals((short)0x4567, x, "success weakCompareAndSetRelease short"); } { boolean success = vh.weakCompareAndSetRelease((short)0x0123, (short)0x89AB); assertEquals(success, false, "failing weakCompareAndSetRelease short"); short x = (short) vh.get(); - assertEquals(x, (short)0x4567, "failing weakCompareAndSetRelease short value"); + assertEquals((short)0x4567, x, "failing weakCompareAndSetRelease short value"); } { @@ -850,14 +848,14 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet short"); short x = (short) vh.get(); - assertEquals(x, (short)0x0123, "success weakCompareAndSet short"); + assertEquals((short)0x0123, x, "success weakCompareAndSet short"); } { boolean success = vh.weakCompareAndSet((short)0x4567, (short)0x89AB); assertEquals(success, false, "failing weakCompareAndSet short"); short x = (short) vh.get(); - assertEquals(x, (short)0x0123, "failing weakCompareAndSet short value"); + assertEquals((short)0x0123, x, "failing weakCompareAndSet short value"); } // Compare set and get @@ -865,27 +863,27 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { vh.set((short)0x0123); short o = (short) vh.getAndSet((short)0x4567); - assertEquals(o, (short)0x0123, "getAndSet short"); + assertEquals((short)0x0123, o, "getAndSet short"); short x = (short) vh.get(); - assertEquals(x, (short)0x4567, "getAndSet short value"); + assertEquals((short)0x4567, x, "getAndSet short value"); } { vh.set((short)0x0123); short o = (short) vh.getAndSetAcquire((short)0x4567); - assertEquals(o, (short)0x0123, "getAndSetAcquire short"); + assertEquals((short)0x0123, o, "getAndSetAcquire short"); short x = (short) vh.get(); - assertEquals(x, (short)0x4567, "getAndSetAcquire short value"); + assertEquals((short)0x4567, x, "getAndSetAcquire short value"); } { vh.set((short)0x0123); short o = (short) vh.getAndSetRelease((short)0x4567); - assertEquals(o, (short)0x0123, "getAndSetRelease short"); + assertEquals((short)0x0123, o, "getAndSetRelease short"); short x = (short) vh.get(); - assertEquals(x, (short)0x4567, "getAndSetRelease short value"); + assertEquals((short)0x4567, x, "getAndSetRelease short value"); } // get and add, add and get @@ -893,27 +891,27 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { vh.set((short)0x0123); short o = (short) vh.getAndAdd((short)0x4567); - assertEquals(o, (short)0x0123, "getAndAdd short"); + assertEquals((short)0x0123, o, "getAndAdd short"); short x = (short) vh.get(); - assertEquals(x, (short)((short)0x0123 + (short)0x4567), "getAndAdd short value"); + assertEquals((short)((short)0x0123 + (short)0x4567), x, "getAndAdd short value"); } { vh.set((short)0x0123); short o = (short) vh.getAndAddAcquire((short)0x4567); - assertEquals(o, (short)0x0123, "getAndAddAcquire short"); + assertEquals((short)0x0123, o, "getAndAddAcquire short"); short x = (short) vh.get(); - assertEquals(x, (short)((short)0x0123 + (short)0x4567), "getAndAddAcquire short value"); + assertEquals((short)((short)0x0123 + (short)0x4567), x, "getAndAddAcquire short value"); } { vh.set((short)0x0123); short o = (short) vh.getAndAddRelease((short)0x4567); - assertEquals(o, (short)0x0123, "getAndAddReleaseshort"); + assertEquals((short)0x0123, o, "getAndAddReleaseshort"); short x = (short) vh.get(); - assertEquals(x, (short)((short)0x0123 + (short)0x4567), "getAndAddRelease short value"); + assertEquals((short)((short)0x0123 + (short)0x4567), x, "getAndAddRelease short value"); } // get and bitwise or @@ -921,27 +919,27 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { vh.set((short)0x0123); short o = (short) vh.getAndBitwiseOr((short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseOr short"); + assertEquals((short)0x0123, o, "getAndBitwiseOr short"); short x = (short) vh.get(); - assertEquals(x, (short)((short)0x0123 | (short)0x4567), "getAndBitwiseOr short value"); + assertEquals((short)((short)0x0123 | (short)0x4567), x, "getAndBitwiseOr short value"); } { vh.set((short)0x0123); short o = (short) vh.getAndBitwiseOrAcquire((short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseOrAcquire short"); + assertEquals((short)0x0123, o, "getAndBitwiseOrAcquire short"); short x = (short) vh.get(); - assertEquals(x, (short)((short)0x0123 | (short)0x4567), "getAndBitwiseOrAcquire short value"); + assertEquals((short)((short)0x0123 | (short)0x4567), x, "getAndBitwiseOrAcquire short value"); } { vh.set((short)0x0123); short o = (short) vh.getAndBitwiseOrRelease((short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseOrRelease short"); + assertEquals((short)0x0123, o, "getAndBitwiseOrRelease short"); short x = (short) vh.get(); - assertEquals(x, (short)((short)0x0123 | (short)0x4567), "getAndBitwiseOrRelease short value"); + assertEquals((short)((short)0x0123 | (short)0x4567), x, "getAndBitwiseOrRelease short value"); } // get and bitwise and @@ -949,27 +947,27 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { vh.set((short)0x0123); short o = (short) vh.getAndBitwiseAnd((short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseAnd short"); + assertEquals((short)0x0123, o, "getAndBitwiseAnd short"); short x = (short) vh.get(); - assertEquals(x, (short)((short)0x0123 & (short)0x4567), "getAndBitwiseAnd short value"); + assertEquals((short)((short)0x0123 & (short)0x4567), x, "getAndBitwiseAnd short value"); } { vh.set((short)0x0123); short o = (short) vh.getAndBitwiseAndAcquire((short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseAndAcquire short"); + assertEquals((short)0x0123, o, "getAndBitwiseAndAcquire short"); short x = (short) vh.get(); - assertEquals(x, (short)((short)0x0123 & (short)0x4567), "getAndBitwiseAndAcquire short value"); + assertEquals((short)((short)0x0123 & (short)0x4567), x, "getAndBitwiseAndAcquire short value"); } { vh.set((short)0x0123); short o = (short) vh.getAndBitwiseAndRelease((short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseAndRelease short"); + assertEquals((short)0x0123, o, "getAndBitwiseAndRelease short"); short x = (short) vh.get(); - assertEquals(x, (short)((short)0x0123 & (short)0x4567), "getAndBitwiseAndRelease short value"); + assertEquals((short)((short)0x0123 & (short)0x4567), x, "getAndBitwiseAndRelease short value"); } // get and bitwise xor @@ -977,27 +975,27 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { vh.set((short)0x0123); short o = (short) vh.getAndBitwiseXor((short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseXor short"); + assertEquals((short)0x0123, o, "getAndBitwiseXor short"); short x = (short) vh.get(); - assertEquals(x, (short)((short)0x0123 ^ (short)0x4567), "getAndBitwiseXor short value"); + assertEquals((short)((short)0x0123 ^ (short)0x4567), x, "getAndBitwiseXor short value"); } { vh.set((short)0x0123); short o = (short) vh.getAndBitwiseXorAcquire((short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseXorAcquire short"); + assertEquals((short)0x0123, o, "getAndBitwiseXorAcquire short"); short x = (short) vh.get(); - assertEquals(x, (short)((short)0x0123 ^ (short)0x4567), "getAndBitwiseXorAcquire short value"); + assertEquals((short)((short)0x0123 ^ (short)0x4567), x, "getAndBitwiseXorAcquire short value"); } { vh.set((short)0x0123); short o = (short) vh.getAndBitwiseXorRelease((short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseXorRelease short"); + assertEquals((short)0x0123, o, "getAndBitwiseXorRelease short"); short x = (short) vh.get(); - assertEquals(x, (short)((short)0x0123 ^ (short)0x4567), "getAndBitwiseXorRelease short value"); + assertEquals((short)((short)0x0123 ^ (short)0x4567), x, "getAndBitwiseXorRelease short value"); } } @@ -1015,7 +1013,7 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { { vh.set(array, i, (short)0x0123); short x = (short) vh.get(array, i); - assertEquals(x, (short)0x0123, "get short value"); + assertEquals((short)0x0123, x, "get short value"); } @@ -1023,21 +1021,21 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { { vh.setVolatile(array, i, (short)0x4567); short x = (short) vh.getVolatile(array, i); - assertEquals(x, (short)0x4567, "setVolatile short value"); + assertEquals((short)0x4567, x, "setVolatile short value"); } // Lazy { vh.setRelease(array, i, (short)0x0123); short x = (short) vh.getAcquire(array, i); - assertEquals(x, (short)0x0123, "setRelease short value"); + assertEquals((short)0x0123, x, "setRelease short value"); } // Opaque { vh.setOpaque(array, i, (short)0x4567); short x = (short) vh.getOpaque(array, i); - assertEquals(x, (short)0x4567, "setOpaque short value"); + assertEquals((short)0x4567, x, "setOpaque short value"); } vh.set(array, i, (short)0x0123); @@ -1047,56 +1045,56 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { boolean r = vh.compareAndSet(array, i, (short)0x0123, (short)0x4567); assertEquals(r, true, "success compareAndSet short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)0x4567, "success compareAndSet short value"); + assertEquals((short)0x4567, x, "success compareAndSet short value"); } { boolean r = vh.compareAndSet(array, i, (short)0x0123, (short)0x89AB); assertEquals(r, false, "failing compareAndSet short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)0x4567, "failing compareAndSet short value"); + assertEquals((short)0x4567, x, "failing compareAndSet short value"); } { short r = (short) vh.compareAndExchange(array, i, (short)0x4567, (short)0x0123); assertEquals(r, (short)0x4567, "success compareAndExchange short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)0x0123, "success compareAndExchange short value"); + assertEquals((short)0x0123, x, "success compareAndExchange short value"); } { short r = (short) vh.compareAndExchange(array, i, (short)0x4567, (short)0x89AB); assertEquals(r, (short)0x0123, "failing compareAndExchange short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)0x0123, "failing compareAndExchange short value"); + assertEquals((short)0x0123, x, "failing compareAndExchange short value"); } { short r = (short) vh.compareAndExchangeAcquire(array, i, (short)0x0123, (short)0x4567); assertEquals(r, (short)0x0123, "success compareAndExchangeAcquire short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)0x4567, "success compareAndExchangeAcquire short value"); + assertEquals((short)0x4567, x, "success compareAndExchangeAcquire short value"); } { short r = (short) vh.compareAndExchangeAcquire(array, i, (short)0x0123, (short)0x89AB); assertEquals(r, (short)0x4567, "failing compareAndExchangeAcquire short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)0x4567, "failing compareAndExchangeAcquire short value"); + assertEquals((short)0x4567, x, "failing compareAndExchangeAcquire short value"); } { short r = (short) vh.compareAndExchangeRelease(array, i, (short)0x4567, (short)0x0123); assertEquals(r, (short)0x4567, "success compareAndExchangeRelease short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)0x0123, "success compareAndExchangeRelease short value"); + assertEquals((short)0x0123, x, "success compareAndExchangeRelease short value"); } { short r = (short) vh.compareAndExchangeRelease(array, i, (short)0x4567, (short)0x89AB); assertEquals(r, (short)0x0123, "failing compareAndExchangeRelease short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)0x0123, "failing compareAndExchangeRelease short value"); + assertEquals((short)0x0123, x, "failing compareAndExchangeRelease short value"); } { @@ -1107,14 +1105,14 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)0x4567, "success weakCompareAndSetPlain short value"); + assertEquals((short)0x4567, x, "success weakCompareAndSetPlain short value"); } { boolean success = vh.weakCompareAndSetPlain(array, i, (short)0x0123, (short)0x89AB); assertEquals(success, false, "failing weakCompareAndSetPlain short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)0x4567, "failing weakCompareAndSetPlain short value"); + assertEquals((short)0x4567, x, "failing weakCompareAndSetPlain short value"); } { @@ -1125,14 +1123,14 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)0x0123, "success weakCompareAndSetAcquire short"); + assertEquals((short)0x0123, x, "success weakCompareAndSetAcquire short"); } { boolean success = vh.weakCompareAndSetAcquire(array, i, (short)0x4567, (short)0x89AB); assertEquals(success, false, "failing weakCompareAndSetAcquire short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)0x0123, "failing weakCompareAndSetAcquire short value"); + assertEquals((short)0x0123, x, "failing weakCompareAndSetAcquire short value"); } { @@ -1143,14 +1141,14 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)0x4567, "success weakCompareAndSetRelease short"); + assertEquals((short)0x4567, x, "success weakCompareAndSetRelease short"); } { boolean success = vh.weakCompareAndSetRelease(array, i, (short)0x0123, (short)0x89AB); assertEquals(success, false, "failing weakCompareAndSetRelease short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)0x4567, "failing weakCompareAndSetRelease short value"); + assertEquals((short)0x4567, x, "failing weakCompareAndSetRelease short value"); } { @@ -1161,14 +1159,14 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)0x0123, "success weakCompareAndSet short"); + assertEquals((short)0x0123, x, "success weakCompareAndSet short"); } { boolean success = vh.weakCompareAndSet(array, i, (short)0x4567, (short)0x89AB); assertEquals(success, false, "failing weakCompareAndSet short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)0x0123, "failing weakCompareAndSet short value"); + assertEquals((short)0x0123, x, "failing weakCompareAndSet short value"); } // Compare set and get @@ -1176,27 +1174,27 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { vh.set(array, i, (short)0x0123); short o = (short) vh.getAndSet(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndSet short"); + assertEquals((short)0x0123, o, "getAndSet short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)0x4567, "getAndSet short value"); + assertEquals((short)0x4567, x, "getAndSet short value"); } { vh.set(array, i, (short)0x0123); short o = (short) vh.getAndSetAcquire(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndSetAcquire short"); + assertEquals((short)0x0123, o, "getAndSetAcquire short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)0x4567, "getAndSetAcquire short value"); + assertEquals((short)0x4567, x, "getAndSetAcquire short value"); } { vh.set(array, i, (short)0x0123); short o = (short) vh.getAndSetRelease(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndSetRelease short"); + assertEquals((short)0x0123, o, "getAndSetRelease short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)0x4567, "getAndSetRelease short value"); + assertEquals((short)0x4567, x, "getAndSetRelease short value"); } // get and add, add and get @@ -1204,27 +1202,27 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { vh.set(array, i, (short)0x0123); short o = (short) vh.getAndAdd(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndAdd short"); + assertEquals((short)0x0123, o, "getAndAdd short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)((short)0x0123 + (short)0x4567), "getAndAdd short value"); + assertEquals((short)((short)0x0123 + (short)0x4567), x, "getAndAdd short value"); } { vh.set(array, i, (short)0x0123); short o = (short) vh.getAndAddAcquire(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndAddAcquire short"); + assertEquals((short)0x0123, o, "getAndAddAcquire short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)((short)0x0123 + (short)0x4567), "getAndAddAcquire short value"); + assertEquals((short)((short)0x0123 + (short)0x4567), x, "getAndAddAcquire short value"); } { vh.set(array, i, (short)0x0123); short o = (short) vh.getAndAddRelease(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndAddReleaseshort"); + assertEquals((short)0x0123, o, "getAndAddReleaseshort"); short x = (short) vh.get(array, i); - assertEquals(x, (short)((short)0x0123 + (short)0x4567), "getAndAddRelease short value"); + assertEquals((short)((short)0x0123 + (short)0x4567), x, "getAndAddRelease short value"); } // get and bitwise or @@ -1232,27 +1230,27 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { vh.set(array, i, (short)0x0123); short o = (short) vh.getAndBitwiseOr(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseOr short"); + assertEquals((short)0x0123, o, "getAndBitwiseOr short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)((short)0x0123 | (short)0x4567), "getAndBitwiseOr short value"); + assertEquals((short)((short)0x0123 | (short)0x4567), x, "getAndBitwiseOr short value"); } { vh.set(array, i, (short)0x0123); short o = (short) vh.getAndBitwiseOrAcquire(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseOrAcquire short"); + assertEquals((short)0x0123, o, "getAndBitwiseOrAcquire short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)((short)0x0123 | (short)0x4567), "getAndBitwiseOrAcquire short value"); + assertEquals((short)((short)0x0123 | (short)0x4567), x, "getAndBitwiseOrAcquire short value"); } { vh.set(array, i, (short)0x0123); short o = (short) vh.getAndBitwiseOrRelease(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseOrRelease short"); + assertEquals((short)0x0123, o, "getAndBitwiseOrRelease short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)((short)0x0123 | (short)0x4567), "getAndBitwiseOrRelease short value"); + assertEquals((short)((short)0x0123 | (short)0x4567), x, "getAndBitwiseOrRelease short value"); } // get and bitwise and @@ -1260,27 +1258,27 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { vh.set(array, i, (short)0x0123); short o = (short) vh.getAndBitwiseAnd(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseAnd short"); + assertEquals((short)0x0123, o, "getAndBitwiseAnd short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)((short)0x0123 & (short)0x4567), "getAndBitwiseAnd short value"); + assertEquals((short)((short)0x0123 & (short)0x4567), x, "getAndBitwiseAnd short value"); } { vh.set(array, i, (short)0x0123); short o = (short) vh.getAndBitwiseAndAcquire(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseAndAcquire short"); + assertEquals((short)0x0123, o, "getAndBitwiseAndAcquire short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)((short)0x0123 & (short)0x4567), "getAndBitwiseAndAcquire short value"); + assertEquals((short)((short)0x0123 & (short)0x4567), x, "getAndBitwiseAndAcquire short value"); } { vh.set(array, i, (short)0x0123); short o = (short) vh.getAndBitwiseAndRelease(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseAndRelease short"); + assertEquals((short)0x0123, o, "getAndBitwiseAndRelease short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)((short)0x0123 & (short)0x4567), "getAndBitwiseAndRelease short value"); + assertEquals((short)((short)0x0123 & (short)0x4567), x, "getAndBitwiseAndRelease short value"); } // get and bitwise xor @@ -1288,27 +1286,27 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { vh.set(array, i, (short)0x0123); short o = (short) vh.getAndBitwiseXor(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseXor short"); + assertEquals((short)0x0123, o, "getAndBitwiseXor short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)((short)0x0123 ^ (short)0x4567), "getAndBitwiseXor short value"); + assertEquals((short)((short)0x0123 ^ (short)0x4567), x, "getAndBitwiseXor short value"); } { vh.set(array, i, (short)0x0123); short o = (short) vh.getAndBitwiseXorAcquire(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseXorAcquire short"); + assertEquals((short)0x0123, o, "getAndBitwiseXorAcquire short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)((short)0x0123 ^ (short)0x4567), "getAndBitwiseXorAcquire short value"); + assertEquals((short)((short)0x0123 ^ (short)0x4567), x, "getAndBitwiseXorAcquire short value"); } { vh.set(array, i, (short)0x0123); short o = (short) vh.getAndBitwiseXorRelease(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseXorRelease short"); + assertEquals((short)0x0123, o, "getAndBitwiseXorRelease short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)((short)0x0123 ^ (short)0x4567), "getAndBitwiseXorRelease short value"); + assertEquals((short)((short)0x0123 ^ (short)0x4567), x, "getAndBitwiseXorRelease short value"); } } } diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessString.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessString.java index 8bc30739660..d1a746ba80e 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessString.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessString.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,28 +23,30 @@ /* * @test - * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessString + * @run junit/othervm -Diters=10 -Xint VarHandleTestAccessString * * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations * to hit compilation thresholds * - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestAccessString - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestAccessString - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestAccessString + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestAccessString + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestAccessString + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestAccessString */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestAccessString extends VarHandleBaseTest { static final String static_final_v = "foo"; @@ -109,7 +111,7 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { return vhs.toArray(new VarHandle[0]); } - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestAccessString.class, "final_v", String.class); @@ -127,8 +129,6 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { vhArrayObject = MethodHandles.arrayElementVarHandle(Object[].class); } - - @DataProvider public Object[][] varHandlesProvider() throws Exception { List vhs = new ArrayList<>(); vhs.add(vhField); @@ -158,7 +158,8 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { } } - @Test(dataProvider = "varHandlesProvider") + @ParameterizedTest + @MethodSource("varHandlesProvider") public void testIsAccessModeSupported(VarHandle vh) { assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET)); @@ -196,8 +197,6 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE)); } - - @DataProvider public Object[][] typesProvider() throws Exception { List types = new ArrayList<>(); types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessString.class)}); @@ -207,16 +206,16 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { return types.stream().toArray(Object[][]::new); } - @Test(dataProvider = "typesProvider") + @ParameterizedTest + @MethodSource("typesProvider") public void testTypes(VarHandle vh, List> pts) { - assertEquals(vh.varType(), String.class); + assertEquals(String.class, vh.varType()); - assertEquals(vh.coordinateTypes(), pts); + assertEquals(pts, vh.coordinateTypes()); testTypes(vh); } - @Test public void testLookupInstanceToStatic() { checkIAE("Lookup of static final field to instance final field", () -> { @@ -243,8 +242,6 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { }); } - - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -291,7 +288,8 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -304,26 +302,26 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { // Plain { String x = (String) vh.get(recv); - assertEquals(x, "foo", "get String value"); + assertEquals("foo", x, "get String value"); } // Volatile { String x = (String) vh.getVolatile(recv); - assertEquals(x, "foo", "getVolatile String value"); + assertEquals("foo", x, "getVolatile String value"); } // Lazy { String x = (String) vh.getAcquire(recv); - assertEquals(x, "foo", "getRelease String value"); + assertEquals("foo", x, "getRelease String value"); } // Opaque { String x = (String) vh.getOpaque(recv); - assertEquals(x, "foo", "getOpaque String value"); + assertEquals("foo", x, "getOpaque String value"); } } @@ -399,26 +397,26 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { // Plain { String x = (String) vh.get(); - assertEquals(x, "foo", "get String value"); + assertEquals("foo", x, "get String value"); } // Volatile { String x = (String) vh.getVolatile(); - assertEquals(x, "foo", "getVolatile String value"); + assertEquals("foo", x, "getVolatile String value"); } // Lazy { String x = (String) vh.getAcquire(); - assertEquals(x, "foo", "getRelease String value"); + assertEquals("foo", x, "getRelease String value"); } // Opaque { String x = (String) vh.getOpaque(); - assertEquals(x, "foo", "getOpaque String value"); + assertEquals("foo", x, "getOpaque String value"); } } @@ -495,7 +493,7 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { { vh.set(recv, "foo"); String x = (String) vh.get(recv); - assertEquals(x, "foo", "set String value"); + assertEquals("foo", x, "set String value"); } @@ -503,21 +501,21 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { { vh.setVolatile(recv, "bar"); String x = (String) vh.getVolatile(recv); - assertEquals(x, "bar", "setVolatile String value"); + assertEquals("bar", x, "setVolatile String value"); } // Lazy { vh.setRelease(recv, "foo"); String x = (String) vh.getAcquire(recv); - assertEquals(x, "foo", "setRelease String value"); + assertEquals("foo", x, "setRelease String value"); } // Opaque { vh.setOpaque(recv, "bar"); String x = (String) vh.getOpaque(recv); - assertEquals(x, "bar", "setOpaque String value"); + assertEquals("bar", x, "setOpaque String value"); } vh.set(recv, "foo"); @@ -527,56 +525,56 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { boolean r = vh.compareAndSet(recv, "foo", "bar"); assertEquals(r, true, "success compareAndSet String"); String x = (String) vh.get(recv); - assertEquals(x, "bar", "success compareAndSet String value"); + assertEquals("bar", x, "success compareAndSet String value"); } { boolean r = vh.compareAndSet(recv, "foo", "baz"); assertEquals(r, false, "failing compareAndSet String"); String x = (String) vh.get(recv); - assertEquals(x, "bar", "failing compareAndSet String value"); + assertEquals("bar", x, "failing compareAndSet String value"); } { String r = (String) vh.compareAndExchange(recv, "bar", "foo"); assertEquals(r, "bar", "success compareAndExchange String"); String x = (String) vh.get(recv); - assertEquals(x, "foo", "success compareAndExchange String value"); + assertEquals("foo", x, "success compareAndExchange String value"); } { String r = (String) vh.compareAndExchange(recv, "bar", "baz"); assertEquals(r, "foo", "failing compareAndExchange String"); String x = (String) vh.get(recv); - assertEquals(x, "foo", "failing compareAndExchange String value"); + assertEquals("foo", x, "failing compareAndExchange String value"); } { String r = (String) vh.compareAndExchangeAcquire(recv, "foo", "bar"); assertEquals(r, "foo", "success compareAndExchangeAcquire String"); String x = (String) vh.get(recv); - assertEquals(x, "bar", "success compareAndExchangeAcquire String value"); + assertEquals("bar", x, "success compareAndExchangeAcquire String value"); } { String r = (String) vh.compareAndExchangeAcquire(recv, "foo", "baz"); assertEquals(r, "bar", "failing compareAndExchangeAcquire String"); String x = (String) vh.get(recv); - assertEquals(x, "bar", "failing compareAndExchangeAcquire String value"); + assertEquals("bar", x, "failing compareAndExchangeAcquire String value"); } { String r = (String) vh.compareAndExchangeRelease(recv, "bar", "foo"); assertEquals(r, "bar", "success compareAndExchangeRelease String"); String x = (String) vh.get(recv); - assertEquals(x, "foo", "success compareAndExchangeRelease String value"); + assertEquals("foo", x, "success compareAndExchangeRelease String value"); } { String r = (String) vh.compareAndExchangeRelease(recv, "bar", "baz"); assertEquals(r, "foo", "failing compareAndExchangeRelease String"); String x = (String) vh.get(recv); - assertEquals(x, "foo", "failing compareAndExchangeRelease String value"); + assertEquals("foo", x, "failing compareAndExchangeRelease String value"); } { @@ -587,14 +585,14 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain String"); String x = (String) vh.get(recv); - assertEquals(x, "bar", "success weakCompareAndSetPlain String value"); + assertEquals("bar", x, "success weakCompareAndSetPlain String value"); } { boolean success = vh.weakCompareAndSetPlain(recv, "foo", "baz"); assertEquals(success, false, "failing weakCompareAndSetPlain String"); String x = (String) vh.get(recv); - assertEquals(x, "bar", "failing weakCompareAndSetPlain String value"); + assertEquals("bar", x, "failing weakCompareAndSetPlain String value"); } { @@ -605,14 +603,14 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire String"); String x = (String) vh.get(recv); - assertEquals(x, "foo", "success weakCompareAndSetAcquire String"); + assertEquals("foo", x, "success weakCompareAndSetAcquire String"); } { boolean success = vh.weakCompareAndSetAcquire(recv, "bar", "baz"); assertEquals(success, false, "failing weakCompareAndSetAcquire String"); String x = (String) vh.get(recv); - assertEquals(x, "foo", "failing weakCompareAndSetAcquire String value"); + assertEquals("foo", x, "failing weakCompareAndSetAcquire String value"); } { @@ -623,14 +621,14 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease String"); String x = (String) vh.get(recv); - assertEquals(x, "bar", "success weakCompareAndSetRelease String"); + assertEquals("bar", x, "success weakCompareAndSetRelease String"); } { boolean success = vh.weakCompareAndSetRelease(recv, "foo", "baz"); assertEquals(success, false, "failing weakCompareAndSetRelease String"); String x = (String) vh.get(recv); - assertEquals(x, "bar", "failing weakCompareAndSetRelease String value"); + assertEquals("bar", x, "failing weakCompareAndSetRelease String value"); } { @@ -641,14 +639,14 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet String"); String x = (String) vh.get(recv); - assertEquals(x, "foo", "success weakCompareAndSet String value"); + assertEquals("foo", x, "success weakCompareAndSet String value"); } { boolean success = vh.weakCompareAndSet(recv, "bar", "baz"); assertEquals(success, false, "failing weakCompareAndSet String"); String x = (String) vh.get(recv); - assertEquals(x, "foo", "failing weakCompareAndSet String value"); + assertEquals("foo", x, "failing weakCompareAndSet String value"); } // Compare set and get @@ -656,27 +654,27 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { vh.set(recv, "foo"); String o = (String) vh.getAndSet(recv, "bar"); - assertEquals(o, "foo", "getAndSet String"); + assertEquals("foo", o, "getAndSet String"); String x = (String) vh.get(recv); - assertEquals(x, "bar", "getAndSet String value"); + assertEquals("bar", x, "getAndSet String value"); } { vh.set(recv, "foo"); String o = (String) vh.getAndSetAcquire(recv, "bar"); - assertEquals(o, "foo", "getAndSetAcquire String"); + assertEquals("foo", o, "getAndSetAcquire String"); String x = (String) vh.get(recv); - assertEquals(x, "bar", "getAndSetAcquire String value"); + assertEquals("bar", x, "getAndSetAcquire String value"); } { vh.set(recv, "foo"); String o = (String) vh.getAndSetRelease(recv, "bar"); - assertEquals(o, "foo", "getAndSetRelease String"); + assertEquals("foo", o, "getAndSetRelease String"); String x = (String) vh.get(recv); - assertEquals(x, "bar", "getAndSetRelease String value"); + assertEquals("bar", x, "getAndSetRelease String value"); } @@ -739,7 +737,7 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { { vh.set("foo"); String x = (String) vh.get(); - assertEquals(x, "foo", "set String value"); + assertEquals("foo", x, "set String value"); } @@ -747,21 +745,21 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { { vh.setVolatile("bar"); String x = (String) vh.getVolatile(); - assertEquals(x, "bar", "setVolatile String value"); + assertEquals("bar", x, "setVolatile String value"); } // Lazy { vh.setRelease("foo"); String x = (String) vh.getAcquire(); - assertEquals(x, "foo", "setRelease String value"); + assertEquals("foo", x, "setRelease String value"); } // Opaque { vh.setOpaque("bar"); String x = (String) vh.getOpaque(); - assertEquals(x, "bar", "setOpaque String value"); + assertEquals("bar", x, "setOpaque String value"); } vh.set("foo"); @@ -771,56 +769,56 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { boolean r = vh.compareAndSet("foo", "bar"); assertEquals(r, true, "success compareAndSet String"); String x = (String) vh.get(); - assertEquals(x, "bar", "success compareAndSet String value"); + assertEquals("bar", x, "success compareAndSet String value"); } { boolean r = vh.compareAndSet("foo", "baz"); assertEquals(r, false, "failing compareAndSet String"); String x = (String) vh.get(); - assertEquals(x, "bar", "failing compareAndSet String value"); + assertEquals("bar", x, "failing compareAndSet String value"); } { String r = (String) vh.compareAndExchange("bar", "foo"); assertEquals(r, "bar", "success compareAndExchange String"); String x = (String) vh.get(); - assertEquals(x, "foo", "success compareAndExchange String value"); + assertEquals("foo", x, "success compareAndExchange String value"); } { String r = (String) vh.compareAndExchange("bar", "baz"); assertEquals(r, "foo", "failing compareAndExchange String"); String x = (String) vh.get(); - assertEquals(x, "foo", "failing compareAndExchange String value"); + assertEquals("foo", x, "failing compareAndExchange String value"); } { String r = (String) vh.compareAndExchangeAcquire("foo", "bar"); assertEquals(r, "foo", "success compareAndExchangeAcquire String"); String x = (String) vh.get(); - assertEquals(x, "bar", "success compareAndExchangeAcquire String value"); + assertEquals("bar", x, "success compareAndExchangeAcquire String value"); } { String r = (String) vh.compareAndExchangeAcquire("foo", "baz"); assertEquals(r, "bar", "failing compareAndExchangeAcquire String"); String x = (String) vh.get(); - assertEquals(x, "bar", "failing compareAndExchangeAcquire String value"); + assertEquals("bar", x, "failing compareAndExchangeAcquire String value"); } { String r = (String) vh.compareAndExchangeRelease("bar", "foo"); assertEquals(r, "bar", "success compareAndExchangeRelease String"); String x = (String) vh.get(); - assertEquals(x, "foo", "success compareAndExchangeRelease String value"); + assertEquals("foo", x, "success compareAndExchangeRelease String value"); } { String r = (String) vh.compareAndExchangeRelease("bar", "baz"); assertEquals(r, "foo", "failing compareAndExchangeRelease String"); String x = (String) vh.get(); - assertEquals(x, "foo", "failing compareAndExchangeRelease String value"); + assertEquals("foo", x, "failing compareAndExchangeRelease String value"); } { @@ -831,14 +829,14 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain String"); String x = (String) vh.get(); - assertEquals(x, "bar", "success weakCompareAndSetPlain String value"); + assertEquals("bar", x, "success weakCompareAndSetPlain String value"); } { boolean success = vh.weakCompareAndSetPlain("foo", "baz"); assertEquals(success, false, "failing weakCompareAndSetPlain String"); String x = (String) vh.get(); - assertEquals(x, "bar", "failing weakCompareAndSetPlain String value"); + assertEquals("bar", x, "failing weakCompareAndSetPlain String value"); } { @@ -849,14 +847,14 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire String"); String x = (String) vh.get(); - assertEquals(x, "foo", "success weakCompareAndSetAcquire String"); + assertEquals("foo", x, "success weakCompareAndSetAcquire String"); } { boolean success = vh.weakCompareAndSetAcquire("bar", "baz"); assertEquals(success, false, "failing weakCompareAndSetAcquire String"); String x = (String) vh.get(); - assertEquals(x, "foo", "failing weakCompareAndSetAcquire String value"); + assertEquals("foo", x, "failing weakCompareAndSetAcquire String value"); } { @@ -867,14 +865,14 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease String"); String x = (String) vh.get(); - assertEquals(x, "bar", "success weakCompareAndSetRelease String"); + assertEquals("bar", x, "success weakCompareAndSetRelease String"); } { boolean success = vh.weakCompareAndSetRelease("foo", "baz"); assertEquals(success, false, "failing weakCompareAndSetRelease String"); String x = (String) vh.get(); - assertEquals(x, "bar", "failing weakCompareAndSetRelease String value"); + assertEquals("bar", x, "failing weakCompareAndSetRelease String value"); } { @@ -885,14 +883,14 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet String"); String x = (String) vh.get(); - assertEquals(x, "foo", "success weakCompareAndSet String"); + assertEquals("foo", x, "success weakCompareAndSet String"); } { boolean success = vh.weakCompareAndSet("bar", "baz"); assertEquals(success, false, "failing weakCompareAndSet String"); String x = (String) vh.get(); - assertEquals(x, "foo", "failing weakCompareAndSet String value"); + assertEquals("foo", x, "failing weakCompareAndSet String value"); } // Compare set and get @@ -900,27 +898,27 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { vh.set("foo"); String o = (String) vh.getAndSet("bar"); - assertEquals(o, "foo", "getAndSet String"); + assertEquals("foo", o, "getAndSet String"); String x = (String) vh.get(); - assertEquals(x, "bar", "getAndSet String value"); + assertEquals("bar", x, "getAndSet String value"); } { vh.set("foo"); String o = (String) vh.getAndSetAcquire("bar"); - assertEquals(o, "foo", "getAndSetAcquire String"); + assertEquals("foo", o, "getAndSetAcquire String"); String x = (String) vh.get(); - assertEquals(x, "bar", "getAndSetAcquire String value"); + assertEquals("bar", x, "getAndSetAcquire String value"); } { vh.set("foo"); String o = (String) vh.getAndSetRelease("bar"); - assertEquals(o, "foo", "getAndSetRelease String"); + assertEquals("foo", o, "getAndSetRelease String"); String x = (String) vh.get(); - assertEquals(x, "bar", "getAndSetRelease String value"); + assertEquals("bar", x, "getAndSetRelease String value"); } @@ -986,7 +984,7 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { { vh.set(array, i, "foo"); String x = (String) vh.get(array, i); - assertEquals(x, "foo", "get String value"); + assertEquals("foo", x, "get String value"); } @@ -994,21 +992,21 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { { vh.setVolatile(array, i, "bar"); String x = (String) vh.getVolatile(array, i); - assertEquals(x, "bar", "setVolatile String value"); + assertEquals("bar", x, "setVolatile String value"); } // Lazy { vh.setRelease(array, i, "foo"); String x = (String) vh.getAcquire(array, i); - assertEquals(x, "foo", "setRelease String value"); + assertEquals("foo", x, "setRelease String value"); } // Opaque { vh.setOpaque(array, i, "bar"); String x = (String) vh.getOpaque(array, i); - assertEquals(x, "bar", "setOpaque String value"); + assertEquals("bar", x, "setOpaque String value"); } vh.set(array, i, "foo"); @@ -1018,56 +1016,56 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { boolean r = vh.compareAndSet(array, i, "foo", "bar"); assertEquals(r, true, "success compareAndSet String"); String x = (String) vh.get(array, i); - assertEquals(x, "bar", "success compareAndSet String value"); + assertEquals("bar", x, "success compareAndSet String value"); } { boolean r = vh.compareAndSet(array, i, "foo", "baz"); assertEquals(r, false, "failing compareAndSet String"); String x = (String) vh.get(array, i); - assertEquals(x, "bar", "failing compareAndSet String value"); + assertEquals("bar", x, "failing compareAndSet String value"); } { String r = (String) vh.compareAndExchange(array, i, "bar", "foo"); assertEquals(r, "bar", "success compareAndExchange String"); String x = (String) vh.get(array, i); - assertEquals(x, "foo", "success compareAndExchange String value"); + assertEquals("foo", x, "success compareAndExchange String value"); } { String r = (String) vh.compareAndExchange(array, i, "bar", "baz"); assertEquals(r, "foo", "failing compareAndExchange String"); String x = (String) vh.get(array, i); - assertEquals(x, "foo", "failing compareAndExchange String value"); + assertEquals("foo", x, "failing compareAndExchange String value"); } { String r = (String) vh.compareAndExchangeAcquire(array, i, "foo", "bar"); assertEquals(r, "foo", "success compareAndExchangeAcquire String"); String x = (String) vh.get(array, i); - assertEquals(x, "bar", "success compareAndExchangeAcquire String value"); + assertEquals("bar", x, "success compareAndExchangeAcquire String value"); } { String r = (String) vh.compareAndExchangeAcquire(array, i, "foo", "baz"); assertEquals(r, "bar", "failing compareAndExchangeAcquire String"); String x = (String) vh.get(array, i); - assertEquals(x, "bar", "failing compareAndExchangeAcquire String value"); + assertEquals("bar", x, "failing compareAndExchangeAcquire String value"); } { String r = (String) vh.compareAndExchangeRelease(array, i, "bar", "foo"); assertEquals(r, "bar", "success compareAndExchangeRelease String"); String x = (String) vh.get(array, i); - assertEquals(x, "foo", "success compareAndExchangeRelease String value"); + assertEquals("foo", x, "success compareAndExchangeRelease String value"); } { String r = (String) vh.compareAndExchangeRelease(array, i, "bar", "baz"); assertEquals(r, "foo", "failing compareAndExchangeRelease String"); String x = (String) vh.get(array, i); - assertEquals(x, "foo", "failing compareAndExchangeRelease String value"); + assertEquals("foo", x, "failing compareAndExchangeRelease String value"); } { @@ -1078,14 +1076,14 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain String"); String x = (String) vh.get(array, i); - assertEquals(x, "bar", "success weakCompareAndSetPlain String value"); + assertEquals("bar", x, "success weakCompareAndSetPlain String value"); } { boolean success = vh.weakCompareAndSetPlain(array, i, "foo", "baz"); assertEquals(success, false, "failing weakCompareAndSetPlain String"); String x = (String) vh.get(array, i); - assertEquals(x, "bar", "failing weakCompareAndSetPlain String value"); + assertEquals("bar", x, "failing weakCompareAndSetPlain String value"); } { @@ -1096,14 +1094,14 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire String"); String x = (String) vh.get(array, i); - assertEquals(x, "foo", "success weakCompareAndSetAcquire String"); + assertEquals("foo", x, "success weakCompareAndSetAcquire String"); } { boolean success = vh.weakCompareAndSetAcquire(array, i, "bar", "baz"); assertEquals(success, false, "failing weakCompareAndSetAcquire String"); String x = (String) vh.get(array, i); - assertEquals(x, "foo", "failing weakCompareAndSetAcquire String value"); + assertEquals("foo", x, "failing weakCompareAndSetAcquire String value"); } { @@ -1114,14 +1112,14 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease String"); String x = (String) vh.get(array, i); - assertEquals(x, "bar", "success weakCompareAndSetRelease String"); + assertEquals("bar", x, "success weakCompareAndSetRelease String"); } { boolean success = vh.weakCompareAndSetRelease(array, i, "foo", "baz"); assertEquals(success, false, "failing weakCompareAndSetRelease String"); String x = (String) vh.get(array, i); - assertEquals(x, "bar", "failing weakCompareAndSetRelease String value"); + assertEquals("bar", x, "failing weakCompareAndSetRelease String value"); } { @@ -1132,14 +1130,14 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet String"); String x = (String) vh.get(array, i); - assertEquals(x, "foo", "success weakCompareAndSet String"); + assertEquals("foo", x, "success weakCompareAndSet String"); } { boolean success = vh.weakCompareAndSet(array, i, "bar", "baz"); assertEquals(success, false, "failing weakCompareAndSet String"); String x = (String) vh.get(array, i); - assertEquals(x, "foo", "failing weakCompareAndSet String value"); + assertEquals("foo", x, "failing weakCompareAndSet String value"); } // Compare set and get @@ -1147,27 +1145,27 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { vh.set(array, i, "foo"); String o = (String) vh.getAndSet(array, i, "bar"); - assertEquals(o, "foo", "getAndSet String"); + assertEquals("foo", o, "getAndSet String"); String x = (String) vh.get(array, i); - assertEquals(x, "bar", "getAndSet String value"); + assertEquals("bar", x, "getAndSet String value"); } { vh.set(array, i, "foo"); String o = (String) vh.getAndSetAcquire(array, i, "bar"); - assertEquals(o, "foo", "getAndSetAcquire String"); + assertEquals("foo", o, "getAndSetAcquire String"); String x = (String) vh.get(array, i); - assertEquals(x, "bar", "getAndSetAcquire String value"); + assertEquals("bar", x, "getAndSetAcquire String value"); } { vh.set(array, i, "foo"); String o = (String) vh.getAndSetRelease(array, i, "bar"); - assertEquals(o, "foo", "getAndSetRelease String"); + assertEquals("foo", o, "getAndSetRelease String"); String x = (String) vh.get(array, i); - assertEquals(x, "bar", "getAndSetRelease String value"); + assertEquals("bar", x, "getAndSetRelease String value"); } diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsChar.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsChar.java index 78c13da45a9..26ac4aab893 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsChar.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsChar.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,25 +26,25 @@ * @bug 8154556 * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations * to hit compilation thresholds - * @run testng/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsChar - * @run testng/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestByteArrayAsChar - * @run testng/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestByteArrayAsChar + * @run junit/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsChar + * @run junit/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestByteArrayAsChar + * @run junit/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestByteArrayAsChar */ -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; -import java.util.Arrays; -import java.util.EnumSet; import java.util.List; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest { static final int SIZE = Character.BYTES; @@ -107,7 +107,8 @@ public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest { } } - @Test(dataProvider = "varHandlesProvider") + @ParameterizedTest + @MethodSource("VarHandleBaseByteArrayTest#varHandlesProvider") public void testIsAccessModeSupported(VarHandleSource vhs) { VarHandle vh = vhs.s; @@ -158,17 +159,16 @@ public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest { assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE)); } - @Test(dataProvider = "typesProvider") + @ParameterizedTest + @MethodSource("typesProvider") public void testTypes(VarHandle vh, List> pts) { - assertEquals(vh.varType(), char.class); + assertEquals(char.class, vh.varType()); - assertEquals(vh.coordinateTypes(), pts); + assertEquals(pts, vh.coordinateTypes()); testTypes(vh); } - - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -230,7 +230,8 @@ public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -239,7 +240,6 @@ public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest { } } - static void testArrayNPE(ByteArraySource bs, VarHandleSource vhs) { VarHandle vh = vhs.s; byte[] array = null; @@ -740,7 +740,7 @@ public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest { { vh.set(array, i, VALUE_1); char x = (char) vh.get(array, i); - assertEquals(x, VALUE_1, "get char value"); + assertEquals(VALUE_1, x, "get char value"); } } } @@ -759,7 +759,7 @@ public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest { { vh.set(array, i, VALUE_1); char x = (char) vh.get(array, i); - assertEquals(x, VALUE_1, "get char value"); + assertEquals(VALUE_1, x, "get char value"); } if (iAligned) { @@ -767,21 +767,21 @@ public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest { { vh.setVolatile(array, i, VALUE_2); char x = (char) vh.getVolatile(array, i); - assertEquals(x, VALUE_2, "setVolatile char value"); + assertEquals(VALUE_2, x, "setVolatile char value"); } // Lazy { vh.setRelease(array, i, VALUE_1); char x = (char) vh.getAcquire(array, i); - assertEquals(x, VALUE_1, "setRelease char value"); + assertEquals(VALUE_1, x, "setRelease char value"); } // Opaque { vh.setOpaque(array, i, VALUE_2); char x = (char) vh.getOpaque(array, i); - assertEquals(x, VALUE_2, "setOpaque char value"); + assertEquals(VALUE_2, x, "setOpaque char value"); } @@ -807,26 +807,26 @@ public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest { // Plain { char x = (char) vh.get(array, i); - assertEquals(x, v, "get char value"); + assertEquals(v, x, "get char value"); } if (iAligned) { // Volatile { char x = (char) vh.getVolatile(array, i); - assertEquals(x, v, "getVolatile char value"); + assertEquals(v, x, "getVolatile char value"); } // Lazy { char x = (char) vh.getAcquire(array, i); - assertEquals(x, v, "getRelease char value"); + assertEquals(v, x, "getRelease char value"); } // Opaque { char x = (char) vh.getOpaque(array, i); - assertEquals(x, v, "getOpaque char value"); + assertEquals(v, x, "getOpaque char value"); } } } diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java index 331b9073e90..a9e1e603c5d 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,25 +26,25 @@ * @bug 8154556 * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations * to hit compilation thresholds - * @run testng/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsDouble - * @run testng/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestByteArrayAsDouble - * @run testng/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestByteArrayAsDouble + * @run junit/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsDouble + * @run junit/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestByteArrayAsDouble + * @run junit/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestByteArrayAsDouble */ -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; -import java.util.Arrays; -import java.util.EnumSet; import java.util.List; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest { static final int SIZE = Double.BYTES; @@ -107,7 +107,8 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest { } } - @Test(dataProvider = "varHandlesProvider") + @ParameterizedTest + @MethodSource("VarHandleBaseByteArrayTest#varHandlesProvider") public void testIsAccessModeSupported(VarHandleSource vhs) { VarHandle vh = vhs.s; @@ -172,17 +173,16 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest { assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE)); } - @Test(dataProvider = "typesProvider") + @ParameterizedTest + @MethodSource("typesProvider") public void testTypes(VarHandle vh, List> pts) { - assertEquals(vh.varType(), double.class); + assertEquals(double.class, vh.varType()); - assertEquals(vh.coordinateTypes(), pts); + assertEquals(pts, vh.coordinateTypes()); testTypes(vh); } - - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -244,7 +244,8 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -253,7 +254,6 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest { } } - static void testArrayNPE(ByteArraySource bs, VarHandleSource vhs) { VarHandle vh = vhs.s; byte[] array = null; @@ -883,7 +883,7 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest { { vh.set(array, i, VALUE_1); double x = (double) vh.get(array, i); - assertEquals(x, VALUE_1, "get double value"); + assertEquals(VALUE_1, x, "get double value"); } } } @@ -902,7 +902,7 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest { { vh.set(array, i, VALUE_1); double x = (double) vh.get(array, i); - assertEquals(x, VALUE_1, "get double value"); + assertEquals(VALUE_1, x, "get double value"); } if (iAligned) { @@ -910,21 +910,21 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest { { vh.setVolatile(array, i, VALUE_2); double x = (double) vh.getVolatile(array, i); - assertEquals(x, VALUE_2, "setVolatile double value"); + assertEquals(VALUE_2, x, "setVolatile double value"); } // Lazy { vh.setRelease(array, i, VALUE_1); double x = (double) vh.getAcquire(array, i); - assertEquals(x, VALUE_1, "setRelease double value"); + assertEquals(VALUE_1, x, "setRelease double value"); } // Opaque { vh.setOpaque(array, i, VALUE_2); double x = (double) vh.getOpaque(array, i); - assertEquals(x, VALUE_2, "setOpaque double value"); + assertEquals(VALUE_2, x, "setOpaque double value"); } vh.set(array, i, VALUE_1); @@ -934,56 +934,56 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest { boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2); assertEquals(r, true, "success compareAndSet double"); double x = (double) vh.get(array, i); - assertEquals(x, VALUE_2, "success compareAndSet double value"); + assertEquals(VALUE_2, x, "success compareAndSet double value"); } { boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3); assertEquals(r, false, "failing compareAndSet double"); double x = (double) vh.get(array, i); - assertEquals(x, VALUE_2, "failing compareAndSet double value"); + assertEquals(VALUE_2, x, "failing compareAndSet double value"); } { double r = (double) vh.compareAndExchange(array, i, VALUE_2, VALUE_1); assertEquals(r, VALUE_2, "success compareAndExchange double"); double x = (double) vh.get(array, i); - assertEquals(x, VALUE_1, "success compareAndExchange double value"); + assertEquals(VALUE_1, x, "success compareAndExchange double value"); } { double r = (double) vh.compareAndExchange(array, i, VALUE_2, VALUE_3); assertEquals(r, VALUE_1, "failing compareAndExchange double"); double x = (double) vh.get(array, i); - assertEquals(x, VALUE_1, "failing compareAndExchange double value"); + assertEquals(VALUE_1, x, "failing compareAndExchange double value"); } { double r = (double) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2); assertEquals(r, VALUE_1, "success compareAndExchangeAcquire double"); double x = (double) vh.get(array, i); - assertEquals(x, VALUE_2, "success compareAndExchangeAcquire double value"); + assertEquals(VALUE_2, x, "success compareAndExchangeAcquire double value"); } { double r = (double) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3); assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire double"); double x = (double) vh.get(array, i); - assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire double value"); + assertEquals(VALUE_2, x, "failing compareAndExchangeAcquire double value"); } { double r = (double) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1); assertEquals(r, VALUE_2, "success compareAndExchangeRelease double"); double x = (double) vh.get(array, i); - assertEquals(x, VALUE_1, "success compareAndExchangeRelease double value"); + assertEquals(VALUE_1, x, "success compareAndExchangeRelease double value"); } { double r = (double) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3); assertEquals(r, VALUE_1, "failing compareAndExchangeRelease double"); double x = (double) vh.get(array, i); - assertEquals(x, VALUE_1, "failing compareAndExchangeRelease double value"); + assertEquals(VALUE_1, x, "failing compareAndExchangeRelease double value"); } { @@ -994,14 +994,14 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest { } assertEquals(success, true, "success weakCompareAndSetPlain double"); double x = (double) vh.get(array, i); - assertEquals(x, VALUE_2, "success weakCompareAndSetPlain double value"); + assertEquals(VALUE_2, x, "success weakCompareAndSetPlain double value"); } { boolean success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_3); assertEquals(success, false, "failing weakCompareAndSetPlain double"); double x = (double) vh.get(array, i); - assertEquals(x, VALUE_2, "failing weakCompareAndSetPlain double value"); + assertEquals(VALUE_2, x, "failing weakCompareAndSetPlain double value"); } { @@ -1012,14 +1012,14 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest { } assertEquals(success, true, "success weakCompareAndSetAcquire double"); double x = (double) vh.get(array, i); - assertEquals(x, VALUE_1, "success weakCompareAndSetAcquire double"); + assertEquals(VALUE_1, x, "success weakCompareAndSetAcquire double"); } { boolean success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_3); assertEquals(success, false, "failing weakCompareAndSetAcquire double"); double x = (double) vh.get(array, i); - assertEquals(x, VALUE_1, "failing weakCompareAndSetAcquire double value"); + assertEquals(VALUE_1, x, "failing weakCompareAndSetAcquire double value"); } { @@ -1030,14 +1030,14 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest { } assertEquals(success, true, "success weakCompareAndSetRelease double"); double x = (double) vh.get(array, i); - assertEquals(x, VALUE_2, "success weakCompareAndSetRelease double"); + assertEquals(VALUE_2, x, "success weakCompareAndSetRelease double"); } { boolean success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_3); assertEquals(success, false, "failing weakCompareAndSetRelease double"); double x = (double) vh.get(array, i); - assertEquals(x, VALUE_2, "failing weakCompareAndSetRelease double value"); + assertEquals(VALUE_2, x, "failing weakCompareAndSetRelease double value"); } { @@ -1048,14 +1048,14 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest { } assertEquals(success, true, "success weakCompareAndSet double"); double x = (double) vh.get(array, i); - assertEquals(x, VALUE_1, "success weakCompareAndSet double"); + assertEquals(VALUE_1, x, "success weakCompareAndSet double"); } { boolean success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_3); assertEquals(success, false, "failing weakCompareAndSet double"); double x = (double) vh.get(array, i); - assertEquals(x, VALUE_1, "failing weakCompareAndSet double value"); + assertEquals(VALUE_1, x, "failing weakCompareAndSet double value"); } // Compare set and get @@ -1063,27 +1063,27 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest { vh.set(array, i, VALUE_1); double o = (double) vh.getAndSet(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndSet double"); + assertEquals(VALUE_1, o, "getAndSet double"); double x = (double) vh.get(array, i); - assertEquals(x, VALUE_2, "getAndSet double value"); + assertEquals(VALUE_2, x, "getAndSet double value"); } { vh.set(array, i, VALUE_1); double o = (double) vh.getAndSetAcquire(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndSetAcquire double"); + assertEquals(VALUE_1, o, "getAndSetAcquire double"); double x = (double) vh.get(array, i); - assertEquals(x, VALUE_2, "getAndSetAcquire double value"); + assertEquals(VALUE_2, x, "getAndSetAcquire double value"); } { vh.set(array, i, VALUE_1); double o = (double) vh.getAndSetRelease(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndSetRelease double"); + assertEquals(VALUE_1, o, "getAndSetRelease double"); double x = (double) vh.get(array, i); - assertEquals(x, VALUE_2, "getAndSetRelease double value"); + assertEquals(VALUE_2, x, "getAndSetRelease double value"); } @@ -1109,26 +1109,26 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest { // Plain { double x = (double) vh.get(array, i); - assertEquals(x, v, "get double value"); + assertEquals(v, x, "get double value"); } if (iAligned) { // Volatile { double x = (double) vh.getVolatile(array, i); - assertEquals(x, v, "getVolatile double value"); + assertEquals(v, x, "getVolatile double value"); } // Lazy { double x = (double) vh.getAcquire(array, i); - assertEquals(x, v, "getRelease double value"); + assertEquals(v, x, "getRelease double value"); } // Opaque { double x = (double) vh.getOpaque(array, i); - assertEquals(x, v, "getOpaque double value"); + assertEquals(v, x, "getOpaque double value"); } } } diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java index 908d61dd597..486487518e9 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,25 +26,25 @@ * @bug 8154556 * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations * to hit compilation thresholds - * @run testng/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsFloat - * @run testng/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestByteArrayAsFloat - * @run testng/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestByteArrayAsFloat + * @run junit/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsFloat + * @run junit/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestByteArrayAsFloat + * @run junit/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestByteArrayAsFloat */ -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; -import java.util.Arrays; -import java.util.EnumSet; import java.util.List; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest { static final int SIZE = Float.BYTES; @@ -107,7 +107,8 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest { } } - @Test(dataProvider = "varHandlesProvider") + @ParameterizedTest + @MethodSource("VarHandleBaseByteArrayTest#varHandlesProvider") public void testIsAccessModeSupported(VarHandleSource vhs) { VarHandle vh = vhs.s; @@ -172,17 +173,16 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest { assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE)); } - @Test(dataProvider = "typesProvider") + @ParameterizedTest + @MethodSource("typesProvider") public void testTypes(VarHandle vh, List> pts) { - assertEquals(vh.varType(), float.class); + assertEquals(float.class, vh.varType()); - assertEquals(vh.coordinateTypes(), pts); + assertEquals(pts, vh.coordinateTypes()); testTypes(vh); } - - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -244,7 +244,8 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -253,7 +254,6 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest { } } - static void testArrayNPE(ByteArraySource bs, VarHandleSource vhs) { VarHandle vh = vhs.s; byte[] array = null; @@ -883,7 +883,7 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest { { vh.set(array, i, VALUE_1); float x = (float) vh.get(array, i); - assertEquals(x, VALUE_1, "get float value"); + assertEquals(VALUE_1, x, "get float value"); } } } @@ -902,7 +902,7 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest { { vh.set(array, i, VALUE_1); float x = (float) vh.get(array, i); - assertEquals(x, VALUE_1, "get float value"); + assertEquals(VALUE_1, x, "get float value"); } if (iAligned) { @@ -910,21 +910,21 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest { { vh.setVolatile(array, i, VALUE_2); float x = (float) vh.getVolatile(array, i); - assertEquals(x, VALUE_2, "setVolatile float value"); + assertEquals(VALUE_2, x, "setVolatile float value"); } // Lazy { vh.setRelease(array, i, VALUE_1); float x = (float) vh.getAcquire(array, i); - assertEquals(x, VALUE_1, "setRelease float value"); + assertEquals(VALUE_1, x, "setRelease float value"); } // Opaque { vh.setOpaque(array, i, VALUE_2); float x = (float) vh.getOpaque(array, i); - assertEquals(x, VALUE_2, "setOpaque float value"); + assertEquals(VALUE_2, x, "setOpaque float value"); } vh.set(array, i, VALUE_1); @@ -934,56 +934,56 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest { boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2); assertEquals(r, true, "success compareAndSet float"); float x = (float) vh.get(array, i); - assertEquals(x, VALUE_2, "success compareAndSet float value"); + assertEquals(VALUE_2, x, "success compareAndSet float value"); } { boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3); assertEquals(r, false, "failing compareAndSet float"); float x = (float) vh.get(array, i); - assertEquals(x, VALUE_2, "failing compareAndSet float value"); + assertEquals(VALUE_2, x, "failing compareAndSet float value"); } { float r = (float) vh.compareAndExchange(array, i, VALUE_2, VALUE_1); assertEquals(r, VALUE_2, "success compareAndExchange float"); float x = (float) vh.get(array, i); - assertEquals(x, VALUE_1, "success compareAndExchange float value"); + assertEquals(VALUE_1, x, "success compareAndExchange float value"); } { float r = (float) vh.compareAndExchange(array, i, VALUE_2, VALUE_3); assertEquals(r, VALUE_1, "failing compareAndExchange float"); float x = (float) vh.get(array, i); - assertEquals(x, VALUE_1, "failing compareAndExchange float value"); + assertEquals(VALUE_1, x, "failing compareAndExchange float value"); } { float r = (float) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2); assertEquals(r, VALUE_1, "success compareAndExchangeAcquire float"); float x = (float) vh.get(array, i); - assertEquals(x, VALUE_2, "success compareAndExchangeAcquire float value"); + assertEquals(VALUE_2, x, "success compareAndExchangeAcquire float value"); } { float r = (float) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3); assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire float"); float x = (float) vh.get(array, i); - assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire float value"); + assertEquals(VALUE_2, x, "failing compareAndExchangeAcquire float value"); } { float r = (float) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1); assertEquals(r, VALUE_2, "success compareAndExchangeRelease float"); float x = (float) vh.get(array, i); - assertEquals(x, VALUE_1, "success compareAndExchangeRelease float value"); + assertEquals(VALUE_1, x, "success compareAndExchangeRelease float value"); } { float r = (float) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3); assertEquals(r, VALUE_1, "failing compareAndExchangeRelease float"); float x = (float) vh.get(array, i); - assertEquals(x, VALUE_1, "failing compareAndExchangeRelease float value"); + assertEquals(VALUE_1, x, "failing compareAndExchangeRelease float value"); } { @@ -994,14 +994,14 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest { } assertEquals(success, true, "success weakCompareAndSetPlain float"); float x = (float) vh.get(array, i); - assertEquals(x, VALUE_2, "success weakCompareAndSetPlain float value"); + assertEquals(VALUE_2, x, "success weakCompareAndSetPlain float value"); } { boolean success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_3); assertEquals(success, false, "failing weakCompareAndSetPlain float"); float x = (float) vh.get(array, i); - assertEquals(x, VALUE_2, "failing weakCompareAndSetPlain float value"); + assertEquals(VALUE_2, x, "failing weakCompareAndSetPlain float value"); } { @@ -1012,14 +1012,14 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest { } assertEquals(success, true, "success weakCompareAndSetAcquire float"); float x = (float) vh.get(array, i); - assertEquals(x, VALUE_1, "success weakCompareAndSetAcquire float"); + assertEquals(VALUE_1, x, "success weakCompareAndSetAcquire float"); } { boolean success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_3); assertEquals(success, false, "failing weakCompareAndSetAcquire float"); float x = (float) vh.get(array, i); - assertEquals(x, VALUE_1, "failing weakCompareAndSetAcquire float value"); + assertEquals(VALUE_1, x, "failing weakCompareAndSetAcquire float value"); } { @@ -1030,14 +1030,14 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest { } assertEquals(success, true, "success weakCompareAndSetRelease float"); float x = (float) vh.get(array, i); - assertEquals(x, VALUE_2, "success weakCompareAndSetRelease float"); + assertEquals(VALUE_2, x, "success weakCompareAndSetRelease float"); } { boolean success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_3); assertEquals(success, false, "failing weakCompareAndSetRelease float"); float x = (float) vh.get(array, i); - assertEquals(x, VALUE_2, "failing weakCompareAndSetRelease float value"); + assertEquals(VALUE_2, x, "failing weakCompareAndSetRelease float value"); } { @@ -1048,14 +1048,14 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest { } assertEquals(success, true, "success weakCompareAndSet float"); float x = (float) vh.get(array, i); - assertEquals(x, VALUE_1, "success weakCompareAndSet float"); + assertEquals(VALUE_1, x, "success weakCompareAndSet float"); } { boolean success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_3); assertEquals(success, false, "failing weakCompareAndSet float"); float x = (float) vh.get(array, i); - assertEquals(x, VALUE_1, "failing weakCompareAndSet float value"); + assertEquals(VALUE_1, x, "failing weakCompareAndSet float value"); } // Compare set and get @@ -1063,27 +1063,27 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest { vh.set(array, i, VALUE_1); float o = (float) vh.getAndSet(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndSet float"); + assertEquals(VALUE_1, o, "getAndSet float"); float x = (float) vh.get(array, i); - assertEquals(x, VALUE_2, "getAndSet float value"); + assertEquals(VALUE_2, x, "getAndSet float value"); } { vh.set(array, i, VALUE_1); float o = (float) vh.getAndSetAcquire(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndSetAcquire float"); + assertEquals(VALUE_1, o, "getAndSetAcquire float"); float x = (float) vh.get(array, i); - assertEquals(x, VALUE_2, "getAndSetAcquire float value"); + assertEquals(VALUE_2, x, "getAndSetAcquire float value"); } { vh.set(array, i, VALUE_1); float o = (float) vh.getAndSetRelease(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndSetRelease float"); + assertEquals(VALUE_1, o, "getAndSetRelease float"); float x = (float) vh.get(array, i); - assertEquals(x, VALUE_2, "getAndSetRelease float value"); + assertEquals(VALUE_2, x, "getAndSetRelease float value"); } @@ -1109,26 +1109,26 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest { // Plain { float x = (float) vh.get(array, i); - assertEquals(x, v, "get float value"); + assertEquals(v, x, "get float value"); } if (iAligned) { // Volatile { float x = (float) vh.getVolatile(array, i); - assertEquals(x, v, "getVolatile float value"); + assertEquals(v, x, "getVolatile float value"); } // Lazy { float x = (float) vh.getAcquire(array, i); - assertEquals(x, v, "getRelease float value"); + assertEquals(v, x, "getRelease float value"); } // Opaque { float x = (float) vh.getOpaque(array, i); - assertEquals(x, v, "getOpaque float value"); + assertEquals(v, x, "getOpaque float value"); } } } diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java index 791510281c1..ce55c3d5e31 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,25 +26,25 @@ * @bug 8154556 * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations * to hit compilation thresholds - * @run testng/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsInt - * @run testng/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestByteArrayAsInt - * @run testng/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestByteArrayAsInt + * @run junit/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsInt + * @run junit/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestByteArrayAsInt + * @run junit/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestByteArrayAsInt */ -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; -import java.util.Arrays; -import java.util.EnumSet; import java.util.List; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestByteArrayAsInt extends VarHandleBaseByteArrayTest { static final int SIZE = Integer.BYTES; @@ -107,7 +107,8 @@ public class VarHandleTestByteArrayAsInt extends VarHandleBaseByteArrayTest { } } - @Test(dataProvider = "varHandlesProvider") + @ParameterizedTest + @MethodSource("VarHandleBaseByteArrayTest#varHandlesProvider") public void testIsAccessModeSupported(VarHandleSource vhs) { VarHandle vh = vhs.s; @@ -190,17 +191,16 @@ public class VarHandleTestByteArrayAsInt extends VarHandleBaseByteArrayTest { } } - @Test(dataProvider = "typesProvider") + @ParameterizedTest + @MethodSource("typesProvider") public void testTypes(VarHandle vh, List> pts) { - assertEquals(vh.varType(), int.class); + assertEquals(int.class, vh.varType()); - assertEquals(vh.coordinateTypes(), pts); + assertEquals(pts, vh.coordinateTypes()); testTypes(vh); } - - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -262,7 +262,8 @@ public class VarHandleTestByteArrayAsInt extends VarHandleBaseByteArrayTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -271,7 +272,6 @@ public class VarHandleTestByteArrayAsInt extends VarHandleBaseByteArrayTest { } } - static void testArrayNPE(ByteArraySource bs, VarHandleSource vhs) { VarHandle vh = vhs.s; byte[] array = null; @@ -1039,7 +1039,7 @@ public class VarHandleTestByteArrayAsInt extends VarHandleBaseByteArrayTest { { vh.set(array, i, VALUE_1); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_1, "get int value"); + assertEquals(VALUE_1, x, "get int value"); } } } @@ -1058,7 +1058,7 @@ public class VarHandleTestByteArrayAsInt extends VarHandleBaseByteArrayTest { { vh.set(array, i, VALUE_1); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_1, "get int value"); + assertEquals(VALUE_1, x, "get int value"); } if (iAligned) { @@ -1066,21 +1066,21 @@ public class VarHandleTestByteArrayAsInt extends VarHandleBaseByteArrayTest { { vh.setVolatile(array, i, VALUE_2); int x = (int) vh.getVolatile(array, i); - assertEquals(x, VALUE_2, "setVolatile int value"); + assertEquals(VALUE_2, x, "setVolatile int value"); } // Lazy { vh.setRelease(array, i, VALUE_1); int x = (int) vh.getAcquire(array, i); - assertEquals(x, VALUE_1, "setRelease int value"); + assertEquals(VALUE_1, x, "setRelease int value"); } // Opaque { vh.setOpaque(array, i, VALUE_2); int x = (int) vh.getOpaque(array, i); - assertEquals(x, VALUE_2, "setOpaque int value"); + assertEquals(VALUE_2, x, "setOpaque int value"); } vh.set(array, i, VALUE_1); @@ -1090,56 +1090,56 @@ public class VarHandleTestByteArrayAsInt extends VarHandleBaseByteArrayTest { boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2); assertEquals(r, true, "success compareAndSet int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_2, "success compareAndSet int value"); + assertEquals(VALUE_2, x, "success compareAndSet int value"); } { boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3); assertEquals(r, false, "failing compareAndSet int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_2, "failing compareAndSet int value"); + assertEquals(VALUE_2, x, "failing compareAndSet int value"); } { int r = (int) vh.compareAndExchange(array, i, VALUE_2, VALUE_1); assertEquals(r, VALUE_2, "success compareAndExchange int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_1, "success compareAndExchange int value"); + assertEquals(VALUE_1, x, "success compareAndExchange int value"); } { int r = (int) vh.compareAndExchange(array, i, VALUE_2, VALUE_3); assertEquals(r, VALUE_1, "failing compareAndExchange int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_1, "failing compareAndExchange int value"); + assertEquals(VALUE_1, x, "failing compareAndExchange int value"); } { int r = (int) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2); assertEquals(r, VALUE_1, "success compareAndExchangeAcquire int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_2, "success compareAndExchangeAcquire int value"); + assertEquals(VALUE_2, x, "success compareAndExchangeAcquire int value"); } { int r = (int) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3); assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire int value"); + assertEquals(VALUE_2, x, "failing compareAndExchangeAcquire int value"); } { int r = (int) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1); assertEquals(r, VALUE_2, "success compareAndExchangeRelease int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_1, "success compareAndExchangeRelease int value"); + assertEquals(VALUE_1, x, "success compareAndExchangeRelease int value"); } { int r = (int) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3); assertEquals(r, VALUE_1, "failing compareAndExchangeRelease int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_1, "failing compareAndExchangeRelease int value"); + assertEquals(VALUE_1, x, "failing compareAndExchangeRelease int value"); } { @@ -1150,14 +1150,14 @@ public class VarHandleTestByteArrayAsInt extends VarHandleBaseByteArrayTest { } assertEquals(success, true, "success weakCompareAndSetPlain int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_2, "success weakCompareAndSetPlain int value"); + assertEquals(VALUE_2, x, "success weakCompareAndSetPlain int value"); } { boolean success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_3); assertEquals(success, false, "failing weakCompareAndSetPlain int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_2, "failing weakCompareAndSetPlain int value"); + assertEquals(VALUE_2, x, "failing weakCompareAndSetPlain int value"); } { @@ -1168,14 +1168,14 @@ public class VarHandleTestByteArrayAsInt extends VarHandleBaseByteArrayTest { } assertEquals(success, true, "success weakCompareAndSetAcquire int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_1, "success weakCompareAndSetAcquire int"); + assertEquals(VALUE_1, x, "success weakCompareAndSetAcquire int"); } { boolean success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_3); assertEquals(success, false, "failing weakCompareAndSetAcquire int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_1, "failing weakCompareAndSetAcquire int value"); + assertEquals(VALUE_1, x, "failing weakCompareAndSetAcquire int value"); } { @@ -1186,14 +1186,14 @@ public class VarHandleTestByteArrayAsInt extends VarHandleBaseByteArrayTest { } assertEquals(success, true, "success weakCompareAndSetRelease int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_2, "success weakCompareAndSetRelease int"); + assertEquals(VALUE_2, x, "success weakCompareAndSetRelease int"); } { boolean success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_3); assertEquals(success, false, "failing weakCompareAndSetRelease int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_2, "failing weakCompareAndSetRelease int value"); + assertEquals(VALUE_2, x, "failing weakCompareAndSetRelease int value"); } { @@ -1204,14 +1204,14 @@ public class VarHandleTestByteArrayAsInt extends VarHandleBaseByteArrayTest { } assertEquals(success, true, "success weakCompareAndSet int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_1, "success weakCompareAndSet int"); + assertEquals(VALUE_1, x, "success weakCompareAndSet int"); } { boolean success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_3); assertEquals(success, false, "failing weakCompareAndSet int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_1, "failing weakCompareAndSet int value"); + assertEquals(VALUE_1, x, "failing weakCompareAndSet int value"); } // Compare set and get @@ -1219,27 +1219,27 @@ public class VarHandleTestByteArrayAsInt extends VarHandleBaseByteArrayTest { vh.set(array, i, VALUE_1); int o = (int) vh.getAndSet(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndSet int"); + assertEquals(VALUE_1, o, "getAndSet int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_2, "getAndSet int value"); + assertEquals(VALUE_2, x, "getAndSet int value"); } { vh.set(array, i, VALUE_1); int o = (int) vh.getAndSetAcquire(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndSetAcquire int"); + assertEquals(VALUE_1, o, "getAndSetAcquire int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_2, "getAndSetAcquire int value"); + assertEquals(VALUE_2, x, "getAndSetAcquire int value"); } { vh.set(array, i, VALUE_1); int o = (int) vh.getAndSetRelease(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndSetRelease int"); + assertEquals(VALUE_1, o, "getAndSetRelease int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_2, "getAndSetRelease int value"); + assertEquals(VALUE_2, x, "getAndSetRelease int value"); } // get and add, add and get @@ -1247,27 +1247,27 @@ public class VarHandleTestByteArrayAsInt extends VarHandleBaseByteArrayTest { vh.set(array, i, VALUE_1); int o = (int) vh.getAndAdd(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndAdd int"); + assertEquals(VALUE_1, o, "getAndAdd int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_1 + VALUE_2, "getAndAdd int value"); + assertEquals(VALUE_1 + VALUE_2, x, "getAndAdd int value"); } { vh.set(array, i, VALUE_1); int o = (int) vh.getAndAddAcquire(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndAddAcquire int"); + assertEquals(VALUE_1, o, "getAndAddAcquire int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_1 + VALUE_2, "getAndAddAcquire int value"); + assertEquals(VALUE_1 + VALUE_2, x, "getAndAddAcquire int value"); } { vh.set(array, i, VALUE_1); int o = (int) vh.getAndAddRelease(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndAddRelease int"); + assertEquals(VALUE_1, o, "getAndAddRelease int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_1 + VALUE_2, "getAndAddRelease int value"); + assertEquals(VALUE_1 + VALUE_2, x, "getAndAddRelease int value"); } // get and bitwise or @@ -1275,27 +1275,27 @@ public class VarHandleTestByteArrayAsInt extends VarHandleBaseByteArrayTest { vh.set(array, i, VALUE_1); int o = (int) vh.getAndBitwiseOr(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndBitwiseOr int"); + assertEquals(VALUE_1, o, "getAndBitwiseOr int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_1 | VALUE_2, "getAndBitwiseOr int value"); + assertEquals(VALUE_1 | VALUE_2, x, "getAndBitwiseOr int value"); } { vh.set(array, i, VALUE_1); int o = (int) vh.getAndBitwiseOrAcquire(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndBitwiseOrAcquire int"); + assertEquals(VALUE_1, o, "getAndBitwiseOrAcquire int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_1 | VALUE_2, "getAndBitwiseOrAcquire int value"); + assertEquals(VALUE_1 | VALUE_2, x, "getAndBitwiseOrAcquire int value"); } { vh.set(array, i, VALUE_1); int o = (int) vh.getAndBitwiseOrRelease(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndBitwiseOrRelease int"); + assertEquals(VALUE_1, o, "getAndBitwiseOrRelease int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_1 | VALUE_2, "getAndBitwiseOrRelease int value"); + assertEquals(VALUE_1 | VALUE_2, x, "getAndBitwiseOrRelease int value"); } // get and bitwise and @@ -1303,27 +1303,27 @@ public class VarHandleTestByteArrayAsInt extends VarHandleBaseByteArrayTest { vh.set(array, i, VALUE_1); int o = (int) vh.getAndBitwiseAnd(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndBitwiseAnd int"); + assertEquals(VALUE_1, o, "getAndBitwiseAnd int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_1 & VALUE_2, "getAndBitwiseAnd int value"); + assertEquals(VALUE_1 & VALUE_2, x, "getAndBitwiseAnd int value"); } { vh.set(array, i, VALUE_1); int o = (int) vh.getAndBitwiseAndAcquire(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndBitwiseAndAcquire int"); + assertEquals(VALUE_1, o, "getAndBitwiseAndAcquire int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_1 & VALUE_2, "getAndBitwiseAndAcquire int value"); + assertEquals(VALUE_1 & VALUE_2, x, "getAndBitwiseAndAcquire int value"); } { vh.set(array, i, VALUE_1); int o = (int) vh.getAndBitwiseAndRelease(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndBitwiseAndRelease int"); + assertEquals(VALUE_1, o, "getAndBitwiseAndRelease int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_1 & VALUE_2, "getAndBitwiseAndRelease int value"); + assertEquals(VALUE_1 & VALUE_2, x, "getAndBitwiseAndRelease int value"); } // get and bitwise xor @@ -1331,27 +1331,27 @@ public class VarHandleTestByteArrayAsInt extends VarHandleBaseByteArrayTest { vh.set(array, i, VALUE_1); int o = (int) vh.getAndBitwiseXor(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndBitwiseXor int"); + assertEquals(VALUE_1, o, "getAndBitwiseXor int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_1 ^ VALUE_2, "getAndBitwiseXor int value"); + assertEquals(VALUE_1 ^ VALUE_2, x, "getAndBitwiseXor int value"); } { vh.set(array, i, VALUE_1); int o = (int) vh.getAndBitwiseXorAcquire(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndBitwiseXorAcquire int"); + assertEquals(VALUE_1, o, "getAndBitwiseXorAcquire int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_1 ^ VALUE_2, "getAndBitwiseXorAcquire int value"); + assertEquals(VALUE_1 ^ VALUE_2, x, "getAndBitwiseXorAcquire int value"); } { vh.set(array, i, VALUE_1); int o = (int) vh.getAndBitwiseXorRelease(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndBitwiseXorRelease int"); + assertEquals(VALUE_1, o, "getAndBitwiseXorRelease int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_1 ^ VALUE_2, "getAndBitwiseXorRelease int value"); + assertEquals(VALUE_1 ^ VALUE_2, x, "getAndBitwiseXorRelease int value"); } } } @@ -1375,26 +1375,26 @@ public class VarHandleTestByteArrayAsInt extends VarHandleBaseByteArrayTest { // Plain { int x = (int) vh.get(array, i); - assertEquals(x, v, "get int value"); + assertEquals(v, x, "get int value"); } if (iAligned) { // Volatile { int x = (int) vh.getVolatile(array, i); - assertEquals(x, v, "getVolatile int value"); + assertEquals(v, x, "getVolatile int value"); } // Lazy { int x = (int) vh.getAcquire(array, i); - assertEquals(x, v, "getRelease int value"); + assertEquals(v, x, "getRelease int value"); } // Opaque { int x = (int) vh.getOpaque(array, i); - assertEquals(x, v, "getOpaque int value"); + assertEquals(v, x, "getOpaque int value"); } } } diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java index 4188a51a559..763703b6079 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,25 +26,25 @@ * @bug 8154556 * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations * to hit compilation thresholds - * @run testng/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsLong - * @run testng/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestByteArrayAsLong - * @run testng/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestByteArrayAsLong + * @run junit/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsLong + * @run junit/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestByteArrayAsLong + * @run junit/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestByteArrayAsLong */ -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; -import java.util.Arrays; -import java.util.EnumSet; import java.util.List; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestByteArrayAsLong extends VarHandleBaseByteArrayTest { static final int SIZE = Long.BYTES; @@ -107,7 +107,8 @@ public class VarHandleTestByteArrayAsLong extends VarHandleBaseByteArrayTest { } } - @Test(dataProvider = "varHandlesProvider") + @ParameterizedTest + @MethodSource("VarHandleBaseByteArrayTest#varHandlesProvider") public void testIsAccessModeSupported(VarHandleSource vhs) { VarHandle vh = vhs.s; @@ -190,17 +191,16 @@ public class VarHandleTestByteArrayAsLong extends VarHandleBaseByteArrayTest { } } - @Test(dataProvider = "typesProvider") + @ParameterizedTest + @MethodSource("typesProvider") public void testTypes(VarHandle vh, List> pts) { - assertEquals(vh.varType(), long.class); + assertEquals(long.class, vh.varType()); - assertEquals(vh.coordinateTypes(), pts); + assertEquals(pts, vh.coordinateTypes()); testTypes(vh); } - - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -262,7 +262,8 @@ public class VarHandleTestByteArrayAsLong extends VarHandleBaseByteArrayTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -271,7 +272,6 @@ public class VarHandleTestByteArrayAsLong extends VarHandleBaseByteArrayTest { } } - static void testArrayNPE(ByteArraySource bs, VarHandleSource vhs) { VarHandle vh = vhs.s; byte[] array = null; @@ -1039,7 +1039,7 @@ public class VarHandleTestByteArrayAsLong extends VarHandleBaseByteArrayTest { { vh.set(array, i, VALUE_1); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_1, "get long value"); + assertEquals(VALUE_1, x, "get long value"); } } } @@ -1058,7 +1058,7 @@ public class VarHandleTestByteArrayAsLong extends VarHandleBaseByteArrayTest { { vh.set(array, i, VALUE_1); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_1, "get long value"); + assertEquals(VALUE_1, x, "get long value"); } if (iAligned) { @@ -1066,21 +1066,21 @@ public class VarHandleTestByteArrayAsLong extends VarHandleBaseByteArrayTest { { vh.setVolatile(array, i, VALUE_2); long x = (long) vh.getVolatile(array, i); - assertEquals(x, VALUE_2, "setVolatile long value"); + assertEquals(VALUE_2, x, "setVolatile long value"); } // Lazy { vh.setRelease(array, i, VALUE_1); long x = (long) vh.getAcquire(array, i); - assertEquals(x, VALUE_1, "setRelease long value"); + assertEquals(VALUE_1, x, "setRelease long value"); } // Opaque { vh.setOpaque(array, i, VALUE_2); long x = (long) vh.getOpaque(array, i); - assertEquals(x, VALUE_2, "setOpaque long value"); + assertEquals(VALUE_2, x, "setOpaque long value"); } vh.set(array, i, VALUE_1); @@ -1090,56 +1090,56 @@ public class VarHandleTestByteArrayAsLong extends VarHandleBaseByteArrayTest { boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2); assertEquals(r, true, "success compareAndSet long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_2, "success compareAndSet long value"); + assertEquals(VALUE_2, x, "success compareAndSet long value"); } { boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3); assertEquals(r, false, "failing compareAndSet long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_2, "failing compareAndSet long value"); + assertEquals(VALUE_2, x, "failing compareAndSet long value"); } { long r = (long) vh.compareAndExchange(array, i, VALUE_2, VALUE_1); assertEquals(r, VALUE_2, "success compareAndExchange long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_1, "success compareAndExchange long value"); + assertEquals(VALUE_1, x, "success compareAndExchange long value"); } { long r = (long) vh.compareAndExchange(array, i, VALUE_2, VALUE_3); assertEquals(r, VALUE_1, "failing compareAndExchange long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_1, "failing compareAndExchange long value"); + assertEquals(VALUE_1, x, "failing compareAndExchange long value"); } { long r = (long) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2); assertEquals(r, VALUE_1, "success compareAndExchangeAcquire long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_2, "success compareAndExchangeAcquire long value"); + assertEquals(VALUE_2, x, "success compareAndExchangeAcquire long value"); } { long r = (long) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3); assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire long value"); + assertEquals(VALUE_2, x, "failing compareAndExchangeAcquire long value"); } { long r = (long) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1); assertEquals(r, VALUE_2, "success compareAndExchangeRelease long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_1, "success compareAndExchangeRelease long value"); + assertEquals(VALUE_1, x, "success compareAndExchangeRelease long value"); } { long r = (long) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3); assertEquals(r, VALUE_1, "failing compareAndExchangeRelease long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_1, "failing compareAndExchangeRelease long value"); + assertEquals(VALUE_1, x, "failing compareAndExchangeRelease long value"); } { @@ -1150,14 +1150,14 @@ public class VarHandleTestByteArrayAsLong extends VarHandleBaseByteArrayTest { } assertEquals(success, true, "success weakCompareAndSetPlain long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_2, "success weakCompareAndSetPlain long value"); + assertEquals(VALUE_2, x, "success weakCompareAndSetPlain long value"); } { boolean success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_3); assertEquals(success, false, "failing weakCompareAndSetPlain long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_2, "failing weakCompareAndSetPlain long value"); + assertEquals(VALUE_2, x, "failing weakCompareAndSetPlain long value"); } { @@ -1168,14 +1168,14 @@ public class VarHandleTestByteArrayAsLong extends VarHandleBaseByteArrayTest { } assertEquals(success, true, "success weakCompareAndSetAcquire long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_1, "success weakCompareAndSetAcquire long"); + assertEquals(VALUE_1, x, "success weakCompareAndSetAcquire long"); } { boolean success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_3); assertEquals(success, false, "failing weakCompareAndSetAcquire long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_1, "failing weakCompareAndSetAcquire long value"); + assertEquals(VALUE_1, x, "failing weakCompareAndSetAcquire long value"); } { @@ -1186,14 +1186,14 @@ public class VarHandleTestByteArrayAsLong extends VarHandleBaseByteArrayTest { } assertEquals(success, true, "success weakCompareAndSetRelease long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_2, "success weakCompareAndSetRelease long"); + assertEquals(VALUE_2, x, "success weakCompareAndSetRelease long"); } { boolean success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_3); assertEquals(success, false, "failing weakCompareAndSetRelease long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_2, "failing weakCompareAndSetRelease long value"); + assertEquals(VALUE_2, x, "failing weakCompareAndSetRelease long value"); } { @@ -1204,14 +1204,14 @@ public class VarHandleTestByteArrayAsLong extends VarHandleBaseByteArrayTest { } assertEquals(success, true, "success weakCompareAndSet long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_1, "success weakCompareAndSet long"); + assertEquals(VALUE_1, x, "success weakCompareAndSet long"); } { boolean success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_3); assertEquals(success, false, "failing weakCompareAndSet long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_1, "failing weakCompareAndSet long value"); + assertEquals(VALUE_1, x, "failing weakCompareAndSet long value"); } // Compare set and get @@ -1219,27 +1219,27 @@ public class VarHandleTestByteArrayAsLong extends VarHandleBaseByteArrayTest { vh.set(array, i, VALUE_1); long o = (long) vh.getAndSet(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndSet long"); + assertEquals(VALUE_1, o, "getAndSet long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_2, "getAndSet long value"); + assertEquals(VALUE_2, x, "getAndSet long value"); } { vh.set(array, i, VALUE_1); long o = (long) vh.getAndSetAcquire(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndSetAcquire long"); + assertEquals(VALUE_1, o, "getAndSetAcquire long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_2, "getAndSetAcquire long value"); + assertEquals(VALUE_2, x, "getAndSetAcquire long value"); } { vh.set(array, i, VALUE_1); long o = (long) vh.getAndSetRelease(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndSetRelease long"); + assertEquals(VALUE_1, o, "getAndSetRelease long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_2, "getAndSetRelease long value"); + assertEquals(VALUE_2, x, "getAndSetRelease long value"); } // get and add, add and get @@ -1247,27 +1247,27 @@ public class VarHandleTestByteArrayAsLong extends VarHandleBaseByteArrayTest { vh.set(array, i, VALUE_1); long o = (long) vh.getAndAdd(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndAdd long"); + assertEquals(VALUE_1, o, "getAndAdd long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_1 + VALUE_2, "getAndAdd long value"); + assertEquals(VALUE_1 + VALUE_2, x, "getAndAdd long value"); } { vh.set(array, i, VALUE_1); long o = (long) vh.getAndAddAcquire(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndAddAcquire long"); + assertEquals(VALUE_1, o, "getAndAddAcquire long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_1 + VALUE_2, "getAndAddAcquire long value"); + assertEquals(VALUE_1 + VALUE_2, x, "getAndAddAcquire long value"); } { vh.set(array, i, VALUE_1); long o = (long) vh.getAndAddRelease(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndAddRelease long"); + assertEquals(VALUE_1, o, "getAndAddRelease long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_1 + VALUE_2, "getAndAddRelease long value"); + assertEquals(VALUE_1 + VALUE_2, x, "getAndAddRelease long value"); } // get and bitwise or @@ -1275,27 +1275,27 @@ public class VarHandleTestByteArrayAsLong extends VarHandleBaseByteArrayTest { vh.set(array, i, VALUE_1); long o = (long) vh.getAndBitwiseOr(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndBitwiseOr long"); + assertEquals(VALUE_1, o, "getAndBitwiseOr long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_1 | VALUE_2, "getAndBitwiseOr long value"); + assertEquals(VALUE_1 | VALUE_2, x, "getAndBitwiseOr long value"); } { vh.set(array, i, VALUE_1); long o = (long) vh.getAndBitwiseOrAcquire(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndBitwiseOrAcquire long"); + assertEquals(VALUE_1, o, "getAndBitwiseOrAcquire long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_1 | VALUE_2, "getAndBitwiseOrAcquire long value"); + assertEquals(VALUE_1 | VALUE_2, x, "getAndBitwiseOrAcquire long value"); } { vh.set(array, i, VALUE_1); long o = (long) vh.getAndBitwiseOrRelease(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndBitwiseOrRelease long"); + assertEquals(VALUE_1, o, "getAndBitwiseOrRelease long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_1 | VALUE_2, "getAndBitwiseOrRelease long value"); + assertEquals(VALUE_1 | VALUE_2, x, "getAndBitwiseOrRelease long value"); } // get and bitwise and @@ -1303,27 +1303,27 @@ public class VarHandleTestByteArrayAsLong extends VarHandleBaseByteArrayTest { vh.set(array, i, VALUE_1); long o = (long) vh.getAndBitwiseAnd(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndBitwiseAnd long"); + assertEquals(VALUE_1, o, "getAndBitwiseAnd long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_1 & VALUE_2, "getAndBitwiseAnd long value"); + assertEquals(VALUE_1 & VALUE_2, x, "getAndBitwiseAnd long value"); } { vh.set(array, i, VALUE_1); long o = (long) vh.getAndBitwiseAndAcquire(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndBitwiseAndAcquire long"); + assertEquals(VALUE_1, o, "getAndBitwiseAndAcquire long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_1 & VALUE_2, "getAndBitwiseAndAcquire long value"); + assertEquals(VALUE_1 & VALUE_2, x, "getAndBitwiseAndAcquire long value"); } { vh.set(array, i, VALUE_1); long o = (long) vh.getAndBitwiseAndRelease(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndBitwiseAndRelease long"); + assertEquals(VALUE_1, o, "getAndBitwiseAndRelease long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_1 & VALUE_2, "getAndBitwiseAndRelease long value"); + assertEquals(VALUE_1 & VALUE_2, x, "getAndBitwiseAndRelease long value"); } // get and bitwise xor @@ -1331,27 +1331,27 @@ public class VarHandleTestByteArrayAsLong extends VarHandleBaseByteArrayTest { vh.set(array, i, VALUE_1); long o = (long) vh.getAndBitwiseXor(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndBitwiseXor long"); + assertEquals(VALUE_1, o, "getAndBitwiseXor long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_1 ^ VALUE_2, "getAndBitwiseXor long value"); + assertEquals(VALUE_1 ^ VALUE_2, x, "getAndBitwiseXor long value"); } { vh.set(array, i, VALUE_1); long o = (long) vh.getAndBitwiseXorAcquire(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndBitwiseXorAcquire long"); + assertEquals(VALUE_1, o, "getAndBitwiseXorAcquire long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_1 ^ VALUE_2, "getAndBitwiseXorAcquire long value"); + assertEquals(VALUE_1 ^ VALUE_2, x, "getAndBitwiseXorAcquire long value"); } { vh.set(array, i, VALUE_1); long o = (long) vh.getAndBitwiseXorRelease(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndBitwiseXorRelease long"); + assertEquals(VALUE_1, o, "getAndBitwiseXorRelease long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_1 ^ VALUE_2, "getAndBitwiseXorRelease long value"); + assertEquals(VALUE_1 ^ VALUE_2, x, "getAndBitwiseXorRelease long value"); } } } @@ -1375,26 +1375,26 @@ public class VarHandleTestByteArrayAsLong extends VarHandleBaseByteArrayTest { // Plain { long x = (long) vh.get(array, i); - assertEquals(x, v, "get long value"); + assertEquals(v, x, "get long value"); } if (iAligned) { // Volatile { long x = (long) vh.getVolatile(array, i); - assertEquals(x, v, "getVolatile long value"); + assertEquals(v, x, "getVolatile long value"); } // Lazy { long x = (long) vh.getAcquire(array, i); - assertEquals(x, v, "getRelease long value"); + assertEquals(v, x, "getRelease long value"); } // Opaque { long x = (long) vh.getOpaque(array, i); - assertEquals(x, v, "getOpaque long value"); + assertEquals(v, x, "getOpaque long value"); } } } diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsShort.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsShort.java index 1ecfef0476e..7a3bc069c22 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsShort.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsShort.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,25 +26,25 @@ * @bug 8154556 * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations * to hit compilation thresholds - * @run testng/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsShort - * @run testng/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestByteArrayAsShort - * @run testng/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestByteArrayAsShort + * @run junit/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsShort + * @run junit/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestByteArrayAsShort + * @run junit/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestByteArrayAsShort */ -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; -import java.util.Arrays; -import java.util.EnumSet; import java.util.List; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest { static final int SIZE = Short.BYTES; @@ -107,7 +107,8 @@ public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest { } } - @Test(dataProvider = "varHandlesProvider") + @ParameterizedTest + @MethodSource("VarHandleBaseByteArrayTest#varHandlesProvider") public void testIsAccessModeSupported(VarHandleSource vhs) { VarHandle vh = vhs.s; @@ -158,17 +159,16 @@ public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest { assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE)); } - @Test(dataProvider = "typesProvider") + @ParameterizedTest + @MethodSource("typesProvider") public void testTypes(VarHandle vh, List> pts) { - assertEquals(vh.varType(), short.class); + assertEquals(short.class, vh.varType()); - assertEquals(vh.coordinateTypes(), pts); + assertEquals(pts, vh.coordinateTypes()); testTypes(vh); } - - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -230,7 +230,8 @@ public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -239,7 +240,6 @@ public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest { } } - static void testArrayNPE(ByteArraySource bs, VarHandleSource vhs) { VarHandle vh = vhs.s; byte[] array = null; @@ -740,7 +740,7 @@ public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest { { vh.set(array, i, VALUE_1); short x = (short) vh.get(array, i); - assertEquals(x, VALUE_1, "get short value"); + assertEquals(VALUE_1, x, "get short value"); } } } @@ -759,7 +759,7 @@ public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest { { vh.set(array, i, VALUE_1); short x = (short) vh.get(array, i); - assertEquals(x, VALUE_1, "get short value"); + assertEquals(VALUE_1, x, "get short value"); } if (iAligned) { @@ -767,21 +767,21 @@ public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest { { vh.setVolatile(array, i, VALUE_2); short x = (short) vh.getVolatile(array, i); - assertEquals(x, VALUE_2, "setVolatile short value"); + assertEquals(VALUE_2, x, "setVolatile short value"); } // Lazy { vh.setRelease(array, i, VALUE_1); short x = (short) vh.getAcquire(array, i); - assertEquals(x, VALUE_1, "setRelease short value"); + assertEquals(VALUE_1, x, "setRelease short value"); } // Opaque { vh.setOpaque(array, i, VALUE_2); short x = (short) vh.getOpaque(array, i); - assertEquals(x, VALUE_2, "setOpaque short value"); + assertEquals(VALUE_2, x, "setOpaque short value"); } @@ -807,26 +807,26 @@ public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest { // Plain { short x = (short) vh.get(array, i); - assertEquals(x, v, "get short value"); + assertEquals(v, x, "get short value"); } if (iAligned) { // Volatile { short x = (short) vh.getVolatile(array, i); - assertEquals(x, v, "getVolatile short value"); + assertEquals(v, x, "getVolatile short value"); } // Lazy { short x = (short) vh.getAcquire(array, i); - assertEquals(x, v, "getRelease short value"); + assertEquals(v, x, "getRelease short value"); } // Opaque { short x = (short) vh.getOpaque(array, i); - assertEquals(x, v, "getOpaque short value"); + assertEquals(v, x, "getOpaque short value"); } } } diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestExact.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestExact.java index fc706815bce..9960e08a0c7 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestExact.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestExact.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,20 +26,20 @@ * @modules java.base/jdk.internal.access.foreign * @modules java.base/jdk.internal.foreign.layout * - * @run testng/othervm -Xverify:all + * @run junit/othervm -Xverify:all * -Djdk.internal.foreign.SHOULD_ADAPT_HANDLES=false * VarHandleTestExact - * @run testng/othervm -Xverify:all + * @run junit/othervm -Xverify:all * -Djdk.internal.foreign.SHOULD_ADAPT_HANDLES=false * -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=true * -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true * VarHandleTestExact - * @run testng/othervm -Xverify:all + * @run junit/othervm -Xverify:all * -Djdk.internal.foreign.SHOULD_ADAPT_HANDLES=false * -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false * -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=false * VarHandleTestExact - * @run testng/othervm -Xverify:all + * @run junit/othervm -Xverify:all * -Djdk.internal.foreign.SHOULD_ADAPT_HANDLES=false * -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false * -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true @@ -50,9 +50,6 @@ import java.lang.foreign.Arena; import java.lang.foreign.MemorySegment; import jdk.internal.foreign.layout.ValueLayouts; -import org.testng.SkipException; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; @@ -64,8 +61,13 @@ import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestExact { private static class Widget { @@ -90,12 +92,13 @@ public class VarHandleTestExact { final Long aLongField_RO = 1234L; } - @Test(dataProvider = "dataObjectAccess") + @ParameterizedTest + @MethodSource("dataObjectAccess") public void testExactSet(String fieldBaseName, Class fieldType, boolean ro, Object testValue, SetX setter, GetX getter, SetStaticX staticSetter, GetStaticX staticGetter) throws NoSuchFieldException, IllegalAccessException { - if (ro) throw new SkipException("Can not test setter with read only field"); + Assumptions.assumeFalse(ro, "Can not test setter with read only field"); VarHandle vh = MethodHandles.lookup().findVarHandle(Widget.class, fieldBaseName + "_RW", fieldType); Widget w = new Widget(); @@ -105,7 +108,8 @@ public class VarHandleTestExact { ".*\\Qhandle's method type (Widget," + fieldType.getSimpleName() + ")void \\E.*"); } - @Test(dataProvider = "dataObjectAccess") + @ParameterizedTest + @MethodSource("dataObjectAccess") public void testExactGet(String fieldBaseName, Class fieldType, boolean ro, Object testValue, SetX setter, GetX getter, SetStaticX staticSetter, GetStaticX staticGetter) @@ -119,12 +123,13 @@ public class VarHandleTestExact { ".*\\Qhandle's method type (Widget)" + fieldType.getSimpleName() + " \\E.*"); } - @Test(dataProvider = "dataObjectAccess") + @ParameterizedTest + @MethodSource("dataObjectAccess") public void testExactSetStatic(String fieldBaseName, Class fieldType, boolean ro, Object testValue, SetX setter, GetX getter, SetStaticX staticSetter, GetStaticX staticGetter) throws NoSuchFieldException, IllegalAccessException { - if (ro) throw new SkipException("Can not test setter with read only field"); + Assumptions.assumeFalse(ro, "Can not test setter with read only field"); VarHandle vh = MethodHandles.lookup().findStaticVarHandle(Widget.class, fieldBaseName + "_SRW", fieldType); doTest(vh, @@ -133,7 +138,8 @@ public class VarHandleTestExact { ".*\\Qhandle's method type (" + fieldType.getSimpleName() + ")void \\E.*"); } - @Test(dataProvider = "dataObjectAccess") + @ParameterizedTest + @MethodSource("dataObjectAccess") public void testExactGetStatic(String fieldBaseName, Class fieldType, boolean ro, Object testValue, SetX setter, GetX getter, SetStaticX staticSetter, GetStaticX staticGetter) @@ -146,7 +152,8 @@ public class VarHandleTestExact { ".*\\Qhandle's method type ()" + fieldType.getSimpleName() + " \\E.*"); } - @Test(dataProvider = "dataSetArray") + @ParameterizedTest + @MethodSource("dataSetArray") public void testExactArraySet(Class arrayClass, Object testValue, SetArrayX setter) { VarHandle vh = MethodHandles.arrayElementVarHandle(arrayClass); Object arr = Array.newInstance(arrayClass.componentType(), 1); @@ -157,7 +164,8 @@ public class VarHandleTestExact { ".*\\Qhandle's method type (" + arrayClass.getSimpleName() + ",int," + arrayClass.componentType().getSimpleName() + ")void \\E.*"); } - @Test(dataProvider = "dataSetBuffer") + @ParameterizedTest + @MethodSource("dataSetBuffer") public void testExactBufferSet(Class arrayClass, Object testValue, SetBufferX setter) { VarHandle vh = MethodHandles.byteBufferViewVarHandle(arrayClass, ByteOrder.nativeOrder()); ByteBuffer buff = ByteBuffer.allocateDirect(8); @@ -168,7 +176,8 @@ public class VarHandleTestExact { ".*\\Qhandle's method type (ByteBuffer,int," + arrayClass.componentType().getSimpleName() + ")void \\E.*"); } - @Test(dataProvider = "dataSetMemorySegment") + @ParameterizedTest + @MethodSource("dataSetMemorySegment") public void testExactSegmentSet(Class carrier, Object testValue, SetSegmentX setter) { VarHandle vh = ValueLayouts.valueLayout(carrier, ByteOrder.nativeOrder()).varHandle(); try (Arena arena = Arena.ofConfined()) { @@ -265,7 +274,6 @@ public class VarHandleTestExact { cases.add(new Object[] { carrier, testValue, setter }); } - @DataProvider public static Object[][] dataObjectAccess() { List cases = new ArrayList<>(); @@ -334,7 +342,6 @@ public class VarHandleTestExact { return cases.toArray(Object[][]::new); } - @DataProvider public static Object[][] dataSetArray() { List cases = new ArrayList<>(); @@ -355,7 +362,6 @@ public class VarHandleTestExact { return cases.toArray(Object[][]::new); } - @DataProvider public static Object[][] dataSetBuffer() { List cases = new ArrayList<>(); @@ -373,7 +379,6 @@ public class VarHandleTestExact { return cases.toArray(Object[][]::new); } - @DataProvider public static Object[][] dataSetMemorySegment() { List cases = new ArrayList<>(); diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessBoolean.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessBoolean.java index 14d5c05d3b8..6540693a906 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessBoolean.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessBoolean.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,22 +25,22 @@ * @test * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations * to hit compilation thresholds - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestMethodHandleAccessBoolean + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestMethodHandleAccessBoolean */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { static final boolean static_final_v = true; @@ -60,7 +60,7 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { VarHandle vhArray; - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestMethodHandleAccessBoolean.class, "final_v", boolean.class); @@ -77,8 +77,6 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { vhArray = MethodHandles.arrayElementVarHandle(boolean[].class); } - - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -111,7 +109,8 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -120,13 +119,12 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { } } - static void testInstanceField(VarHandleTestMethodHandleAccessBoolean recv, Handles hs) throws Throwable { // Plain { hs.get(TestAccessMode.SET).invokeExact(recv, true); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, true, "set boolean value"); + assertEquals(true, x, "set boolean value"); } @@ -134,21 +132,21 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact(recv, false); boolean x = (boolean) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(recv); - assertEquals(x, false, "setVolatile boolean value"); + assertEquals(false, x, "setVolatile boolean value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact(recv, true); boolean x = (boolean) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(recv); - assertEquals(x, true, "setRelease boolean value"); + assertEquals(true, x, "setRelease boolean value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact(recv, false); boolean x = (boolean) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(recv); - assertEquals(x, false, "setOpaque boolean value"); + assertEquals(false, x, "setOpaque boolean value"); } hs.get(TestAccessMode.SET).invokeExact(recv, true); @@ -158,56 +156,56 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, true, false); assertEquals(r, true, "success compareAndSet boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, false, "success compareAndSet boolean value"); + assertEquals(false, x, "success compareAndSet boolean value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, true, false); assertEquals(r, false, "failing compareAndSet boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, false, "failing compareAndSet boolean value"); + assertEquals(false, x, "failing compareAndSet boolean value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, false, true); assertEquals(r, false, "success compareAndExchange boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, true, "success compareAndExchange boolean value"); + assertEquals(true, x, "success compareAndExchange boolean value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, false, false); assertEquals(r, true, "failing compareAndExchange boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, true, "failing compareAndExchange boolean value"); + assertEquals(true, x, "failing compareAndExchange boolean value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, true, false); assertEquals(r, true, "success compareAndExchangeAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, false, "success compareAndExchangeAcquire boolean value"); + assertEquals(false, x, "success compareAndExchangeAcquire boolean value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, true, false); assertEquals(r, false, "failing compareAndExchangeAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, false, "failing compareAndExchangeAcquire boolean value"); + assertEquals(false, x, "failing compareAndExchangeAcquire boolean value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, false, true); assertEquals(r, false, "success compareAndExchangeRelease boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, true, "success compareAndExchangeRelease boolean value"); + assertEquals(true, x, "success compareAndExchangeRelease boolean value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, false, false); assertEquals(r, true, "failing compareAndExchangeRelease boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, true, "failing compareAndExchangeRelease boolean value"); + assertEquals(true, x, "failing compareAndExchangeRelease boolean value"); } { @@ -219,14 +217,14 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, false, "success weakCompareAndSetPlain boolean value"); + assertEquals(false, x, "success weakCompareAndSetPlain boolean value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, true, false); assertEquals(success, false, "failing weakCompareAndSetPlain boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, false, "failing weakCompareAndSetPlain boolean value"); + assertEquals(false, x, "failing weakCompareAndSetPlain boolean value"); } { @@ -238,14 +236,14 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, true, "success weakCompareAndSetAcquire boolean"); + assertEquals(true, x, "success weakCompareAndSetAcquire boolean"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, false, false); assertEquals(success, false, "failing weakCompareAndSetAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, true, "failing weakCompareAndSetAcquire boolean value"); + assertEquals(true, x, "failing weakCompareAndSetAcquire boolean value"); } { @@ -257,14 +255,14 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, false, "success weakCompareAndSetRelease boolean"); + assertEquals(false, x, "success weakCompareAndSetRelease boolean"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, true, false); assertEquals(success, false, "failing weakCompareAndSetRelease boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, false, "failing weakCompareAndSetRelease boolean value"); + assertEquals(false, x, "failing weakCompareAndSetRelease boolean value"); } { @@ -276,22 +274,22 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, true, "success weakCompareAndSet boolean"); + assertEquals(true, x, "success weakCompareAndSet boolean"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, false, false); assertEquals(success, false, "failing weakCompareAndSet boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, true, "failing weakCompareAndSet boolean value"); + assertEquals(true, x, "failing weakCompareAndSet boolean value"); } // Compare set and get { boolean o = (boolean) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, false); - assertEquals(o, true, "getAndSet boolean"); + assertEquals(true, o, "getAndSet boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, false, "getAndSet boolean value"); + assertEquals(false, x, "getAndSet boolean value"); } @@ -300,27 +298,27 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(recv, true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_BITWISE_OR).invokeExact(recv, false); - assertEquals(o, true, "getAndBitwiseOr boolean"); + assertEquals(true, o, "getAndBitwiseOr boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (boolean)(true | false), "getAndBitwiseOr boolean value"); + assertEquals((boolean)(true | false), x, "getAndBitwiseOr boolean value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_BITWISE_OR_ACQUIRE).invokeExact(recv, false); - assertEquals(o, true, "getAndBitwiseOrAcquire boolean"); + assertEquals(true, o, "getAndBitwiseOrAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (boolean)(true | false), "getAndBitwiseOrAcquire boolean value"); + assertEquals((boolean)(true | false), x, "getAndBitwiseOrAcquire boolean value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_BITWISE_OR_RELEASE).invokeExact(recv, false); - assertEquals(o, true, "getAndBitwiseOrRelease boolean"); + assertEquals(true, o, "getAndBitwiseOrRelease boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (boolean)(true | false), "getAndBitwiseOrRelease boolean value"); + assertEquals((boolean)(true | false), x, "getAndBitwiseOrRelease boolean value"); } // get and bitwise and @@ -328,27 +326,27 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(recv, true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_BITWISE_AND).invokeExact(recv, false); - assertEquals(o, true, "getAndBitwiseAnd boolean"); + assertEquals(true, o, "getAndBitwiseAnd boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (boolean)(true & false), "getAndBitwiseAnd boolean value"); + assertEquals((boolean)(true & false), x, "getAndBitwiseAnd boolean value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_BITWISE_AND_ACQUIRE).invokeExact(recv, false); - assertEquals(o, true, "getAndBitwiseAndAcquire boolean"); + assertEquals(true, o, "getAndBitwiseAndAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (boolean)(true & false), "getAndBitwiseAndAcquire boolean value"); + assertEquals((boolean)(true & false), x, "getAndBitwiseAndAcquire boolean value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_BITWISE_AND_RELEASE).invokeExact(recv, false); - assertEquals(o, true, "getAndBitwiseAndRelease boolean"); + assertEquals(true, o, "getAndBitwiseAndRelease boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (boolean)(true & false), "getAndBitwiseAndRelease boolean value"); + assertEquals((boolean)(true & false), x, "getAndBitwiseAndRelease boolean value"); } // get and bitwise xor @@ -356,27 +354,27 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(recv, true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_BITWISE_XOR).invokeExact(recv, false); - assertEquals(o, true, "getAndBitwiseXor boolean"); + assertEquals(true, o, "getAndBitwiseXor boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (boolean)(true ^ false), "getAndBitwiseXor boolean value"); + assertEquals((boolean)(true ^ false), x, "getAndBitwiseXor boolean value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_ACQUIRE).invokeExact(recv, false); - assertEquals(o, true, "getAndBitwiseXorAcquire boolean"); + assertEquals(true, o, "getAndBitwiseXorAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (boolean)(true ^ false), "getAndBitwiseXorAcquire boolean value"); + assertEquals((boolean)(true ^ false), x, "getAndBitwiseXorAcquire boolean value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_RELEASE).invokeExact(recv, false); - assertEquals(o, true, "getAndBitwiseXorRelease boolean"); + assertEquals(true, o, "getAndBitwiseXorRelease boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (boolean)(true ^ false), "getAndBitwiseXorRelease boolean value"); + assertEquals((boolean)(true ^ false), x, "getAndBitwiseXorRelease boolean value"); } } @@ -396,7 +394,7 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { { hs.get(TestAccessMode.SET).invokeExact(true); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, true, "set boolean value"); + assertEquals(true, x, "set boolean value"); } @@ -404,21 +402,21 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact(false); boolean x = (boolean) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(); - assertEquals(x, false, "setVolatile boolean value"); + assertEquals(false, x, "setVolatile boolean value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact(true); boolean x = (boolean) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(); - assertEquals(x, true, "setRelease boolean value"); + assertEquals(true, x, "setRelease boolean value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact(false); boolean x = (boolean) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(); - assertEquals(x, false, "setOpaque boolean value"); + assertEquals(false, x, "setOpaque boolean value"); } hs.get(TestAccessMode.SET).invokeExact(true); @@ -428,56 +426,56 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(true, false); assertEquals(r, true, "success compareAndSet boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, false, "success compareAndSet boolean value"); + assertEquals(false, x, "success compareAndSet boolean value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(true, false); assertEquals(r, false, "failing compareAndSet boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, false, "failing compareAndSet boolean value"); + assertEquals(false, x, "failing compareAndSet boolean value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(false, true); assertEquals(r, false, "success compareAndExchange boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, true, "success compareAndExchange boolean value"); + assertEquals(true, x, "success compareAndExchange boolean value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(false, false); assertEquals(r, true, "failing compareAndExchange boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, true, "failing compareAndExchange boolean value"); + assertEquals(true, x, "failing compareAndExchange boolean value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(true, false); assertEquals(r, true, "success compareAndExchangeAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, false, "success compareAndExchangeAcquire boolean value"); + assertEquals(false, x, "success compareAndExchangeAcquire boolean value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(true, false); assertEquals(r, false, "failing compareAndExchangeAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, false, "failing compareAndExchangeAcquire boolean value"); + assertEquals(false, x, "failing compareAndExchangeAcquire boolean value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(false, true); assertEquals(r, false, "success compareAndExchangeRelease boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, true, "success compareAndExchangeRelease boolean value"); + assertEquals(true, x, "success compareAndExchangeRelease boolean value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(false, false); assertEquals(r, true, "failing compareAndExchangeRelease boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, true, "failing compareAndExchangeRelease boolean value"); + assertEquals(true, x, "failing compareAndExchangeRelease boolean value"); } { @@ -489,14 +487,14 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, false, "success weakCompareAndSetPlain boolean value"); + assertEquals(false, x, "success weakCompareAndSetPlain boolean value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(true, false); assertEquals(success, false, "failing weakCompareAndSetPlain boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, false, "failing weakCompareAndSetPlain boolean value"); + assertEquals(false, x, "failing weakCompareAndSetPlain boolean value"); } { @@ -508,7 +506,7 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, true, "success weakCompareAndSetAcquire boolean"); + assertEquals(true, x, "success weakCompareAndSetAcquire boolean"); } { @@ -516,7 +514,7 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { boolean success = (boolean) mh.invokeExact(false, false); assertEquals(success, false, "failing weakCompareAndSetAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, true, "failing weakCompareAndSetAcquire boolean value"); + assertEquals(true, x, "failing weakCompareAndSetAcquire boolean value"); } { @@ -528,14 +526,14 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, false, "success weakCompareAndSetRelease boolean"); + assertEquals(false, x, "success weakCompareAndSetRelease boolean"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(true, false); assertEquals(success, false, "failing weakCompareAndSetRelease boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, false, "failing weakCompareAndSetRelease boolean value"); + assertEquals(false, x, "failing weakCompareAndSetRelease boolean value"); } { @@ -547,14 +545,14 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, true, "success weakCompareAndSet boolean"); + assertEquals(true, x, "success weakCompareAndSet boolean"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(false, false); assertEquals(success, false, "failing weakCompareAndSet boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, true, "failing weakCompareAndSetRe boolean value"); + assertEquals(true, x, "failing weakCompareAndSetRe boolean value"); } // Compare set and get @@ -562,9 +560,9 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_SET).invokeExact(false); - assertEquals(o, true, "getAndSet boolean"); + assertEquals(true, o, "getAndSet boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, false, "getAndSet boolean value"); + assertEquals(false, x, "getAndSet boolean value"); } // Compare set and get @@ -572,9 +570,9 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact(false); - assertEquals(o, true, "getAndSetAcquire boolean"); + assertEquals(true, o, "getAndSetAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, false, "getAndSetAcquire boolean value"); + assertEquals(false, x, "getAndSetAcquire boolean value"); } // Compare set and get @@ -582,9 +580,9 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact(false); - assertEquals(o, true, "getAndSetRelease boolean"); + assertEquals(true, o, "getAndSetRelease boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, false, "getAndSetRelease boolean value"); + assertEquals(false, x, "getAndSetRelease boolean value"); } @@ -593,27 +591,27 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_BITWISE_OR).invokeExact(false); - assertEquals(o, true, "getAndBitwiseOr boolean"); + assertEquals(true, o, "getAndBitwiseOr boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (boolean)(true | false), "getAndBitwiseOr boolean value"); + assertEquals((boolean)(true | false), x, "getAndBitwiseOr boolean value"); } { hs.get(TestAccessMode.SET).invokeExact(true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_BITWISE_OR_ACQUIRE).invokeExact(false); - assertEquals(o, true, "getAndBitwiseOrAcquire boolean"); + assertEquals(true, o, "getAndBitwiseOrAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (boolean)(true | false), "getAndBitwiseOrAcquire boolean value"); + assertEquals((boolean)(true | false), x, "getAndBitwiseOrAcquire boolean value"); } { hs.get(TestAccessMode.SET).invokeExact(true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_BITWISE_OR_RELEASE).invokeExact(false); - assertEquals(o, true, "getAndBitwiseOrRelease boolean"); + assertEquals(true, o, "getAndBitwiseOrRelease boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (boolean)(true | false), "getAndBitwiseOrRelease boolean value"); + assertEquals((boolean)(true | false), x, "getAndBitwiseOrRelease boolean value"); } // get and bitwise and @@ -621,27 +619,27 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_BITWISE_AND).invokeExact(false); - assertEquals(o, true, "getAndBitwiseAnd boolean"); + assertEquals(true, o, "getAndBitwiseAnd boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (boolean)(true & false), "getAndBitwiseAnd boolean value"); + assertEquals((boolean)(true & false), x, "getAndBitwiseAnd boolean value"); } { hs.get(TestAccessMode.SET).invokeExact(true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_BITWISE_AND_ACQUIRE).invokeExact(false); - assertEquals(o, true, "getAndBitwiseAndAcquire boolean"); + assertEquals(true, o, "getAndBitwiseAndAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (boolean)(true & false), "getAndBitwiseAndAcquire boolean value"); + assertEquals((boolean)(true & false), x, "getAndBitwiseAndAcquire boolean value"); } { hs.get(TestAccessMode.SET).invokeExact(true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_BITWISE_AND_RELEASE).invokeExact(false); - assertEquals(o, true, "getAndBitwiseAndRelease boolean"); + assertEquals(true, o, "getAndBitwiseAndRelease boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (boolean)(true & false), "getAndBitwiseAndRelease boolean value"); + assertEquals((boolean)(true & false), x, "getAndBitwiseAndRelease boolean value"); } // get and bitwise xor @@ -649,27 +647,27 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_BITWISE_XOR).invokeExact(false); - assertEquals(o, true, "getAndBitwiseXor boolean"); + assertEquals(true, o, "getAndBitwiseXor boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (boolean)(true ^ false), "getAndBitwiseXor boolean value"); + assertEquals((boolean)(true ^ false), x, "getAndBitwiseXor boolean value"); } { hs.get(TestAccessMode.SET).invokeExact(true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_ACQUIRE).invokeExact(false); - assertEquals(o, true, "getAndBitwiseXorAcquire boolean"); + assertEquals(true, o, "getAndBitwiseXorAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (boolean)(true ^ false), "getAndBitwiseXorAcquire boolean value"); + assertEquals((boolean)(true ^ false), x, "getAndBitwiseXorAcquire boolean value"); } { hs.get(TestAccessMode.SET).invokeExact(true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_RELEASE).invokeExact(false); - assertEquals(o, true, "getAndBitwiseXorRelease boolean"); + assertEquals(true, o, "getAndBitwiseXorRelease boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (boolean)(true ^ false), "getAndBitwiseXorRelease boolean value"); + assertEquals((boolean)(true ^ false), x, "getAndBitwiseXorRelease boolean value"); } } @@ -692,7 +690,7 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { { hs.get(TestAccessMode.SET).invokeExact(array, i, true); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, true, "get boolean value"); + assertEquals(true, x, "get boolean value"); } @@ -700,21 +698,21 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact(array, i, false); boolean x = (boolean) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(array, i); - assertEquals(x, false, "setVolatile boolean value"); + assertEquals(false, x, "setVolatile boolean value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact(array, i, true); boolean x = (boolean) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(array, i); - assertEquals(x, true, "setRelease boolean value"); + assertEquals(true, x, "setRelease boolean value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact(array, i, false); boolean x = (boolean) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(array, i); - assertEquals(x, false, "setOpaque boolean value"); + assertEquals(false, x, "setOpaque boolean value"); } hs.get(TestAccessMode.SET).invokeExact(array, i, true); @@ -724,56 +722,56 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, true, false); assertEquals(r, true, "success compareAndSet boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, false, "success compareAndSet boolean value"); + assertEquals(false, x, "success compareAndSet boolean value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, true, false); assertEquals(r, false, "failing compareAndSet boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, false, "failing compareAndSet boolean value"); + assertEquals(false, x, "failing compareAndSet boolean value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, false, true); assertEquals(r, false, "success compareAndExchange boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, true, "success compareAndExchange boolean value"); + assertEquals(true, x, "success compareAndExchange boolean value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, false, false); assertEquals(r, true, "failing compareAndExchange boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, true, "failing compareAndExchange boolean value"); + assertEquals(true, x, "failing compareAndExchange boolean value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, true, false); assertEquals(r, true, "success compareAndExchangeAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, false, "success compareAndExchangeAcquire boolean value"); + assertEquals(false, x, "success compareAndExchangeAcquire boolean value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, true, false); assertEquals(r, false, "failing compareAndExchangeAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, false, "failing compareAndExchangeAcquire boolean value"); + assertEquals(false, x, "failing compareAndExchangeAcquire boolean value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, false, true); assertEquals(r, false, "success compareAndExchangeRelease boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, true, "success compareAndExchangeRelease boolean value"); + assertEquals(true, x, "success compareAndExchangeRelease boolean value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, false, false); assertEquals(r, true, "failing compareAndExchangeRelease boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, true, "failing compareAndExchangeRelease boolean value"); + assertEquals(true, x, "failing compareAndExchangeRelease boolean value"); } { @@ -785,14 +783,14 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, false, "success weakCompareAndSetPlain boolean value"); + assertEquals(false, x, "success weakCompareAndSetPlain boolean value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, true, false); assertEquals(success, false, "failing weakCompareAndSetPlain boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, false, "failing weakCompareAndSetPlain boolean value"); + assertEquals(false, x, "failing weakCompareAndSetPlain boolean value"); } { @@ -804,14 +802,14 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, true, "success weakCompareAndSetAcquire boolean"); + assertEquals(true, x, "success weakCompareAndSetAcquire boolean"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, false, false); assertEquals(success, false, "failing weakCompareAndSetAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, true, "failing weakCompareAndSetAcquire boolean value"); + assertEquals(true, x, "failing weakCompareAndSetAcquire boolean value"); } { @@ -823,14 +821,14 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, false, "success weakCompareAndSetRelease boolean"); + assertEquals(false, x, "success weakCompareAndSetRelease boolean"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, true, false); assertEquals(success, false, "failing weakCompareAndSetAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, false, "failing weakCompareAndSetAcquire boolean value"); + assertEquals(false, x, "failing weakCompareAndSetAcquire boolean value"); } { @@ -842,14 +840,14 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, true, "success weakCompareAndSet boolean"); + assertEquals(true, x, "success weakCompareAndSet boolean"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, false, false); assertEquals(success, false, "failing weakCompareAndSet boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, true, "failing weakCompareAndSet boolean value"); + assertEquals(true, x, "failing weakCompareAndSet boolean value"); } // Compare set and get @@ -857,27 +855,27 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, false); - assertEquals(o, true, "getAndSet boolean"); + assertEquals(true, o, "getAndSet boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, false, "getAndSet boolean value"); + assertEquals(false, x, "getAndSet boolean value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact(array, i, false); - assertEquals(o, true, "getAndSetAcquire boolean"); + assertEquals(true, o, "getAndSetAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, false, "getAndSetAcquire boolean value"); + assertEquals(false, x, "getAndSetAcquire boolean value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact(array, i, false); - assertEquals(o, true, "getAndSetRelease boolean"); + assertEquals(true, o, "getAndSetRelease boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, false, "getAndSetRelease boolean value"); + assertEquals(false, x, "getAndSetRelease boolean value"); } @@ -886,27 +884,27 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_BITWISE_OR).invokeExact(array, i, false); - assertEquals(o, true, "getAndBitwiseOr boolean"); + assertEquals(true, o, "getAndBitwiseOr boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (boolean)(true | false), "getAndBitwiseOr boolean value"); + assertEquals((boolean)(true | false), x, "getAndBitwiseOr boolean value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_BITWISE_OR_ACQUIRE).invokeExact(array, i, false); - assertEquals(o, true, "getAndBitwiseOrAcquire boolean"); + assertEquals(true, o, "getAndBitwiseOrAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (boolean)(true | false), "getAndBitwiseOrAcquire boolean value"); + assertEquals((boolean)(true | false), x, "getAndBitwiseOrAcquire boolean value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_BITWISE_OR_RELEASE).invokeExact(array, i, false); - assertEquals(o, true, "getAndBitwiseOrRelease boolean"); + assertEquals(true, o, "getAndBitwiseOrRelease boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (boolean)(true | false), "getAndBitwiseOrRelease boolean value"); + assertEquals((boolean)(true | false), x, "getAndBitwiseOrRelease boolean value"); } // get and bitwise and @@ -914,27 +912,27 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_BITWISE_AND).invokeExact(array, i, false); - assertEquals(o, true, "getAndBitwiseAnd boolean"); + assertEquals(true, o, "getAndBitwiseAnd boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (boolean)(true & false), "getAndBitwiseAnd boolean value"); + assertEquals((boolean)(true & false), x, "getAndBitwiseAnd boolean value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_BITWISE_AND_ACQUIRE).invokeExact(array, i, false); - assertEquals(o, true, "getAndBitwiseAndAcquire boolean"); + assertEquals(true, o, "getAndBitwiseAndAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (boolean)(true & false), "getAndBitwiseAndAcquire boolean value"); + assertEquals((boolean)(true & false), x, "getAndBitwiseAndAcquire boolean value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_BITWISE_AND_RELEASE).invokeExact(array, i, false); - assertEquals(o, true, "getAndBitwiseAndRelease boolean"); + assertEquals(true, o, "getAndBitwiseAndRelease boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (boolean)(true & false), "getAndBitwiseAndRelease boolean value"); + assertEquals((boolean)(true & false), x, "getAndBitwiseAndRelease boolean value"); } // get and bitwise xor @@ -942,27 +940,27 @@ public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_BITWISE_XOR).invokeExact(array, i, false); - assertEquals(o, true, "getAndBitwiseXor boolean"); + assertEquals(true, o, "getAndBitwiseXor boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (boolean)(true ^ false), "getAndBitwiseXor boolean value"); + assertEquals((boolean)(true ^ false), x, "getAndBitwiseXor boolean value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_ACQUIRE).invokeExact(array, i, false); - assertEquals(o, true, "getAndBitwiseXorAcquire boolean"); + assertEquals(true, o, "getAndBitwiseXorAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (boolean)(true ^ false), "getAndBitwiseXorAcquire boolean value"); + assertEquals((boolean)(true ^ false), x, "getAndBitwiseXorAcquire boolean value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, true); boolean o = (boolean) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_RELEASE).invokeExact(array, i, false); - assertEquals(o, true, "getAndBitwiseXorRelease boolean"); + assertEquals(true, o, "getAndBitwiseXorRelease boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (boolean)(true ^ false), "getAndBitwiseXorRelease boolean value"); + assertEquals((boolean)(true ^ false), x, "getAndBitwiseXorRelease boolean value"); } } } diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessByte.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessByte.java index 5b3eafba63b..6f7f54a57f5 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessByte.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessByte.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,22 +25,22 @@ * @test * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations * to hit compilation thresholds - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestMethodHandleAccessByte + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestMethodHandleAccessByte */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { static final byte static_final_v = (byte)0x01; @@ -60,7 +60,7 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { VarHandle vhArray; - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestMethodHandleAccessByte.class, "final_v", byte.class); @@ -77,8 +77,6 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { vhArray = MethodHandles.arrayElementVarHandle(byte[].class); } - - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -111,7 +109,8 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -120,13 +119,12 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { } } - static void testInstanceField(VarHandleTestMethodHandleAccessByte recv, Handles hs) throws Throwable { // Plain { hs.get(TestAccessMode.SET).invokeExact(recv, (byte)0x01); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)0x01, "set byte value"); + assertEquals((byte)0x01, x, "set byte value"); } @@ -134,21 +132,21 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact(recv, (byte)0x23); byte x = (byte) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(recv); - assertEquals(x, (byte)0x23, "setVolatile byte value"); + assertEquals((byte)0x23, x, "setVolatile byte value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact(recv, (byte)0x01); byte x = (byte) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(recv); - assertEquals(x, (byte)0x01, "setRelease byte value"); + assertEquals((byte)0x01, x, "setRelease byte value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact(recv, (byte)0x23); byte x = (byte) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(recv); - assertEquals(x, (byte)0x23, "setOpaque byte value"); + assertEquals((byte)0x23, x, "setOpaque byte value"); } hs.get(TestAccessMode.SET).invokeExact(recv, (byte)0x01); @@ -158,56 +156,56 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, (byte)0x01, (byte)0x23); assertEquals(r, true, "success compareAndSet byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)0x23, "success compareAndSet byte value"); + assertEquals((byte)0x23, x, "success compareAndSet byte value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, (byte)0x01, (byte)0x45); assertEquals(r, false, "failing compareAndSet byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)0x23, "failing compareAndSet byte value"); + assertEquals((byte)0x23, x, "failing compareAndSet byte value"); } { byte r = (byte) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, (byte)0x23, (byte)0x01); assertEquals(r, (byte)0x23, "success compareAndExchange byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)0x01, "success compareAndExchange byte value"); + assertEquals((byte)0x01, x, "success compareAndExchange byte value"); } { byte r = (byte) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, (byte)0x23, (byte)0x45); assertEquals(r, (byte)0x01, "failing compareAndExchange byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)0x01, "failing compareAndExchange byte value"); + assertEquals((byte)0x01, x, "failing compareAndExchange byte value"); } { byte r = (byte) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, (byte)0x01, (byte)0x23); assertEquals(r, (byte)0x01, "success compareAndExchangeAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)0x23, "success compareAndExchangeAcquire byte value"); + assertEquals((byte)0x23, x, "success compareAndExchangeAcquire byte value"); } { byte r = (byte) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, (byte)0x01, (byte)0x45); assertEquals(r, (byte)0x23, "failing compareAndExchangeAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)0x23, "failing compareAndExchangeAcquire byte value"); + assertEquals((byte)0x23, x, "failing compareAndExchangeAcquire byte value"); } { byte r = (byte) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, (byte)0x23, (byte)0x01); assertEquals(r, (byte)0x23, "success compareAndExchangeRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)0x01, "success compareAndExchangeRelease byte value"); + assertEquals((byte)0x01, x, "success compareAndExchangeRelease byte value"); } { byte r = (byte) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, (byte)0x23, (byte)0x45); assertEquals(r, (byte)0x01, "failing compareAndExchangeRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)0x01, "failing compareAndExchangeRelease byte value"); + assertEquals((byte)0x01, x, "failing compareAndExchangeRelease byte value"); } { @@ -219,14 +217,14 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)0x23, "success weakCompareAndSetPlain byte value"); + assertEquals((byte)0x23, x, "success weakCompareAndSetPlain byte value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, (byte)0x01, (byte)0x45); assertEquals(success, false, "failing weakCompareAndSetPlain byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)0x23, "failing weakCompareAndSetPlain byte value"); + assertEquals((byte)0x23, x, "failing weakCompareAndSetPlain byte value"); } { @@ -238,14 +236,14 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)0x01, "success weakCompareAndSetAcquire byte"); + assertEquals((byte)0x01, x, "success weakCompareAndSetAcquire byte"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, (byte)0x23, (byte)0x45); assertEquals(success, false, "failing weakCompareAndSetAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)0x01, "failing weakCompareAndSetAcquire byte value"); + assertEquals((byte)0x01, x, "failing weakCompareAndSetAcquire byte value"); } { @@ -257,14 +255,14 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)0x23, "success weakCompareAndSetRelease byte"); + assertEquals((byte)0x23, x, "success weakCompareAndSetRelease byte"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, (byte)0x01, (byte)0x45); assertEquals(success, false, "failing weakCompareAndSetRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)0x23, "failing weakCompareAndSetRelease byte value"); + assertEquals((byte)0x23, x, "failing weakCompareAndSetRelease byte value"); } { @@ -276,22 +274,22 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)0x01, "success weakCompareAndSet byte"); + assertEquals((byte)0x01, x, "success weakCompareAndSet byte"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, (byte)0x23, (byte)0x45); assertEquals(success, false, "failing weakCompareAndSet byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)0x01, "failing weakCompareAndSet byte value"); + assertEquals((byte)0x01, x, "failing weakCompareAndSet byte value"); } // Compare set and get { byte o = (byte) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndSet byte"); + assertEquals((byte)0x01, o, "getAndSet byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)0x23, "getAndSet byte value"); + assertEquals((byte)0x23, x, "getAndSet byte value"); } // get and add, add and get @@ -299,27 +297,27 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(recv, (byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(recv, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndAdd byte"); + assertEquals((byte)0x01, o, "getAndAdd byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)((byte)0x01 + (byte)0x23), "getAndAdd byte value"); + assertEquals((byte)((byte)0x01 + (byte)0x23), x, "getAndAdd byte value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, (byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact(recv, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndAddAcquire byte"); + assertEquals((byte)0x01, o, "getAndAddAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)((byte)0x01 + (byte)0x23), "getAndAddAcquire byte value"); + assertEquals((byte)((byte)0x01 + (byte)0x23), x, "getAndAddAcquire byte value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, (byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact(recv, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndAddRelease byte"); + assertEquals((byte)0x01, o, "getAndAddRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)((byte)0x01 + (byte)0x23), "getAndAddRelease byte value"); + assertEquals((byte)((byte)0x01 + (byte)0x23), x, "getAndAddRelease byte value"); } // get and bitwise or @@ -327,27 +325,27 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(recv, (byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_BITWISE_OR).invokeExact(recv, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseOr byte"); + assertEquals((byte)0x01, o, "getAndBitwiseOr byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)((byte)0x01 | (byte)0x23), "getAndBitwiseOr byte value"); + assertEquals((byte)((byte)0x01 | (byte)0x23), x, "getAndBitwiseOr byte value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, (byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_BITWISE_OR_ACQUIRE).invokeExact(recv, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseOrAcquire byte"); + assertEquals((byte)0x01, o, "getAndBitwiseOrAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)((byte)0x01 | (byte)0x23), "getAndBitwiseOrAcquire byte value"); + assertEquals((byte)((byte)0x01 | (byte)0x23), x, "getAndBitwiseOrAcquire byte value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, (byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_BITWISE_OR_RELEASE).invokeExact(recv, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseOrRelease byte"); + assertEquals((byte)0x01, o, "getAndBitwiseOrRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)((byte)0x01 | (byte)0x23), "getAndBitwiseOrRelease byte value"); + assertEquals((byte)((byte)0x01 | (byte)0x23), x, "getAndBitwiseOrRelease byte value"); } // get and bitwise and @@ -355,27 +353,27 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(recv, (byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_BITWISE_AND).invokeExact(recv, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseAnd byte"); + assertEquals((byte)0x01, o, "getAndBitwiseAnd byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)((byte)0x01 & (byte)0x23), "getAndBitwiseAnd byte value"); + assertEquals((byte)((byte)0x01 & (byte)0x23), x, "getAndBitwiseAnd byte value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, (byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_BITWISE_AND_ACQUIRE).invokeExact(recv, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseAndAcquire byte"); + assertEquals((byte)0x01, o, "getAndBitwiseAndAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)((byte)0x01 & (byte)0x23), "getAndBitwiseAndAcquire byte value"); + assertEquals((byte)((byte)0x01 & (byte)0x23), x, "getAndBitwiseAndAcquire byte value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, (byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_BITWISE_AND_RELEASE).invokeExact(recv, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseAndRelease byte"); + assertEquals((byte)0x01, o, "getAndBitwiseAndRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)((byte)0x01 & (byte)0x23), "getAndBitwiseAndRelease byte value"); + assertEquals((byte)((byte)0x01 & (byte)0x23), x, "getAndBitwiseAndRelease byte value"); } // get and bitwise xor @@ -383,27 +381,27 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(recv, (byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_BITWISE_XOR).invokeExact(recv, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseXor byte"); + assertEquals((byte)0x01, o, "getAndBitwiseXor byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)((byte)0x01 ^ (byte)0x23), "getAndBitwiseXor byte value"); + assertEquals((byte)((byte)0x01 ^ (byte)0x23), x, "getAndBitwiseXor byte value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, (byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_ACQUIRE).invokeExact(recv, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseXorAcquire byte"); + assertEquals((byte)0x01, o, "getAndBitwiseXorAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)((byte)0x01 ^ (byte)0x23), "getAndBitwiseXorAcquire byte value"); + assertEquals((byte)((byte)0x01 ^ (byte)0x23), x, "getAndBitwiseXorAcquire byte value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, (byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_RELEASE).invokeExact(recv, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseXorRelease byte"); + assertEquals((byte)0x01, o, "getAndBitwiseXorRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)((byte)0x01 ^ (byte)0x23), "getAndBitwiseXorRelease byte value"); + assertEquals((byte)((byte)0x01 ^ (byte)0x23), x, "getAndBitwiseXorRelease byte value"); } } @@ -418,7 +416,7 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { { hs.get(TestAccessMode.SET).invokeExact((byte)0x01); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)0x01, "set byte value"); + assertEquals((byte)0x01, x, "set byte value"); } @@ -426,21 +424,21 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact((byte)0x23); byte x = (byte) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(); - assertEquals(x, (byte)0x23, "setVolatile byte value"); + assertEquals((byte)0x23, x, "setVolatile byte value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact((byte)0x01); byte x = (byte) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(); - assertEquals(x, (byte)0x01, "setRelease byte value"); + assertEquals((byte)0x01, x, "setRelease byte value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact((byte)0x23); byte x = (byte) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(); - assertEquals(x, (byte)0x23, "setOpaque byte value"); + assertEquals((byte)0x23, x, "setOpaque byte value"); } hs.get(TestAccessMode.SET).invokeExact((byte)0x01); @@ -450,56 +448,56 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact((byte)0x01, (byte)0x23); assertEquals(r, true, "success compareAndSet byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)0x23, "success compareAndSet byte value"); + assertEquals((byte)0x23, x, "success compareAndSet byte value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact((byte)0x01, (byte)0x45); assertEquals(r, false, "failing compareAndSet byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)0x23, "failing compareAndSet byte value"); + assertEquals((byte)0x23, x, "failing compareAndSet byte value"); } { byte r = (byte) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact((byte)0x23, (byte)0x01); assertEquals(r, (byte)0x23, "success compareAndExchange byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)0x01, "success compareAndExchange byte value"); + assertEquals((byte)0x01, x, "success compareAndExchange byte value"); } { byte r = (byte) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact((byte)0x23, (byte)0x45); assertEquals(r, (byte)0x01, "failing compareAndExchange byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)0x01, "failing compareAndExchange byte value"); + assertEquals((byte)0x01, x, "failing compareAndExchange byte value"); } { byte r = (byte) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact((byte)0x01, (byte)0x23); assertEquals(r, (byte)0x01, "success compareAndExchangeAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)0x23, "success compareAndExchangeAcquire byte value"); + assertEquals((byte)0x23, x, "success compareAndExchangeAcquire byte value"); } { byte r = (byte) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact((byte)0x01, (byte)0x45); assertEquals(r, (byte)0x23, "failing compareAndExchangeAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)0x23, "failing compareAndExchangeAcquire byte value"); + assertEquals((byte)0x23, x, "failing compareAndExchangeAcquire byte value"); } { byte r = (byte) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact((byte)0x23, (byte)0x01); assertEquals(r, (byte)0x23, "success compareAndExchangeRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)0x01, "success compareAndExchangeRelease byte value"); + assertEquals((byte)0x01, x, "success compareAndExchangeRelease byte value"); } { byte r = (byte) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact((byte)0x23, (byte)0x45); assertEquals(r, (byte)0x01, "failing compareAndExchangeRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)0x01, "failing compareAndExchangeRelease byte value"); + assertEquals((byte)0x01, x, "failing compareAndExchangeRelease byte value"); } { @@ -511,14 +509,14 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)0x23, "success weakCompareAndSetPlain byte value"); + assertEquals((byte)0x23, x, "success weakCompareAndSetPlain byte value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact((byte)0x01, (byte)0x45); assertEquals(success, false, "failing weakCompareAndSetPlain byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)0x23, "failing weakCompareAndSetPlain byte value"); + assertEquals((byte)0x23, x, "failing weakCompareAndSetPlain byte value"); } { @@ -530,7 +528,7 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)0x01, "success weakCompareAndSetAcquire byte"); + assertEquals((byte)0x01, x, "success weakCompareAndSetAcquire byte"); } { @@ -538,7 +536,7 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { boolean success = (boolean) mh.invokeExact((byte)0x23, (byte)0x45); assertEquals(success, false, "failing weakCompareAndSetAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)0x01, "failing weakCompareAndSetAcquire byte value"); + assertEquals((byte)0x01, x, "failing weakCompareAndSetAcquire byte value"); } { @@ -550,14 +548,14 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)0x23, "success weakCompareAndSetRelease byte"); + assertEquals((byte)0x23, x, "success weakCompareAndSetRelease byte"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact((byte)0x01, (byte)0x45); assertEquals(success, false, "failing weakCompareAndSetRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)0x23, "failing weakCompareAndSetRelease byte value"); + assertEquals((byte)0x23, x, "failing weakCompareAndSetRelease byte value"); } { @@ -569,14 +567,14 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)0x01, "success weakCompareAndSet byte"); + assertEquals((byte)0x01, x, "success weakCompareAndSet byte"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact((byte)0x23, (byte)0x45); assertEquals(success, false, "failing weakCompareAndSet byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)0x01, "failing weakCompareAndSetRe byte value"); + assertEquals((byte)0x01, x, "failing weakCompareAndSetRe byte value"); } // Compare set and get @@ -584,9 +582,9 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact((byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_SET).invokeExact((byte)0x23); - assertEquals(o, (byte)0x01, "getAndSet byte"); + assertEquals((byte)0x01, o, "getAndSet byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)0x23, "getAndSet byte value"); + assertEquals((byte)0x23, x, "getAndSet byte value"); } // Compare set and get @@ -594,9 +592,9 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact((byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact((byte)0x23); - assertEquals(o, (byte)0x01, "getAndSetAcquire byte"); + assertEquals((byte)0x01, o, "getAndSetAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)0x23, "getAndSetAcquire byte value"); + assertEquals((byte)0x23, x, "getAndSetAcquire byte value"); } // Compare set and get @@ -604,9 +602,9 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact((byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact((byte)0x23); - assertEquals(o, (byte)0x01, "getAndSetRelease byte"); + assertEquals((byte)0x01, o, "getAndSetRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)0x23, "getAndSetRelease byte value"); + assertEquals((byte)0x23, x, "getAndSetRelease byte value"); } // get and add, add and get @@ -614,27 +612,27 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact((byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_ADD).invokeExact((byte)0x23); - assertEquals(o, (byte)0x01, "getAndAdd byte"); + assertEquals((byte)0x01, o, "getAndAdd byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)((byte)0x01 + (byte)0x23), "getAndAdd byte value"); + assertEquals((byte)((byte)0x01 + (byte)0x23), x, "getAndAdd byte value"); } { hs.get(TestAccessMode.SET).invokeExact((byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact((byte)0x23); - assertEquals(o, (byte)0x01, "getAndAddAcquire byte"); + assertEquals((byte)0x01, o, "getAndAddAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)((byte)0x01 + (byte)0x23), "getAndAddAcquire byte value"); + assertEquals((byte)((byte)0x01 + (byte)0x23), x, "getAndAddAcquire byte value"); } { hs.get(TestAccessMode.SET).invokeExact((byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact((byte)0x23); - assertEquals(o, (byte)0x01, "getAndAddRelease byte"); + assertEquals((byte)0x01, o, "getAndAddRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)((byte)0x01 + (byte)0x23), "getAndAddRelease byte value"); + assertEquals((byte)((byte)0x01 + (byte)0x23), x, "getAndAddRelease byte value"); } // get and bitwise or @@ -642,27 +640,27 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact((byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_BITWISE_OR).invokeExact((byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseOr byte"); + assertEquals((byte)0x01, o, "getAndBitwiseOr byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)((byte)0x01 | (byte)0x23), "getAndBitwiseOr byte value"); + assertEquals((byte)((byte)0x01 | (byte)0x23), x, "getAndBitwiseOr byte value"); } { hs.get(TestAccessMode.SET).invokeExact((byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_BITWISE_OR_ACQUIRE).invokeExact((byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseOrAcquire byte"); + assertEquals((byte)0x01, o, "getAndBitwiseOrAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)((byte)0x01 | (byte)0x23), "getAndBitwiseOrAcquire byte value"); + assertEquals((byte)((byte)0x01 | (byte)0x23), x, "getAndBitwiseOrAcquire byte value"); } { hs.get(TestAccessMode.SET).invokeExact((byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_BITWISE_OR_RELEASE).invokeExact((byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseOrRelease byte"); + assertEquals((byte)0x01, o, "getAndBitwiseOrRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)((byte)0x01 | (byte)0x23), "getAndBitwiseOrRelease byte value"); + assertEquals((byte)((byte)0x01 | (byte)0x23), x, "getAndBitwiseOrRelease byte value"); } // get and bitwise and @@ -670,27 +668,27 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact((byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_BITWISE_AND).invokeExact((byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseAnd byte"); + assertEquals((byte)0x01, o, "getAndBitwiseAnd byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)((byte)0x01 & (byte)0x23), "getAndBitwiseAnd byte value"); + assertEquals((byte)((byte)0x01 & (byte)0x23), x, "getAndBitwiseAnd byte value"); } { hs.get(TestAccessMode.SET).invokeExact((byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_BITWISE_AND_ACQUIRE).invokeExact((byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseAndAcquire byte"); + assertEquals((byte)0x01, o, "getAndBitwiseAndAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)((byte)0x01 & (byte)0x23), "getAndBitwiseAndAcquire byte value"); + assertEquals((byte)((byte)0x01 & (byte)0x23), x, "getAndBitwiseAndAcquire byte value"); } { hs.get(TestAccessMode.SET).invokeExact((byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_BITWISE_AND_RELEASE).invokeExact((byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseAndRelease byte"); + assertEquals((byte)0x01, o, "getAndBitwiseAndRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)((byte)0x01 & (byte)0x23), "getAndBitwiseAndRelease byte value"); + assertEquals((byte)((byte)0x01 & (byte)0x23), x, "getAndBitwiseAndRelease byte value"); } // get and bitwise xor @@ -698,27 +696,27 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact((byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_BITWISE_XOR).invokeExact((byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseXor byte"); + assertEquals((byte)0x01, o, "getAndBitwiseXor byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)((byte)0x01 ^ (byte)0x23), "getAndBitwiseXor byte value"); + assertEquals((byte)((byte)0x01 ^ (byte)0x23), x, "getAndBitwiseXor byte value"); } { hs.get(TestAccessMode.SET).invokeExact((byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_ACQUIRE).invokeExact((byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseXorAcquire byte"); + assertEquals((byte)0x01, o, "getAndBitwiseXorAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)((byte)0x01 ^ (byte)0x23), "getAndBitwiseXorAcquire byte value"); + assertEquals((byte)((byte)0x01 ^ (byte)0x23), x, "getAndBitwiseXorAcquire byte value"); } { hs.get(TestAccessMode.SET).invokeExact((byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_RELEASE).invokeExact((byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseXorRelease byte"); + assertEquals((byte)0x01, o, "getAndBitwiseXorRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)((byte)0x01 ^ (byte)0x23), "getAndBitwiseXorRelease byte value"); + assertEquals((byte)((byte)0x01 ^ (byte)0x23), x, "getAndBitwiseXorRelease byte value"); } } @@ -736,7 +734,7 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { { hs.get(TestAccessMode.SET).invokeExact(array, i, (byte)0x01); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)0x01, "get byte value"); + assertEquals((byte)0x01, x, "get byte value"); } @@ -744,21 +742,21 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact(array, i, (byte)0x23); byte x = (byte) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(array, i); - assertEquals(x, (byte)0x23, "setVolatile byte value"); + assertEquals((byte)0x23, x, "setVolatile byte value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact(array, i, (byte)0x01); byte x = (byte) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(array, i); - assertEquals(x, (byte)0x01, "setRelease byte value"); + assertEquals((byte)0x01, x, "setRelease byte value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact(array, i, (byte)0x23); byte x = (byte) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(array, i); - assertEquals(x, (byte)0x23, "setOpaque byte value"); + assertEquals((byte)0x23, x, "setOpaque byte value"); } hs.get(TestAccessMode.SET).invokeExact(array, i, (byte)0x01); @@ -768,56 +766,56 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, (byte)0x01, (byte)0x23); assertEquals(r, true, "success compareAndSet byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)0x23, "success compareAndSet byte value"); + assertEquals((byte)0x23, x, "success compareAndSet byte value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, (byte)0x01, (byte)0x45); assertEquals(r, false, "failing compareAndSet byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)0x23, "failing compareAndSet byte value"); + assertEquals((byte)0x23, x, "failing compareAndSet byte value"); } { byte r = (byte) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, (byte)0x23, (byte)0x01); assertEquals(r, (byte)0x23, "success compareAndExchange byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)0x01, "success compareAndExchange byte value"); + assertEquals((byte)0x01, x, "success compareAndExchange byte value"); } { byte r = (byte) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, (byte)0x23, (byte)0x45); assertEquals(r, (byte)0x01, "failing compareAndExchange byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)0x01, "failing compareAndExchange byte value"); + assertEquals((byte)0x01, x, "failing compareAndExchange byte value"); } { byte r = (byte) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, (byte)0x01, (byte)0x23); assertEquals(r, (byte)0x01, "success compareAndExchangeAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)0x23, "success compareAndExchangeAcquire byte value"); + assertEquals((byte)0x23, x, "success compareAndExchangeAcquire byte value"); } { byte r = (byte) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, (byte)0x01, (byte)0x45); assertEquals(r, (byte)0x23, "failing compareAndExchangeAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)0x23, "failing compareAndExchangeAcquire byte value"); + assertEquals((byte)0x23, x, "failing compareAndExchangeAcquire byte value"); } { byte r = (byte) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, (byte)0x23, (byte)0x01); assertEquals(r, (byte)0x23, "success compareAndExchangeRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)0x01, "success compareAndExchangeRelease byte value"); + assertEquals((byte)0x01, x, "success compareAndExchangeRelease byte value"); } { byte r = (byte) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, (byte)0x23, (byte)0x45); assertEquals(r, (byte)0x01, "failing compareAndExchangeRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)0x01, "failing compareAndExchangeRelease byte value"); + assertEquals((byte)0x01, x, "failing compareAndExchangeRelease byte value"); } { @@ -829,14 +827,14 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)0x23, "success weakCompareAndSetPlain byte value"); + assertEquals((byte)0x23, x, "success weakCompareAndSetPlain byte value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, (byte)0x01, (byte)0x45); assertEquals(success, false, "failing weakCompareAndSetPlain byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)0x23, "failing weakCompareAndSetPlain byte value"); + assertEquals((byte)0x23, x, "failing weakCompareAndSetPlain byte value"); } { @@ -848,14 +846,14 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)0x01, "success weakCompareAndSetAcquire byte"); + assertEquals((byte)0x01, x, "success weakCompareAndSetAcquire byte"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, (byte)0x23, (byte)0x45); assertEquals(success, false, "failing weakCompareAndSetAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)0x01, "failing weakCompareAndSetAcquire byte value"); + assertEquals((byte)0x01, x, "failing weakCompareAndSetAcquire byte value"); } { @@ -867,14 +865,14 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)0x23, "success weakCompareAndSetRelease byte"); + assertEquals((byte)0x23, x, "success weakCompareAndSetRelease byte"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, (byte)0x01, (byte)0x45); assertEquals(success, false, "failing weakCompareAndSetAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)0x23, "failing weakCompareAndSetAcquire byte value"); + assertEquals((byte)0x23, x, "failing weakCompareAndSetAcquire byte value"); } { @@ -886,14 +884,14 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)0x01, "success weakCompareAndSet byte"); + assertEquals((byte)0x01, x, "success weakCompareAndSet byte"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, (byte)0x23, (byte)0x45); assertEquals(success, false, "failing weakCompareAndSet byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)0x01, "failing weakCompareAndSet byte value"); + assertEquals((byte)0x01, x, "failing weakCompareAndSet byte value"); } // Compare set and get @@ -901,27 +899,27 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, (byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndSet byte"); + assertEquals((byte)0x01, o, "getAndSet byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)0x23, "getAndSet byte value"); + assertEquals((byte)0x23, x, "getAndSet byte value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, (byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndSetAcquire byte"); + assertEquals((byte)0x01, o, "getAndSetAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)0x23, "getAndSetAcquire byte value"); + assertEquals((byte)0x23, x, "getAndSetAcquire byte value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, (byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndSetRelease byte"); + assertEquals((byte)0x01, o, "getAndSetRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)0x23, "getAndSetRelease byte value"); + assertEquals((byte)0x23, x, "getAndSetRelease byte value"); } // get and add, add and get @@ -929,27 +927,27 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, (byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndAdd byte"); + assertEquals((byte)0x01, o, "getAndAdd byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)((byte)0x01 + (byte)0x23), "getAndAdd byte value"); + assertEquals((byte)((byte)0x01 + (byte)0x23), x, "getAndAdd byte value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, (byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndAddAcquire byte"); + assertEquals((byte)0x01, o, "getAndAddAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)((byte)0x01 + (byte)0x23), "getAndAddAcquire byte value"); + assertEquals((byte)((byte)0x01 + (byte)0x23), x, "getAndAddAcquire byte value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, (byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndAddRelease byte"); + assertEquals((byte)0x01, o, "getAndAddRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)((byte)0x01 + (byte)0x23), "getAndAddRelease byte value"); + assertEquals((byte)((byte)0x01 + (byte)0x23), x, "getAndAddRelease byte value"); } // get and bitwise or @@ -957,27 +955,27 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, (byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_BITWISE_OR).invokeExact(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseOr byte"); + assertEquals((byte)0x01, o, "getAndBitwiseOr byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)((byte)0x01 | (byte)0x23), "getAndBitwiseOr byte value"); + assertEquals((byte)((byte)0x01 | (byte)0x23), x, "getAndBitwiseOr byte value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, (byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_BITWISE_OR_ACQUIRE).invokeExact(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseOrAcquire byte"); + assertEquals((byte)0x01, o, "getAndBitwiseOrAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)((byte)0x01 | (byte)0x23), "getAndBitwiseOrAcquire byte value"); + assertEquals((byte)((byte)0x01 | (byte)0x23), x, "getAndBitwiseOrAcquire byte value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, (byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_BITWISE_OR_RELEASE).invokeExact(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseOrRelease byte"); + assertEquals((byte)0x01, o, "getAndBitwiseOrRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)((byte)0x01 | (byte)0x23), "getAndBitwiseOrRelease byte value"); + assertEquals((byte)((byte)0x01 | (byte)0x23), x, "getAndBitwiseOrRelease byte value"); } // get and bitwise and @@ -985,27 +983,27 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, (byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_BITWISE_AND).invokeExact(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseAnd byte"); + assertEquals((byte)0x01, o, "getAndBitwiseAnd byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)((byte)0x01 & (byte)0x23), "getAndBitwiseAnd byte value"); + assertEquals((byte)((byte)0x01 & (byte)0x23), x, "getAndBitwiseAnd byte value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, (byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_BITWISE_AND_ACQUIRE).invokeExact(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseAndAcquire byte"); + assertEquals((byte)0x01, o, "getAndBitwiseAndAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)((byte)0x01 & (byte)0x23), "getAndBitwiseAndAcquire byte value"); + assertEquals((byte)((byte)0x01 & (byte)0x23), x, "getAndBitwiseAndAcquire byte value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, (byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_BITWISE_AND_RELEASE).invokeExact(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseAndRelease byte"); + assertEquals((byte)0x01, o, "getAndBitwiseAndRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)((byte)0x01 & (byte)0x23), "getAndBitwiseAndRelease byte value"); + assertEquals((byte)((byte)0x01 & (byte)0x23), x, "getAndBitwiseAndRelease byte value"); } // get and bitwise xor @@ -1013,27 +1011,27 @@ public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, (byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_BITWISE_XOR).invokeExact(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseXor byte"); + assertEquals((byte)0x01, o, "getAndBitwiseXor byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)((byte)0x01 ^ (byte)0x23), "getAndBitwiseXor byte value"); + assertEquals((byte)((byte)0x01 ^ (byte)0x23), x, "getAndBitwiseXor byte value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, (byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_ACQUIRE).invokeExact(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseXorAcquire byte"); + assertEquals((byte)0x01, o, "getAndBitwiseXorAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)((byte)0x01 ^ (byte)0x23), "getAndBitwiseXorAcquire byte value"); + assertEquals((byte)((byte)0x01 ^ (byte)0x23), x, "getAndBitwiseXorAcquire byte value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, (byte)0x01); byte o = (byte) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_RELEASE).invokeExact(array, i, (byte)0x23); - assertEquals(o, (byte)0x01, "getAndBitwiseXorRelease byte"); + assertEquals((byte)0x01, o, "getAndBitwiseXorRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)((byte)0x01 ^ (byte)0x23), "getAndBitwiseXorRelease byte value"); + assertEquals((byte)((byte)0x01 ^ (byte)0x23), x, "getAndBitwiseXorRelease byte value"); } } } diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessChar.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessChar.java index d191b507366..3e31ee282ff 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessChar.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessChar.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,22 +25,22 @@ * @test * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations * to hit compilation thresholds - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestMethodHandleAccessChar + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestMethodHandleAccessChar */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { static final char static_final_v = '\u0123'; @@ -60,7 +60,7 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { VarHandle vhArray; - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestMethodHandleAccessChar.class, "final_v", char.class); @@ -77,8 +77,6 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { vhArray = MethodHandles.arrayElementVarHandle(char[].class); } - - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -111,7 +109,8 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -120,13 +119,12 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { } } - static void testInstanceField(VarHandleTestMethodHandleAccessChar recv, Handles hs) throws Throwable { // Plain { hs.get(TestAccessMode.SET).invokeExact(recv, '\u0123'); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, '\u0123', "set char value"); + assertEquals('\u0123', x, "set char value"); } @@ -134,21 +132,21 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact(recv, '\u4567'); char x = (char) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(recv); - assertEquals(x, '\u4567', "setVolatile char value"); + assertEquals('\u4567', x, "setVolatile char value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact(recv, '\u0123'); char x = (char) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(recv); - assertEquals(x, '\u0123', "setRelease char value"); + assertEquals('\u0123', x, "setRelease char value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact(recv, '\u4567'); char x = (char) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(recv); - assertEquals(x, '\u4567', "setOpaque char value"); + assertEquals('\u4567', x, "setOpaque char value"); } hs.get(TestAccessMode.SET).invokeExact(recv, '\u0123'); @@ -158,56 +156,56 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, '\u0123', '\u4567'); assertEquals(r, true, "success compareAndSet char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, '\u4567', "success compareAndSet char value"); + assertEquals('\u4567', x, "success compareAndSet char value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, '\u0123', '\u89AB'); assertEquals(r, false, "failing compareAndSet char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, '\u4567', "failing compareAndSet char value"); + assertEquals('\u4567', x, "failing compareAndSet char value"); } { char r = (char) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, '\u4567', '\u0123'); assertEquals(r, '\u4567', "success compareAndExchange char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, '\u0123', "success compareAndExchange char value"); + assertEquals('\u0123', x, "success compareAndExchange char value"); } { char r = (char) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, '\u4567', '\u89AB'); assertEquals(r, '\u0123', "failing compareAndExchange char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, '\u0123', "failing compareAndExchange char value"); + assertEquals('\u0123', x, "failing compareAndExchange char value"); } { char r = (char) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, '\u0123', '\u4567'); assertEquals(r, '\u0123', "success compareAndExchangeAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, '\u4567', "success compareAndExchangeAcquire char value"); + assertEquals('\u4567', x, "success compareAndExchangeAcquire char value"); } { char r = (char) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, '\u0123', '\u89AB'); assertEquals(r, '\u4567', "failing compareAndExchangeAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, '\u4567', "failing compareAndExchangeAcquire char value"); + assertEquals('\u4567', x, "failing compareAndExchangeAcquire char value"); } { char r = (char) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, '\u4567', '\u0123'); assertEquals(r, '\u4567', "success compareAndExchangeRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, '\u0123', "success compareAndExchangeRelease char value"); + assertEquals('\u0123', x, "success compareAndExchangeRelease char value"); } { char r = (char) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, '\u4567', '\u89AB'); assertEquals(r, '\u0123', "failing compareAndExchangeRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, '\u0123', "failing compareAndExchangeRelease char value"); + assertEquals('\u0123', x, "failing compareAndExchangeRelease char value"); } { @@ -219,14 +217,14 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, '\u4567', "success weakCompareAndSetPlain char value"); + assertEquals('\u4567', x, "success weakCompareAndSetPlain char value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, '\u0123', '\u89AB'); assertEquals(success, false, "failing weakCompareAndSetPlain char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, '\u4567', "failing weakCompareAndSetPlain char value"); + assertEquals('\u4567', x, "failing weakCompareAndSetPlain char value"); } { @@ -238,14 +236,14 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, '\u0123', "success weakCompareAndSetAcquire char"); + assertEquals('\u0123', x, "success weakCompareAndSetAcquire char"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, '\u4567', '\u89AB'); assertEquals(success, false, "failing weakCompareAndSetAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, '\u0123', "failing weakCompareAndSetAcquire char value"); + assertEquals('\u0123', x, "failing weakCompareAndSetAcquire char value"); } { @@ -257,14 +255,14 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, '\u4567', "success weakCompareAndSetRelease char"); + assertEquals('\u4567', x, "success weakCompareAndSetRelease char"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, '\u0123', '\u89AB'); assertEquals(success, false, "failing weakCompareAndSetRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, '\u4567', "failing weakCompareAndSetRelease char value"); + assertEquals('\u4567', x, "failing weakCompareAndSetRelease char value"); } { @@ -276,22 +274,22 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, '\u0123', "success weakCompareAndSet char"); + assertEquals('\u0123', x, "success weakCompareAndSet char"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, '\u4567', '\u89AB'); assertEquals(success, false, "failing weakCompareAndSet char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, '\u0123', "failing weakCompareAndSet char value"); + assertEquals('\u0123', x, "failing weakCompareAndSet char value"); } // Compare set and get { char o = (char) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, '\u4567'); - assertEquals(o, '\u0123', "getAndSet char"); + assertEquals('\u0123', o, "getAndSet char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, '\u4567', "getAndSet char value"); + assertEquals('\u4567', x, "getAndSet char value"); } // get and add, add and get @@ -299,27 +297,27 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(recv, '\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(recv, '\u4567'); - assertEquals(o, '\u0123', "getAndAdd char"); + assertEquals('\u0123', o, "getAndAdd char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (char)('\u0123' + '\u4567'), "getAndAdd char value"); + assertEquals((char)('\u0123' + '\u4567'), x, "getAndAdd char value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, '\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact(recv, '\u4567'); - assertEquals(o, '\u0123', "getAndAddAcquire char"); + assertEquals('\u0123', o, "getAndAddAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (char)('\u0123' + '\u4567'), "getAndAddAcquire char value"); + assertEquals((char)('\u0123' + '\u4567'), x, "getAndAddAcquire char value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, '\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact(recv, '\u4567'); - assertEquals(o, '\u0123', "getAndAddRelease char"); + assertEquals('\u0123', o, "getAndAddRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (char)('\u0123' + '\u4567'), "getAndAddRelease char value"); + assertEquals((char)('\u0123' + '\u4567'), x, "getAndAddRelease char value"); } // get and bitwise or @@ -327,27 +325,27 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(recv, '\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_BITWISE_OR).invokeExact(recv, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseOr char"); + assertEquals('\u0123', o, "getAndBitwiseOr char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (char)('\u0123' | '\u4567'), "getAndBitwiseOr char value"); + assertEquals((char)('\u0123' | '\u4567'), x, "getAndBitwiseOr char value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, '\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_BITWISE_OR_ACQUIRE).invokeExact(recv, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseOrAcquire char"); + assertEquals('\u0123', o, "getAndBitwiseOrAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (char)('\u0123' | '\u4567'), "getAndBitwiseOrAcquire char value"); + assertEquals((char)('\u0123' | '\u4567'), x, "getAndBitwiseOrAcquire char value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, '\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_BITWISE_OR_RELEASE).invokeExact(recv, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseOrRelease char"); + assertEquals('\u0123', o, "getAndBitwiseOrRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (char)('\u0123' | '\u4567'), "getAndBitwiseOrRelease char value"); + assertEquals((char)('\u0123' | '\u4567'), x, "getAndBitwiseOrRelease char value"); } // get and bitwise and @@ -355,27 +353,27 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(recv, '\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_BITWISE_AND).invokeExact(recv, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseAnd char"); + assertEquals('\u0123', o, "getAndBitwiseAnd char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (char)('\u0123' & '\u4567'), "getAndBitwiseAnd char value"); + assertEquals((char)('\u0123' & '\u4567'), x, "getAndBitwiseAnd char value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, '\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_BITWISE_AND_ACQUIRE).invokeExact(recv, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseAndAcquire char"); + assertEquals('\u0123', o, "getAndBitwiseAndAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (char)('\u0123' & '\u4567'), "getAndBitwiseAndAcquire char value"); + assertEquals((char)('\u0123' & '\u4567'), x, "getAndBitwiseAndAcquire char value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, '\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_BITWISE_AND_RELEASE).invokeExact(recv, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseAndRelease char"); + assertEquals('\u0123', o, "getAndBitwiseAndRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (char)('\u0123' & '\u4567'), "getAndBitwiseAndRelease char value"); + assertEquals((char)('\u0123' & '\u4567'), x, "getAndBitwiseAndRelease char value"); } // get and bitwise xor @@ -383,27 +381,27 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(recv, '\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_BITWISE_XOR).invokeExact(recv, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseXor char"); + assertEquals('\u0123', o, "getAndBitwiseXor char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (char)('\u0123' ^ '\u4567'), "getAndBitwiseXor char value"); + assertEquals((char)('\u0123' ^ '\u4567'), x, "getAndBitwiseXor char value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, '\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_ACQUIRE).invokeExact(recv, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseXorAcquire char"); + assertEquals('\u0123', o, "getAndBitwiseXorAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (char)('\u0123' ^ '\u4567'), "getAndBitwiseXorAcquire char value"); + assertEquals((char)('\u0123' ^ '\u4567'), x, "getAndBitwiseXorAcquire char value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, '\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_RELEASE).invokeExact(recv, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseXorRelease char"); + assertEquals('\u0123', o, "getAndBitwiseXorRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (char)('\u0123' ^ '\u4567'), "getAndBitwiseXorRelease char value"); + assertEquals((char)('\u0123' ^ '\u4567'), x, "getAndBitwiseXorRelease char value"); } } @@ -418,7 +416,7 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { { hs.get(TestAccessMode.SET).invokeExact('\u0123'); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, '\u0123', "set char value"); + assertEquals('\u0123', x, "set char value"); } @@ -426,21 +424,21 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact('\u4567'); char x = (char) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(); - assertEquals(x, '\u4567', "setVolatile char value"); + assertEquals('\u4567', x, "setVolatile char value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact('\u0123'); char x = (char) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(); - assertEquals(x, '\u0123', "setRelease char value"); + assertEquals('\u0123', x, "setRelease char value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact('\u4567'); char x = (char) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(); - assertEquals(x, '\u4567', "setOpaque char value"); + assertEquals('\u4567', x, "setOpaque char value"); } hs.get(TestAccessMode.SET).invokeExact('\u0123'); @@ -450,56 +448,56 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact('\u0123', '\u4567'); assertEquals(r, true, "success compareAndSet char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, '\u4567', "success compareAndSet char value"); + assertEquals('\u4567', x, "success compareAndSet char value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact('\u0123', '\u89AB'); assertEquals(r, false, "failing compareAndSet char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, '\u4567', "failing compareAndSet char value"); + assertEquals('\u4567', x, "failing compareAndSet char value"); } { char r = (char) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact('\u4567', '\u0123'); assertEquals(r, '\u4567', "success compareAndExchange char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, '\u0123', "success compareAndExchange char value"); + assertEquals('\u0123', x, "success compareAndExchange char value"); } { char r = (char) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact('\u4567', '\u89AB'); assertEquals(r, '\u0123', "failing compareAndExchange char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, '\u0123', "failing compareAndExchange char value"); + assertEquals('\u0123', x, "failing compareAndExchange char value"); } { char r = (char) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact('\u0123', '\u4567'); assertEquals(r, '\u0123', "success compareAndExchangeAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, '\u4567', "success compareAndExchangeAcquire char value"); + assertEquals('\u4567', x, "success compareAndExchangeAcquire char value"); } { char r = (char) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact('\u0123', '\u89AB'); assertEquals(r, '\u4567', "failing compareAndExchangeAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, '\u4567', "failing compareAndExchangeAcquire char value"); + assertEquals('\u4567', x, "failing compareAndExchangeAcquire char value"); } { char r = (char) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact('\u4567', '\u0123'); assertEquals(r, '\u4567', "success compareAndExchangeRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, '\u0123', "success compareAndExchangeRelease char value"); + assertEquals('\u0123', x, "success compareAndExchangeRelease char value"); } { char r = (char) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact('\u4567', '\u89AB'); assertEquals(r, '\u0123', "failing compareAndExchangeRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, '\u0123', "failing compareAndExchangeRelease char value"); + assertEquals('\u0123', x, "failing compareAndExchangeRelease char value"); } { @@ -511,14 +509,14 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, '\u4567', "success weakCompareAndSetPlain char value"); + assertEquals('\u4567', x, "success weakCompareAndSetPlain char value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact('\u0123', '\u89AB'); assertEquals(success, false, "failing weakCompareAndSetPlain char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, '\u4567', "failing weakCompareAndSetPlain char value"); + assertEquals('\u4567', x, "failing weakCompareAndSetPlain char value"); } { @@ -530,7 +528,7 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, '\u0123', "success weakCompareAndSetAcquire char"); + assertEquals('\u0123', x, "success weakCompareAndSetAcquire char"); } { @@ -538,7 +536,7 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { boolean success = (boolean) mh.invokeExact('\u4567', '\u89AB'); assertEquals(success, false, "failing weakCompareAndSetAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, '\u0123', "failing weakCompareAndSetAcquire char value"); + assertEquals('\u0123', x, "failing weakCompareAndSetAcquire char value"); } { @@ -550,14 +548,14 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, '\u4567', "success weakCompareAndSetRelease char"); + assertEquals('\u4567', x, "success weakCompareAndSetRelease char"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact('\u0123', '\u89AB'); assertEquals(success, false, "failing weakCompareAndSetRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, '\u4567', "failing weakCompareAndSetRelease char value"); + assertEquals('\u4567', x, "failing weakCompareAndSetRelease char value"); } { @@ -569,14 +567,14 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, '\u0123', "success weakCompareAndSet char"); + assertEquals('\u0123', x, "success weakCompareAndSet char"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact('\u4567', '\u89AB'); assertEquals(success, false, "failing weakCompareAndSet char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, '\u0123', "failing weakCompareAndSetRe char value"); + assertEquals('\u0123', x, "failing weakCompareAndSetRe char value"); } // Compare set and get @@ -584,9 +582,9 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact('\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_SET).invokeExact('\u4567'); - assertEquals(o, '\u0123', "getAndSet char"); + assertEquals('\u0123', o, "getAndSet char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, '\u4567', "getAndSet char value"); + assertEquals('\u4567', x, "getAndSet char value"); } // Compare set and get @@ -594,9 +592,9 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact('\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact('\u4567'); - assertEquals(o, '\u0123', "getAndSetAcquire char"); + assertEquals('\u0123', o, "getAndSetAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, '\u4567', "getAndSetAcquire char value"); + assertEquals('\u4567', x, "getAndSetAcquire char value"); } // Compare set and get @@ -604,9 +602,9 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact('\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact('\u4567'); - assertEquals(o, '\u0123', "getAndSetRelease char"); + assertEquals('\u0123', o, "getAndSetRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, '\u4567', "getAndSetRelease char value"); + assertEquals('\u4567', x, "getAndSetRelease char value"); } // get and add, add and get @@ -614,27 +612,27 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact('\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_ADD).invokeExact('\u4567'); - assertEquals(o, '\u0123', "getAndAdd char"); + assertEquals('\u0123', o, "getAndAdd char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (char)('\u0123' + '\u4567'), "getAndAdd char value"); + assertEquals((char)('\u0123' + '\u4567'), x, "getAndAdd char value"); } { hs.get(TestAccessMode.SET).invokeExact('\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact('\u4567'); - assertEquals(o, '\u0123', "getAndAddAcquire char"); + assertEquals('\u0123', o, "getAndAddAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (char)('\u0123' + '\u4567'), "getAndAddAcquire char value"); + assertEquals((char)('\u0123' + '\u4567'), x, "getAndAddAcquire char value"); } { hs.get(TestAccessMode.SET).invokeExact('\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact('\u4567'); - assertEquals(o, '\u0123', "getAndAddRelease char"); + assertEquals('\u0123', o, "getAndAddRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (char)('\u0123' + '\u4567'), "getAndAddRelease char value"); + assertEquals((char)('\u0123' + '\u4567'), x, "getAndAddRelease char value"); } // get and bitwise or @@ -642,27 +640,27 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact('\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_BITWISE_OR).invokeExact('\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseOr char"); + assertEquals('\u0123', o, "getAndBitwiseOr char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (char)('\u0123' | '\u4567'), "getAndBitwiseOr char value"); + assertEquals((char)('\u0123' | '\u4567'), x, "getAndBitwiseOr char value"); } { hs.get(TestAccessMode.SET).invokeExact('\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_BITWISE_OR_ACQUIRE).invokeExact('\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseOrAcquire char"); + assertEquals('\u0123', o, "getAndBitwiseOrAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (char)('\u0123' | '\u4567'), "getAndBitwiseOrAcquire char value"); + assertEquals((char)('\u0123' | '\u4567'), x, "getAndBitwiseOrAcquire char value"); } { hs.get(TestAccessMode.SET).invokeExact('\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_BITWISE_OR_RELEASE).invokeExact('\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseOrRelease char"); + assertEquals('\u0123', o, "getAndBitwiseOrRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (char)('\u0123' | '\u4567'), "getAndBitwiseOrRelease char value"); + assertEquals((char)('\u0123' | '\u4567'), x, "getAndBitwiseOrRelease char value"); } // get and bitwise and @@ -670,27 +668,27 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact('\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_BITWISE_AND).invokeExact('\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseAnd char"); + assertEquals('\u0123', o, "getAndBitwiseAnd char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (char)('\u0123' & '\u4567'), "getAndBitwiseAnd char value"); + assertEquals((char)('\u0123' & '\u4567'), x, "getAndBitwiseAnd char value"); } { hs.get(TestAccessMode.SET).invokeExact('\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_BITWISE_AND_ACQUIRE).invokeExact('\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseAndAcquire char"); + assertEquals('\u0123', o, "getAndBitwiseAndAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (char)('\u0123' & '\u4567'), "getAndBitwiseAndAcquire char value"); + assertEquals((char)('\u0123' & '\u4567'), x, "getAndBitwiseAndAcquire char value"); } { hs.get(TestAccessMode.SET).invokeExact('\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_BITWISE_AND_RELEASE).invokeExact('\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseAndRelease char"); + assertEquals('\u0123', o, "getAndBitwiseAndRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (char)('\u0123' & '\u4567'), "getAndBitwiseAndRelease char value"); + assertEquals((char)('\u0123' & '\u4567'), x, "getAndBitwiseAndRelease char value"); } // get and bitwise xor @@ -698,27 +696,27 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact('\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_BITWISE_XOR).invokeExact('\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseXor char"); + assertEquals('\u0123', o, "getAndBitwiseXor char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (char)('\u0123' ^ '\u4567'), "getAndBitwiseXor char value"); + assertEquals((char)('\u0123' ^ '\u4567'), x, "getAndBitwiseXor char value"); } { hs.get(TestAccessMode.SET).invokeExact('\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_ACQUIRE).invokeExact('\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseXorAcquire char"); + assertEquals('\u0123', o, "getAndBitwiseXorAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (char)('\u0123' ^ '\u4567'), "getAndBitwiseXorAcquire char value"); + assertEquals((char)('\u0123' ^ '\u4567'), x, "getAndBitwiseXorAcquire char value"); } { hs.get(TestAccessMode.SET).invokeExact('\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_RELEASE).invokeExact('\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseXorRelease char"); + assertEquals('\u0123', o, "getAndBitwiseXorRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (char)('\u0123' ^ '\u4567'), "getAndBitwiseXorRelease char value"); + assertEquals((char)('\u0123' ^ '\u4567'), x, "getAndBitwiseXorRelease char value"); } } @@ -736,7 +734,7 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { { hs.get(TestAccessMode.SET).invokeExact(array, i, '\u0123'); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, '\u0123', "get char value"); + assertEquals('\u0123', x, "get char value"); } @@ -744,21 +742,21 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact(array, i, '\u4567'); char x = (char) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(array, i); - assertEquals(x, '\u4567', "setVolatile char value"); + assertEquals('\u4567', x, "setVolatile char value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact(array, i, '\u0123'); char x = (char) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(array, i); - assertEquals(x, '\u0123', "setRelease char value"); + assertEquals('\u0123', x, "setRelease char value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact(array, i, '\u4567'); char x = (char) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(array, i); - assertEquals(x, '\u4567', "setOpaque char value"); + assertEquals('\u4567', x, "setOpaque char value"); } hs.get(TestAccessMode.SET).invokeExact(array, i, '\u0123'); @@ -768,56 +766,56 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, '\u0123', '\u4567'); assertEquals(r, true, "success compareAndSet char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, '\u4567', "success compareAndSet char value"); + assertEquals('\u4567', x, "success compareAndSet char value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, '\u0123', '\u89AB'); assertEquals(r, false, "failing compareAndSet char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, '\u4567', "failing compareAndSet char value"); + assertEquals('\u4567', x, "failing compareAndSet char value"); } { char r = (char) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, '\u4567', '\u0123'); assertEquals(r, '\u4567', "success compareAndExchange char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, '\u0123', "success compareAndExchange char value"); + assertEquals('\u0123', x, "success compareAndExchange char value"); } { char r = (char) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, '\u4567', '\u89AB'); assertEquals(r, '\u0123', "failing compareAndExchange char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, '\u0123', "failing compareAndExchange char value"); + assertEquals('\u0123', x, "failing compareAndExchange char value"); } { char r = (char) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, '\u0123', '\u4567'); assertEquals(r, '\u0123', "success compareAndExchangeAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, '\u4567', "success compareAndExchangeAcquire char value"); + assertEquals('\u4567', x, "success compareAndExchangeAcquire char value"); } { char r = (char) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, '\u0123', '\u89AB'); assertEquals(r, '\u4567', "failing compareAndExchangeAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, '\u4567', "failing compareAndExchangeAcquire char value"); + assertEquals('\u4567', x, "failing compareAndExchangeAcquire char value"); } { char r = (char) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, '\u4567', '\u0123'); assertEquals(r, '\u4567', "success compareAndExchangeRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, '\u0123', "success compareAndExchangeRelease char value"); + assertEquals('\u0123', x, "success compareAndExchangeRelease char value"); } { char r = (char) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, '\u4567', '\u89AB'); assertEquals(r, '\u0123', "failing compareAndExchangeRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, '\u0123', "failing compareAndExchangeRelease char value"); + assertEquals('\u0123', x, "failing compareAndExchangeRelease char value"); } { @@ -829,14 +827,14 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, '\u4567', "success weakCompareAndSetPlain char value"); + assertEquals('\u4567', x, "success weakCompareAndSetPlain char value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, '\u0123', '\u89AB'); assertEquals(success, false, "failing weakCompareAndSetPlain char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, '\u4567', "failing weakCompareAndSetPlain char value"); + assertEquals('\u4567', x, "failing weakCompareAndSetPlain char value"); } { @@ -848,14 +846,14 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, '\u0123', "success weakCompareAndSetAcquire char"); + assertEquals('\u0123', x, "success weakCompareAndSetAcquire char"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, '\u4567', '\u89AB'); assertEquals(success, false, "failing weakCompareAndSetAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, '\u0123', "failing weakCompareAndSetAcquire char value"); + assertEquals('\u0123', x, "failing weakCompareAndSetAcquire char value"); } { @@ -867,14 +865,14 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, '\u4567', "success weakCompareAndSetRelease char"); + assertEquals('\u4567', x, "success weakCompareAndSetRelease char"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, '\u0123', '\u89AB'); assertEquals(success, false, "failing weakCompareAndSetAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, '\u4567', "failing weakCompareAndSetAcquire char value"); + assertEquals('\u4567', x, "failing weakCompareAndSetAcquire char value"); } { @@ -886,14 +884,14 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, '\u0123', "success weakCompareAndSet char"); + assertEquals('\u0123', x, "success weakCompareAndSet char"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, '\u4567', '\u89AB'); assertEquals(success, false, "failing weakCompareAndSet char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, '\u0123', "failing weakCompareAndSet char value"); + assertEquals('\u0123', x, "failing weakCompareAndSet char value"); } // Compare set and get @@ -901,27 +899,27 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, '\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndSet char"); + assertEquals('\u0123', o, "getAndSet char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, '\u4567', "getAndSet char value"); + assertEquals('\u4567', x, "getAndSet char value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, '\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndSetAcquire char"); + assertEquals('\u0123', o, "getAndSetAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, '\u4567', "getAndSetAcquire char value"); + assertEquals('\u4567', x, "getAndSetAcquire char value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, '\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndSetRelease char"); + assertEquals('\u0123', o, "getAndSetRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, '\u4567', "getAndSetRelease char value"); + assertEquals('\u4567', x, "getAndSetRelease char value"); } // get and add, add and get @@ -929,27 +927,27 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, '\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndAdd char"); + assertEquals('\u0123', o, "getAndAdd char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (char)('\u0123' + '\u4567'), "getAndAdd char value"); + assertEquals((char)('\u0123' + '\u4567'), x, "getAndAdd char value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, '\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndAddAcquire char"); + assertEquals('\u0123', o, "getAndAddAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (char)('\u0123' + '\u4567'), "getAndAddAcquire char value"); + assertEquals((char)('\u0123' + '\u4567'), x, "getAndAddAcquire char value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, '\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndAddRelease char"); + assertEquals('\u0123', o, "getAndAddRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (char)('\u0123' + '\u4567'), "getAndAddRelease char value"); + assertEquals((char)('\u0123' + '\u4567'), x, "getAndAddRelease char value"); } // get and bitwise or @@ -957,27 +955,27 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, '\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_BITWISE_OR).invokeExact(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseOr char"); + assertEquals('\u0123', o, "getAndBitwiseOr char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (char)('\u0123' | '\u4567'), "getAndBitwiseOr char value"); + assertEquals((char)('\u0123' | '\u4567'), x, "getAndBitwiseOr char value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, '\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_BITWISE_OR_ACQUIRE).invokeExact(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseOrAcquire char"); + assertEquals('\u0123', o, "getAndBitwiseOrAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (char)('\u0123' | '\u4567'), "getAndBitwiseOrAcquire char value"); + assertEquals((char)('\u0123' | '\u4567'), x, "getAndBitwiseOrAcquire char value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, '\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_BITWISE_OR_RELEASE).invokeExact(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseOrRelease char"); + assertEquals('\u0123', o, "getAndBitwiseOrRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (char)('\u0123' | '\u4567'), "getAndBitwiseOrRelease char value"); + assertEquals((char)('\u0123' | '\u4567'), x, "getAndBitwiseOrRelease char value"); } // get and bitwise and @@ -985,27 +983,27 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, '\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_BITWISE_AND).invokeExact(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseAnd char"); + assertEquals('\u0123', o, "getAndBitwiseAnd char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (char)('\u0123' & '\u4567'), "getAndBitwiseAnd char value"); + assertEquals((char)('\u0123' & '\u4567'), x, "getAndBitwiseAnd char value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, '\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_BITWISE_AND_ACQUIRE).invokeExact(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseAndAcquire char"); + assertEquals('\u0123', o, "getAndBitwiseAndAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (char)('\u0123' & '\u4567'), "getAndBitwiseAndAcquire char value"); + assertEquals((char)('\u0123' & '\u4567'), x, "getAndBitwiseAndAcquire char value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, '\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_BITWISE_AND_RELEASE).invokeExact(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseAndRelease char"); + assertEquals('\u0123', o, "getAndBitwiseAndRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (char)('\u0123' & '\u4567'), "getAndBitwiseAndRelease char value"); + assertEquals((char)('\u0123' & '\u4567'), x, "getAndBitwiseAndRelease char value"); } // get and bitwise xor @@ -1013,27 +1011,27 @@ public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, '\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_BITWISE_XOR).invokeExact(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseXor char"); + assertEquals('\u0123', o, "getAndBitwiseXor char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (char)('\u0123' ^ '\u4567'), "getAndBitwiseXor char value"); + assertEquals((char)('\u0123' ^ '\u4567'), x, "getAndBitwiseXor char value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, '\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_ACQUIRE).invokeExact(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseXorAcquire char"); + assertEquals('\u0123', o, "getAndBitwiseXorAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (char)('\u0123' ^ '\u4567'), "getAndBitwiseXorAcquire char value"); + assertEquals((char)('\u0123' ^ '\u4567'), x, "getAndBitwiseXorAcquire char value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, '\u0123'); char o = (char) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_RELEASE).invokeExact(array, i, '\u4567'); - assertEquals(o, '\u0123', "getAndBitwiseXorRelease char"); + assertEquals('\u0123', o, "getAndBitwiseXorRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (char)('\u0123' ^ '\u4567'), "getAndBitwiseXorRelease char value"); + assertEquals((char)('\u0123' ^ '\u4567'), x, "getAndBitwiseXorRelease char value"); } } } diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessDouble.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessDouble.java index fe0455d2375..056d45478ed 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessDouble.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessDouble.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,22 +25,22 @@ * @test * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations * to hit compilation thresholds - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestMethodHandleAccessDouble + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestMethodHandleAccessDouble */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { static final double static_final_v = 1.0d; @@ -60,7 +60,7 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { VarHandle vhArray; - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestMethodHandleAccessDouble.class, "final_v", double.class); @@ -77,8 +77,6 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { vhArray = MethodHandles.arrayElementVarHandle(double[].class); } - - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -111,7 +109,8 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -120,13 +119,12 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { } } - static void testInstanceField(VarHandleTestMethodHandleAccessDouble recv, Handles hs) throws Throwable { // Plain { hs.get(TestAccessMode.SET).invokeExact(recv, 1.0d); double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 1.0d, "set double value"); + assertEquals(1.0d, x, "set double value"); } @@ -134,21 +132,21 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact(recv, 2.0d); double x = (double) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(recv); - assertEquals(x, 2.0d, "setVolatile double value"); + assertEquals(2.0d, x, "setVolatile double value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact(recv, 1.0d); double x = (double) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(recv); - assertEquals(x, 1.0d, "setRelease double value"); + assertEquals(1.0d, x, "setRelease double value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact(recv, 2.0d); double x = (double) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(recv); - assertEquals(x, 2.0d, "setOpaque double value"); + assertEquals(2.0d, x, "setOpaque double value"); } hs.get(TestAccessMode.SET).invokeExact(recv, 1.0d); @@ -158,56 +156,56 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, 1.0d, 2.0d); assertEquals(r, true, "success compareAndSet double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 2.0d, "success compareAndSet double value"); + assertEquals(2.0d, x, "success compareAndSet double value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, 1.0d, 3.0d); assertEquals(r, false, "failing compareAndSet double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 2.0d, "failing compareAndSet double value"); + assertEquals(2.0d, x, "failing compareAndSet double value"); } { double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, 2.0d, 1.0d); assertEquals(r, 2.0d, "success compareAndExchange double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 1.0d, "success compareAndExchange double value"); + assertEquals(1.0d, x, "success compareAndExchange double value"); } { double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, 2.0d, 3.0d); assertEquals(r, 1.0d, "failing compareAndExchange double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 1.0d, "failing compareAndExchange double value"); + assertEquals(1.0d, x, "failing compareAndExchange double value"); } { double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, 1.0d, 2.0d); assertEquals(r, 1.0d, "success compareAndExchangeAcquire double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 2.0d, "success compareAndExchangeAcquire double value"); + assertEquals(2.0d, x, "success compareAndExchangeAcquire double value"); } { double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, 1.0d, 3.0d); assertEquals(r, 2.0d, "failing compareAndExchangeAcquire double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 2.0d, "failing compareAndExchangeAcquire double value"); + assertEquals(2.0d, x, "failing compareAndExchangeAcquire double value"); } { double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, 2.0d, 1.0d); assertEquals(r, 2.0d, "success compareAndExchangeRelease double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 1.0d, "success compareAndExchangeRelease double value"); + assertEquals(1.0d, x, "success compareAndExchangeRelease double value"); } { double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, 2.0d, 3.0d); assertEquals(r, 1.0d, "failing compareAndExchangeRelease double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 1.0d, "failing compareAndExchangeRelease double value"); + assertEquals(1.0d, x, "failing compareAndExchangeRelease double value"); } { @@ -219,14 +217,14 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 2.0d, "success weakCompareAndSetPlain double value"); + assertEquals(2.0d, x, "success weakCompareAndSetPlain double value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, 1.0d, 3.0d); assertEquals(success, false, "failing weakCompareAndSetPlain double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 2.0d, "failing weakCompareAndSetPlain double value"); + assertEquals(2.0d, x, "failing weakCompareAndSetPlain double value"); } { @@ -238,14 +236,14 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 1.0d, "success weakCompareAndSetAcquire double"); + assertEquals(1.0d, x, "success weakCompareAndSetAcquire double"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, 2.0d, 3.0d); assertEquals(success, false, "failing weakCompareAndSetAcquire double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 1.0d, "failing weakCompareAndSetAcquire double value"); + assertEquals(1.0d, x, "failing weakCompareAndSetAcquire double value"); } { @@ -257,14 +255,14 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 2.0d, "success weakCompareAndSetRelease double"); + assertEquals(2.0d, x, "success weakCompareAndSetRelease double"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, 1.0d, 3.0d); assertEquals(success, false, "failing weakCompareAndSetRelease double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 2.0d, "failing weakCompareAndSetRelease double value"); + assertEquals(2.0d, x, "failing weakCompareAndSetRelease double value"); } { @@ -276,22 +274,22 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 1.0d, "success weakCompareAndSet double"); + assertEquals(1.0d, x, "success weakCompareAndSet double"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, 2.0d, 3.0d); assertEquals(success, false, "failing weakCompareAndSet double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 1.0d, "failing weakCompareAndSet double value"); + assertEquals(1.0d, x, "failing weakCompareAndSet double value"); } // Compare set and get { double o = (double) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, 2.0d); - assertEquals(o, 1.0d, "getAndSet double"); + assertEquals(1.0d, o, "getAndSet double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 2.0d, "getAndSet double value"); + assertEquals(2.0d, x, "getAndSet double value"); } // get and add, add and get @@ -299,27 +297,27 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(recv, 1.0d); double o = (double) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(recv, 2.0d); - assertEquals(o, 1.0d, "getAndAdd double"); + assertEquals(1.0d, o, "getAndAdd double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (double)(1.0d + 2.0d), "getAndAdd double value"); + assertEquals((double)(1.0d + 2.0d), x, "getAndAdd double value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, 1.0d); double o = (double) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact(recv, 2.0d); - assertEquals(o, 1.0d, "getAndAddAcquire double"); + assertEquals(1.0d, o, "getAndAddAcquire double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (double)(1.0d + 2.0d), "getAndAddAcquire double value"); + assertEquals((double)(1.0d + 2.0d), x, "getAndAddAcquire double value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, 1.0d); double o = (double) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact(recv, 2.0d); - assertEquals(o, 1.0d, "getAndAddRelease double"); + assertEquals(1.0d, o, "getAndAddRelease double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (double)(1.0d + 2.0d), "getAndAddRelease double value"); + assertEquals((double)(1.0d + 2.0d), x, "getAndAddRelease double value"); } } @@ -340,7 +338,7 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { { hs.get(TestAccessMode.SET).invokeExact(1.0d); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 1.0d, "set double value"); + assertEquals(1.0d, x, "set double value"); } @@ -348,21 +346,21 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact(2.0d); double x = (double) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(); - assertEquals(x, 2.0d, "setVolatile double value"); + assertEquals(2.0d, x, "setVolatile double value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact(1.0d); double x = (double) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(); - assertEquals(x, 1.0d, "setRelease double value"); + assertEquals(1.0d, x, "setRelease double value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact(2.0d); double x = (double) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(); - assertEquals(x, 2.0d, "setOpaque double value"); + assertEquals(2.0d, x, "setOpaque double value"); } hs.get(TestAccessMode.SET).invokeExact(1.0d); @@ -372,56 +370,56 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(1.0d, 2.0d); assertEquals(r, true, "success compareAndSet double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 2.0d, "success compareAndSet double value"); + assertEquals(2.0d, x, "success compareAndSet double value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(1.0d, 3.0d); assertEquals(r, false, "failing compareAndSet double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 2.0d, "failing compareAndSet double value"); + assertEquals(2.0d, x, "failing compareAndSet double value"); } { double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(2.0d, 1.0d); assertEquals(r, 2.0d, "success compareAndExchange double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 1.0d, "success compareAndExchange double value"); + assertEquals(1.0d, x, "success compareAndExchange double value"); } { double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(2.0d, 3.0d); assertEquals(r, 1.0d, "failing compareAndExchange double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 1.0d, "failing compareAndExchange double value"); + assertEquals(1.0d, x, "failing compareAndExchange double value"); } { double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(1.0d, 2.0d); assertEquals(r, 1.0d, "success compareAndExchangeAcquire double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 2.0d, "success compareAndExchangeAcquire double value"); + assertEquals(2.0d, x, "success compareAndExchangeAcquire double value"); } { double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(1.0d, 3.0d); assertEquals(r, 2.0d, "failing compareAndExchangeAcquire double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 2.0d, "failing compareAndExchangeAcquire double value"); + assertEquals(2.0d, x, "failing compareAndExchangeAcquire double value"); } { double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(2.0d, 1.0d); assertEquals(r, 2.0d, "success compareAndExchangeRelease double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 1.0d, "success compareAndExchangeRelease double value"); + assertEquals(1.0d, x, "success compareAndExchangeRelease double value"); } { double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(2.0d, 3.0d); assertEquals(r, 1.0d, "failing compareAndExchangeRelease double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 1.0d, "failing compareAndExchangeRelease double value"); + assertEquals(1.0d, x, "failing compareAndExchangeRelease double value"); } { @@ -433,14 +431,14 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 2.0d, "success weakCompareAndSetPlain double value"); + assertEquals(2.0d, x, "success weakCompareAndSetPlain double value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(1.0d, 3.0d); assertEquals(success, false, "failing weakCompareAndSetPlain double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 2.0d, "failing weakCompareAndSetPlain double value"); + assertEquals(2.0d, x, "failing weakCompareAndSetPlain double value"); } { @@ -452,7 +450,7 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 1.0d, "success weakCompareAndSetAcquire double"); + assertEquals(1.0d, x, "success weakCompareAndSetAcquire double"); } { @@ -460,7 +458,7 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { boolean success = (boolean) mh.invokeExact(2.0d, 3.0d); assertEquals(success, false, "failing weakCompareAndSetAcquire double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 1.0d, "failing weakCompareAndSetAcquire double value"); + assertEquals(1.0d, x, "failing weakCompareAndSetAcquire double value"); } { @@ -472,14 +470,14 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 2.0d, "success weakCompareAndSetRelease double"); + assertEquals(2.0d, x, "success weakCompareAndSetRelease double"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(1.0d, 3.0d); assertEquals(success, false, "failing weakCompareAndSetRelease double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 2.0d, "failing weakCompareAndSetRelease double value"); + assertEquals(2.0d, x, "failing weakCompareAndSetRelease double value"); } { @@ -491,14 +489,14 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 1.0d, "success weakCompareAndSet double"); + assertEquals(1.0d, x, "success weakCompareAndSet double"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(2.0d, 3.0d); assertEquals(success, false, "failing weakCompareAndSet double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 1.0d, "failing weakCompareAndSetRe double value"); + assertEquals(1.0d, x, "failing weakCompareAndSetRe double value"); } // Compare set and get @@ -506,9 +504,9 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(1.0d); double o = (double) hs.get(TestAccessMode.GET_AND_SET).invokeExact(2.0d); - assertEquals(o, 1.0d, "getAndSet double"); + assertEquals(1.0d, o, "getAndSet double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 2.0d, "getAndSet double value"); + assertEquals(2.0d, x, "getAndSet double value"); } // Compare set and get @@ -516,9 +514,9 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(1.0d); double o = (double) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact(2.0d); - assertEquals(o, 1.0d, "getAndSetAcquire double"); + assertEquals(1.0d, o, "getAndSetAcquire double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 2.0d, "getAndSetAcquire double value"); + assertEquals(2.0d, x, "getAndSetAcquire double value"); } // Compare set and get @@ -526,9 +524,9 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(1.0d); double o = (double) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact(2.0d); - assertEquals(o, 1.0d, "getAndSetRelease double"); + assertEquals(1.0d, o, "getAndSetRelease double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 2.0d, "getAndSetRelease double value"); + assertEquals(2.0d, x, "getAndSetRelease double value"); } // get and add, add and get @@ -536,27 +534,27 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(1.0d); double o = (double) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(2.0d); - assertEquals(o, 1.0d, "getAndAdd double"); + assertEquals(1.0d, o, "getAndAdd double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (double)(1.0d + 2.0d), "getAndAdd double value"); + assertEquals((double)(1.0d + 2.0d), x, "getAndAdd double value"); } { hs.get(TestAccessMode.SET).invokeExact(1.0d); double o = (double) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact(2.0d); - assertEquals(o, 1.0d, "getAndAddAcquire double"); + assertEquals(1.0d, o, "getAndAddAcquire double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (double)(1.0d + 2.0d), "getAndAddAcquire double value"); + assertEquals((double)(1.0d + 2.0d), x, "getAndAddAcquire double value"); } { hs.get(TestAccessMode.SET).invokeExact(1.0d); double o = (double) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact(2.0d); - assertEquals(o, 1.0d, "getAndAddRelease double"); + assertEquals(1.0d, o, "getAndAddRelease double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (double)(1.0d + 2.0d), "getAndAddRelease double value"); + assertEquals((double)(1.0d + 2.0d), x, "getAndAddRelease double value"); } } @@ -580,7 +578,7 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { { hs.get(TestAccessMode.SET).invokeExact(array, i, 1.0d); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 1.0d, "get double value"); + assertEquals(1.0d, x, "get double value"); } @@ -588,21 +586,21 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact(array, i, 2.0d); double x = (double) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(array, i); - assertEquals(x, 2.0d, "setVolatile double value"); + assertEquals(2.0d, x, "setVolatile double value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact(array, i, 1.0d); double x = (double) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(array, i); - assertEquals(x, 1.0d, "setRelease double value"); + assertEquals(1.0d, x, "setRelease double value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact(array, i, 2.0d); double x = (double) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(array, i); - assertEquals(x, 2.0d, "setOpaque double value"); + assertEquals(2.0d, x, "setOpaque double value"); } hs.get(TestAccessMode.SET).invokeExact(array, i, 1.0d); @@ -612,56 +610,56 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, 1.0d, 2.0d); assertEquals(r, true, "success compareAndSet double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 2.0d, "success compareAndSet double value"); + assertEquals(2.0d, x, "success compareAndSet double value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, 1.0d, 3.0d); assertEquals(r, false, "failing compareAndSet double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 2.0d, "failing compareAndSet double value"); + assertEquals(2.0d, x, "failing compareAndSet double value"); } { double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, 2.0d, 1.0d); assertEquals(r, 2.0d, "success compareAndExchange double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 1.0d, "success compareAndExchange double value"); + assertEquals(1.0d, x, "success compareAndExchange double value"); } { double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, 2.0d, 3.0d); assertEquals(r, 1.0d, "failing compareAndExchange double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 1.0d, "failing compareAndExchange double value"); + assertEquals(1.0d, x, "failing compareAndExchange double value"); } { double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, 1.0d, 2.0d); assertEquals(r, 1.0d, "success compareAndExchangeAcquire double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 2.0d, "success compareAndExchangeAcquire double value"); + assertEquals(2.0d, x, "success compareAndExchangeAcquire double value"); } { double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, 1.0d, 3.0d); assertEquals(r, 2.0d, "failing compareAndExchangeAcquire double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 2.0d, "failing compareAndExchangeAcquire double value"); + assertEquals(2.0d, x, "failing compareAndExchangeAcquire double value"); } { double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, 2.0d, 1.0d); assertEquals(r, 2.0d, "success compareAndExchangeRelease double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 1.0d, "success compareAndExchangeRelease double value"); + assertEquals(1.0d, x, "success compareAndExchangeRelease double value"); } { double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, 2.0d, 3.0d); assertEquals(r, 1.0d, "failing compareAndExchangeRelease double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 1.0d, "failing compareAndExchangeRelease double value"); + assertEquals(1.0d, x, "failing compareAndExchangeRelease double value"); } { @@ -673,14 +671,14 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 2.0d, "success weakCompareAndSetPlain double value"); + assertEquals(2.0d, x, "success weakCompareAndSetPlain double value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, 1.0d, 3.0d); assertEquals(success, false, "failing weakCompareAndSetPlain double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 2.0d, "failing weakCompareAndSetPlain double value"); + assertEquals(2.0d, x, "failing weakCompareAndSetPlain double value"); } { @@ -692,14 +690,14 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 1.0d, "success weakCompareAndSetAcquire double"); + assertEquals(1.0d, x, "success weakCompareAndSetAcquire double"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 2.0d, 3.0d); assertEquals(success, false, "failing weakCompareAndSetAcquire double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 1.0d, "failing weakCompareAndSetAcquire double value"); + assertEquals(1.0d, x, "failing weakCompareAndSetAcquire double value"); } { @@ -711,14 +709,14 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 2.0d, "success weakCompareAndSetRelease double"); + assertEquals(2.0d, x, "success weakCompareAndSetRelease double"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 1.0d, 3.0d); assertEquals(success, false, "failing weakCompareAndSetAcquire double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 2.0d, "failing weakCompareAndSetAcquire double value"); + assertEquals(2.0d, x, "failing weakCompareAndSetAcquire double value"); } { @@ -730,14 +728,14 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 1.0d, "success weakCompareAndSet double"); + assertEquals(1.0d, x, "success weakCompareAndSet double"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, 2.0d, 3.0d); assertEquals(success, false, "failing weakCompareAndSet double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 1.0d, "failing weakCompareAndSet double value"); + assertEquals(1.0d, x, "failing weakCompareAndSet double value"); } // Compare set and get @@ -745,27 +743,27 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, 1.0d); double o = (double) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, 2.0d); - assertEquals(o, 1.0d, "getAndSet double"); + assertEquals(1.0d, o, "getAndSet double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 2.0d, "getAndSet double value"); + assertEquals(2.0d, x, "getAndSet double value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, 1.0d); double o = (double) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact(array, i, 2.0d); - assertEquals(o, 1.0d, "getAndSetAcquire double"); + assertEquals(1.0d, o, "getAndSetAcquire double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 2.0d, "getAndSetAcquire double value"); + assertEquals(2.0d, x, "getAndSetAcquire double value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, 1.0d); double o = (double) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact(array, i, 2.0d); - assertEquals(o, 1.0d, "getAndSetRelease double"); + assertEquals(1.0d, o, "getAndSetRelease double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 2.0d, "getAndSetRelease double value"); + assertEquals(2.0d, x, "getAndSetRelease double value"); } // get and add, add and get @@ -773,27 +771,27 @@ public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, 1.0d); double o = (double) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(array, i, 2.0d); - assertEquals(o, 1.0d, "getAndAdd double"); + assertEquals(1.0d, o, "getAndAdd double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (double)(1.0d + 2.0d), "getAndAdd double value"); + assertEquals((double)(1.0d + 2.0d), x, "getAndAdd double value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, 1.0d); double o = (double) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact(array, i, 2.0d); - assertEquals(o, 1.0d, "getAndAddAcquire double"); + assertEquals(1.0d, o, "getAndAddAcquire double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (double)(1.0d + 2.0d), "getAndAddAcquire double value"); + assertEquals((double)(1.0d + 2.0d), x, "getAndAddAcquire double value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, 1.0d); double o = (double) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact(array, i, 2.0d); - assertEquals(o, 1.0d, "getAndAddRelease double"); + assertEquals(1.0d, o, "getAndAddRelease double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (double)(1.0d + 2.0d), "getAndAddRelease double value"); + assertEquals((double)(1.0d + 2.0d), x, "getAndAddRelease double value"); } } diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessFloat.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessFloat.java index 256e4723eec..98eb72301cb 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessFloat.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessFloat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,22 +25,22 @@ * @test * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations * to hit compilation thresholds - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestMethodHandleAccessFloat + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestMethodHandleAccessFloat */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { static final float static_final_v = 1.0f; @@ -60,7 +60,7 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { VarHandle vhArray; - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestMethodHandleAccessFloat.class, "final_v", float.class); @@ -77,8 +77,6 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { vhArray = MethodHandles.arrayElementVarHandle(float[].class); } - - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -111,7 +109,8 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -120,13 +119,12 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { } } - static void testInstanceField(VarHandleTestMethodHandleAccessFloat recv, Handles hs) throws Throwable { // Plain { hs.get(TestAccessMode.SET).invokeExact(recv, 1.0f); float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 1.0f, "set float value"); + assertEquals(1.0f, x, "set float value"); } @@ -134,21 +132,21 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact(recv, 2.0f); float x = (float) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(recv); - assertEquals(x, 2.0f, "setVolatile float value"); + assertEquals(2.0f, x, "setVolatile float value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact(recv, 1.0f); float x = (float) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(recv); - assertEquals(x, 1.0f, "setRelease float value"); + assertEquals(1.0f, x, "setRelease float value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact(recv, 2.0f); float x = (float) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(recv); - assertEquals(x, 2.0f, "setOpaque float value"); + assertEquals(2.0f, x, "setOpaque float value"); } hs.get(TestAccessMode.SET).invokeExact(recv, 1.0f); @@ -158,56 +156,56 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, 1.0f, 2.0f); assertEquals(r, true, "success compareAndSet float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 2.0f, "success compareAndSet float value"); + assertEquals(2.0f, x, "success compareAndSet float value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, 1.0f, 3.0f); assertEquals(r, false, "failing compareAndSet float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 2.0f, "failing compareAndSet float value"); + assertEquals(2.0f, x, "failing compareAndSet float value"); } { float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, 2.0f, 1.0f); assertEquals(r, 2.0f, "success compareAndExchange float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 1.0f, "success compareAndExchange float value"); + assertEquals(1.0f, x, "success compareAndExchange float value"); } { float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, 2.0f, 3.0f); assertEquals(r, 1.0f, "failing compareAndExchange float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 1.0f, "failing compareAndExchange float value"); + assertEquals(1.0f, x, "failing compareAndExchange float value"); } { float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, 1.0f, 2.0f); assertEquals(r, 1.0f, "success compareAndExchangeAcquire float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 2.0f, "success compareAndExchangeAcquire float value"); + assertEquals(2.0f, x, "success compareAndExchangeAcquire float value"); } { float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, 1.0f, 3.0f); assertEquals(r, 2.0f, "failing compareAndExchangeAcquire float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 2.0f, "failing compareAndExchangeAcquire float value"); + assertEquals(2.0f, x, "failing compareAndExchangeAcquire float value"); } { float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, 2.0f, 1.0f); assertEquals(r, 2.0f, "success compareAndExchangeRelease float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 1.0f, "success compareAndExchangeRelease float value"); + assertEquals(1.0f, x, "success compareAndExchangeRelease float value"); } { float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, 2.0f, 3.0f); assertEquals(r, 1.0f, "failing compareAndExchangeRelease float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 1.0f, "failing compareAndExchangeRelease float value"); + assertEquals(1.0f, x, "failing compareAndExchangeRelease float value"); } { @@ -219,14 +217,14 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 2.0f, "success weakCompareAndSetPlain float value"); + assertEquals(2.0f, x, "success weakCompareAndSetPlain float value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, 1.0f, 3.0f); assertEquals(success, false, "failing weakCompareAndSetPlain float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 2.0f, "failing weakCompareAndSetPlain float value"); + assertEquals(2.0f, x, "failing weakCompareAndSetPlain float value"); } { @@ -238,14 +236,14 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 1.0f, "success weakCompareAndSetAcquire float"); + assertEquals(1.0f, x, "success weakCompareAndSetAcquire float"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, 2.0f, 3.0f); assertEquals(success, false, "failing weakCompareAndSetAcquire float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 1.0f, "failing weakCompareAndSetAcquire float value"); + assertEquals(1.0f, x, "failing weakCompareAndSetAcquire float value"); } { @@ -257,14 +255,14 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 2.0f, "success weakCompareAndSetRelease float"); + assertEquals(2.0f, x, "success weakCompareAndSetRelease float"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, 1.0f, 3.0f); assertEquals(success, false, "failing weakCompareAndSetRelease float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 2.0f, "failing weakCompareAndSetRelease float value"); + assertEquals(2.0f, x, "failing weakCompareAndSetRelease float value"); } { @@ -276,22 +274,22 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 1.0f, "success weakCompareAndSet float"); + assertEquals(1.0f, x, "success weakCompareAndSet float"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, 2.0f, 3.0f); assertEquals(success, false, "failing weakCompareAndSet float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 1.0f, "failing weakCompareAndSet float value"); + assertEquals(1.0f, x, "failing weakCompareAndSet float value"); } // Compare set and get { float o = (float) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, 2.0f); - assertEquals(o, 1.0f, "getAndSet float"); + assertEquals(1.0f, o, "getAndSet float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 2.0f, "getAndSet float value"); + assertEquals(2.0f, x, "getAndSet float value"); } // get and add, add and get @@ -299,27 +297,27 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(recv, 1.0f); float o = (float) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(recv, 2.0f); - assertEquals(o, 1.0f, "getAndAdd float"); + assertEquals(1.0f, o, "getAndAdd float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (float)(1.0f + 2.0f), "getAndAdd float value"); + assertEquals((float)(1.0f + 2.0f), x, "getAndAdd float value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, 1.0f); float o = (float) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact(recv, 2.0f); - assertEquals(o, 1.0f, "getAndAddAcquire float"); + assertEquals(1.0f, o, "getAndAddAcquire float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (float)(1.0f + 2.0f), "getAndAddAcquire float value"); + assertEquals((float)(1.0f + 2.0f), x, "getAndAddAcquire float value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, 1.0f); float o = (float) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact(recv, 2.0f); - assertEquals(o, 1.0f, "getAndAddRelease float"); + assertEquals(1.0f, o, "getAndAddRelease float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (float)(1.0f + 2.0f), "getAndAddRelease float value"); + assertEquals((float)(1.0f + 2.0f), x, "getAndAddRelease float value"); } } @@ -340,7 +338,7 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { { hs.get(TestAccessMode.SET).invokeExact(1.0f); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 1.0f, "set float value"); + assertEquals(1.0f, x, "set float value"); } @@ -348,21 +346,21 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact(2.0f); float x = (float) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(); - assertEquals(x, 2.0f, "setVolatile float value"); + assertEquals(2.0f, x, "setVolatile float value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact(1.0f); float x = (float) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(); - assertEquals(x, 1.0f, "setRelease float value"); + assertEquals(1.0f, x, "setRelease float value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact(2.0f); float x = (float) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(); - assertEquals(x, 2.0f, "setOpaque float value"); + assertEquals(2.0f, x, "setOpaque float value"); } hs.get(TestAccessMode.SET).invokeExact(1.0f); @@ -372,56 +370,56 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(1.0f, 2.0f); assertEquals(r, true, "success compareAndSet float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 2.0f, "success compareAndSet float value"); + assertEquals(2.0f, x, "success compareAndSet float value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(1.0f, 3.0f); assertEquals(r, false, "failing compareAndSet float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 2.0f, "failing compareAndSet float value"); + assertEquals(2.0f, x, "failing compareAndSet float value"); } { float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(2.0f, 1.0f); assertEquals(r, 2.0f, "success compareAndExchange float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 1.0f, "success compareAndExchange float value"); + assertEquals(1.0f, x, "success compareAndExchange float value"); } { float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(2.0f, 3.0f); assertEquals(r, 1.0f, "failing compareAndExchange float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 1.0f, "failing compareAndExchange float value"); + assertEquals(1.0f, x, "failing compareAndExchange float value"); } { float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(1.0f, 2.0f); assertEquals(r, 1.0f, "success compareAndExchangeAcquire float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 2.0f, "success compareAndExchangeAcquire float value"); + assertEquals(2.0f, x, "success compareAndExchangeAcquire float value"); } { float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(1.0f, 3.0f); assertEquals(r, 2.0f, "failing compareAndExchangeAcquire float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 2.0f, "failing compareAndExchangeAcquire float value"); + assertEquals(2.0f, x, "failing compareAndExchangeAcquire float value"); } { float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(2.0f, 1.0f); assertEquals(r, 2.0f, "success compareAndExchangeRelease float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 1.0f, "success compareAndExchangeRelease float value"); + assertEquals(1.0f, x, "success compareAndExchangeRelease float value"); } { float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(2.0f, 3.0f); assertEquals(r, 1.0f, "failing compareAndExchangeRelease float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 1.0f, "failing compareAndExchangeRelease float value"); + assertEquals(1.0f, x, "failing compareAndExchangeRelease float value"); } { @@ -433,14 +431,14 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 2.0f, "success weakCompareAndSetPlain float value"); + assertEquals(2.0f, x, "success weakCompareAndSetPlain float value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(1.0f, 3.0f); assertEquals(success, false, "failing weakCompareAndSetPlain float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 2.0f, "failing weakCompareAndSetPlain float value"); + assertEquals(2.0f, x, "failing weakCompareAndSetPlain float value"); } { @@ -452,7 +450,7 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 1.0f, "success weakCompareAndSetAcquire float"); + assertEquals(1.0f, x, "success weakCompareAndSetAcquire float"); } { @@ -460,7 +458,7 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { boolean success = (boolean) mh.invokeExact(2.0f, 3.0f); assertEquals(success, false, "failing weakCompareAndSetAcquire float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 1.0f, "failing weakCompareAndSetAcquire float value"); + assertEquals(1.0f, x, "failing weakCompareAndSetAcquire float value"); } { @@ -472,14 +470,14 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 2.0f, "success weakCompareAndSetRelease float"); + assertEquals(2.0f, x, "success weakCompareAndSetRelease float"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(1.0f, 3.0f); assertEquals(success, false, "failing weakCompareAndSetRelease float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 2.0f, "failing weakCompareAndSetRelease float value"); + assertEquals(2.0f, x, "failing weakCompareAndSetRelease float value"); } { @@ -491,14 +489,14 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 1.0f, "success weakCompareAndSet float"); + assertEquals(1.0f, x, "success weakCompareAndSet float"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(2.0f, 3.0f); assertEquals(success, false, "failing weakCompareAndSet float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 1.0f, "failing weakCompareAndSetRe float value"); + assertEquals(1.0f, x, "failing weakCompareAndSetRe float value"); } // Compare set and get @@ -506,9 +504,9 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(1.0f); float o = (float) hs.get(TestAccessMode.GET_AND_SET).invokeExact(2.0f); - assertEquals(o, 1.0f, "getAndSet float"); + assertEquals(1.0f, o, "getAndSet float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 2.0f, "getAndSet float value"); + assertEquals(2.0f, x, "getAndSet float value"); } // Compare set and get @@ -516,9 +514,9 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(1.0f); float o = (float) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact(2.0f); - assertEquals(o, 1.0f, "getAndSetAcquire float"); + assertEquals(1.0f, o, "getAndSetAcquire float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 2.0f, "getAndSetAcquire float value"); + assertEquals(2.0f, x, "getAndSetAcquire float value"); } // Compare set and get @@ -526,9 +524,9 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(1.0f); float o = (float) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact(2.0f); - assertEquals(o, 1.0f, "getAndSetRelease float"); + assertEquals(1.0f, o, "getAndSetRelease float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 2.0f, "getAndSetRelease float value"); + assertEquals(2.0f, x, "getAndSetRelease float value"); } // get and add, add and get @@ -536,27 +534,27 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(1.0f); float o = (float) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(2.0f); - assertEquals(o, 1.0f, "getAndAdd float"); + assertEquals(1.0f, o, "getAndAdd float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (float)(1.0f + 2.0f), "getAndAdd float value"); + assertEquals((float)(1.0f + 2.0f), x, "getAndAdd float value"); } { hs.get(TestAccessMode.SET).invokeExact(1.0f); float o = (float) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact(2.0f); - assertEquals(o, 1.0f, "getAndAddAcquire float"); + assertEquals(1.0f, o, "getAndAddAcquire float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (float)(1.0f + 2.0f), "getAndAddAcquire float value"); + assertEquals((float)(1.0f + 2.0f), x, "getAndAddAcquire float value"); } { hs.get(TestAccessMode.SET).invokeExact(1.0f); float o = (float) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact(2.0f); - assertEquals(o, 1.0f, "getAndAddRelease float"); + assertEquals(1.0f, o, "getAndAddRelease float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (float)(1.0f + 2.0f), "getAndAddRelease float value"); + assertEquals((float)(1.0f + 2.0f), x, "getAndAddRelease float value"); } } @@ -580,7 +578,7 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { { hs.get(TestAccessMode.SET).invokeExact(array, i, 1.0f); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 1.0f, "get float value"); + assertEquals(1.0f, x, "get float value"); } @@ -588,21 +586,21 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact(array, i, 2.0f); float x = (float) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(array, i); - assertEquals(x, 2.0f, "setVolatile float value"); + assertEquals(2.0f, x, "setVolatile float value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact(array, i, 1.0f); float x = (float) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(array, i); - assertEquals(x, 1.0f, "setRelease float value"); + assertEquals(1.0f, x, "setRelease float value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact(array, i, 2.0f); float x = (float) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(array, i); - assertEquals(x, 2.0f, "setOpaque float value"); + assertEquals(2.0f, x, "setOpaque float value"); } hs.get(TestAccessMode.SET).invokeExact(array, i, 1.0f); @@ -612,56 +610,56 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, 1.0f, 2.0f); assertEquals(r, true, "success compareAndSet float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 2.0f, "success compareAndSet float value"); + assertEquals(2.0f, x, "success compareAndSet float value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, 1.0f, 3.0f); assertEquals(r, false, "failing compareAndSet float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 2.0f, "failing compareAndSet float value"); + assertEquals(2.0f, x, "failing compareAndSet float value"); } { float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, 2.0f, 1.0f); assertEquals(r, 2.0f, "success compareAndExchange float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 1.0f, "success compareAndExchange float value"); + assertEquals(1.0f, x, "success compareAndExchange float value"); } { float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, 2.0f, 3.0f); assertEquals(r, 1.0f, "failing compareAndExchange float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 1.0f, "failing compareAndExchange float value"); + assertEquals(1.0f, x, "failing compareAndExchange float value"); } { float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, 1.0f, 2.0f); assertEquals(r, 1.0f, "success compareAndExchangeAcquire float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 2.0f, "success compareAndExchangeAcquire float value"); + assertEquals(2.0f, x, "success compareAndExchangeAcquire float value"); } { float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, 1.0f, 3.0f); assertEquals(r, 2.0f, "failing compareAndExchangeAcquire float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 2.0f, "failing compareAndExchangeAcquire float value"); + assertEquals(2.0f, x, "failing compareAndExchangeAcquire float value"); } { float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, 2.0f, 1.0f); assertEquals(r, 2.0f, "success compareAndExchangeRelease float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 1.0f, "success compareAndExchangeRelease float value"); + assertEquals(1.0f, x, "success compareAndExchangeRelease float value"); } { float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, 2.0f, 3.0f); assertEquals(r, 1.0f, "failing compareAndExchangeRelease float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 1.0f, "failing compareAndExchangeRelease float value"); + assertEquals(1.0f, x, "failing compareAndExchangeRelease float value"); } { @@ -673,14 +671,14 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 2.0f, "success weakCompareAndSetPlain float value"); + assertEquals(2.0f, x, "success weakCompareAndSetPlain float value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, 1.0f, 3.0f); assertEquals(success, false, "failing weakCompareAndSetPlain float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 2.0f, "failing weakCompareAndSetPlain float value"); + assertEquals(2.0f, x, "failing weakCompareAndSetPlain float value"); } { @@ -692,14 +690,14 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 1.0f, "success weakCompareAndSetAcquire float"); + assertEquals(1.0f, x, "success weakCompareAndSetAcquire float"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 2.0f, 3.0f); assertEquals(success, false, "failing weakCompareAndSetAcquire float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 1.0f, "failing weakCompareAndSetAcquire float value"); + assertEquals(1.0f, x, "failing weakCompareAndSetAcquire float value"); } { @@ -711,14 +709,14 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 2.0f, "success weakCompareAndSetRelease float"); + assertEquals(2.0f, x, "success weakCompareAndSetRelease float"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 1.0f, 3.0f); assertEquals(success, false, "failing weakCompareAndSetAcquire float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 2.0f, "failing weakCompareAndSetAcquire float value"); + assertEquals(2.0f, x, "failing weakCompareAndSetAcquire float value"); } { @@ -730,14 +728,14 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 1.0f, "success weakCompareAndSet float"); + assertEquals(1.0f, x, "success weakCompareAndSet float"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, 2.0f, 3.0f); assertEquals(success, false, "failing weakCompareAndSet float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 1.0f, "failing weakCompareAndSet float value"); + assertEquals(1.0f, x, "failing weakCompareAndSet float value"); } // Compare set and get @@ -745,27 +743,27 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, 1.0f); float o = (float) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, 2.0f); - assertEquals(o, 1.0f, "getAndSet float"); + assertEquals(1.0f, o, "getAndSet float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 2.0f, "getAndSet float value"); + assertEquals(2.0f, x, "getAndSet float value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, 1.0f); float o = (float) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact(array, i, 2.0f); - assertEquals(o, 1.0f, "getAndSetAcquire float"); + assertEquals(1.0f, o, "getAndSetAcquire float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 2.0f, "getAndSetAcquire float value"); + assertEquals(2.0f, x, "getAndSetAcquire float value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, 1.0f); float o = (float) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact(array, i, 2.0f); - assertEquals(o, 1.0f, "getAndSetRelease float"); + assertEquals(1.0f, o, "getAndSetRelease float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 2.0f, "getAndSetRelease float value"); + assertEquals(2.0f, x, "getAndSetRelease float value"); } // get and add, add and get @@ -773,27 +771,27 @@ public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, 1.0f); float o = (float) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(array, i, 2.0f); - assertEquals(o, 1.0f, "getAndAdd float"); + assertEquals(1.0f, o, "getAndAdd float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (float)(1.0f + 2.0f), "getAndAdd float value"); + assertEquals((float)(1.0f + 2.0f), x, "getAndAdd float value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, 1.0f); float o = (float) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact(array, i, 2.0f); - assertEquals(o, 1.0f, "getAndAddAcquire float"); + assertEquals(1.0f, o, "getAndAddAcquire float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (float)(1.0f + 2.0f), "getAndAddAcquire float value"); + assertEquals((float)(1.0f + 2.0f), x, "getAndAddAcquire float value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, 1.0f); float o = (float) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact(array, i, 2.0f); - assertEquals(o, 1.0f, "getAndAddRelease float"); + assertEquals(1.0f, o, "getAndAddRelease float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (float)(1.0f + 2.0f), "getAndAddRelease float value"); + assertEquals((float)(1.0f + 2.0f), x, "getAndAddRelease float value"); } } diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessInt.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessInt.java index d8558e0b070..920d8453bab 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessInt.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessInt.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,22 +25,22 @@ * @test * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations * to hit compilation thresholds - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestMethodHandleAccessInt + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestMethodHandleAccessInt */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { static final int static_final_v = 0x01234567; @@ -60,7 +60,7 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { VarHandle vhArray; - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestMethodHandleAccessInt.class, "final_v", int.class); @@ -77,8 +77,6 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { vhArray = MethodHandles.arrayElementVarHandle(int[].class); } - - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -111,7 +109,8 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -120,13 +119,12 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { } } - static void testInstanceField(VarHandleTestMethodHandleAccessInt recv, Handles hs) throws Throwable { // Plain { hs.get(TestAccessMode.SET).invokeExact(recv, 0x01234567); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x01234567, "set int value"); + assertEquals(0x01234567, x, "set int value"); } @@ -134,21 +132,21 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact(recv, 0x89ABCDEF); int x = (int) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(recv); - assertEquals(x, 0x89ABCDEF, "setVolatile int value"); + assertEquals(0x89ABCDEF, x, "setVolatile int value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact(recv, 0x01234567); int x = (int) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(recv); - assertEquals(x, 0x01234567, "setRelease int value"); + assertEquals(0x01234567, x, "setRelease int value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact(recv, 0x89ABCDEF); int x = (int) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(recv); - assertEquals(x, 0x89ABCDEF, "setOpaque int value"); + assertEquals(0x89ABCDEF, x, "setOpaque int value"); } hs.get(TestAccessMode.SET).invokeExact(recv, 0x01234567); @@ -158,56 +156,56 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, 0x01234567, 0x89ABCDEF); assertEquals(r, true, "success compareAndSet int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x89ABCDEF, "success compareAndSet int value"); + assertEquals(0x89ABCDEF, x, "success compareAndSet int value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, 0x01234567, 0xCAFEBABE); assertEquals(r, false, "failing compareAndSet int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x89ABCDEF, "failing compareAndSet int value"); + assertEquals(0x89ABCDEF, x, "failing compareAndSet int value"); } { int r = (int) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, 0x89ABCDEF, 0x01234567); assertEquals(r, 0x89ABCDEF, "success compareAndExchange int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x01234567, "success compareAndExchange int value"); + assertEquals(0x01234567, x, "success compareAndExchange int value"); } { int r = (int) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, 0x89ABCDEF, 0xCAFEBABE); assertEquals(r, 0x01234567, "failing compareAndExchange int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x01234567, "failing compareAndExchange int value"); + assertEquals(0x01234567, x, "failing compareAndExchange int value"); } { int r = (int) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, 0x01234567, 0x89ABCDEF); assertEquals(r, 0x01234567, "success compareAndExchangeAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x89ABCDEF, "success compareAndExchangeAcquire int value"); + assertEquals(0x89ABCDEF, x, "success compareAndExchangeAcquire int value"); } { int r = (int) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, 0x01234567, 0xCAFEBABE); assertEquals(r, 0x89ABCDEF, "failing compareAndExchangeAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x89ABCDEF, "failing compareAndExchangeAcquire int value"); + assertEquals(0x89ABCDEF, x, "failing compareAndExchangeAcquire int value"); } { int r = (int) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, 0x89ABCDEF, 0x01234567); assertEquals(r, 0x89ABCDEF, "success compareAndExchangeRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x01234567, "success compareAndExchangeRelease int value"); + assertEquals(0x01234567, x, "success compareAndExchangeRelease int value"); } { int r = (int) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, 0x89ABCDEF, 0xCAFEBABE); assertEquals(r, 0x01234567, "failing compareAndExchangeRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x01234567, "failing compareAndExchangeRelease int value"); + assertEquals(0x01234567, x, "failing compareAndExchangeRelease int value"); } { @@ -219,14 +217,14 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x89ABCDEF, "success weakCompareAndSetPlain int value"); + assertEquals(0x89ABCDEF, x, "success weakCompareAndSetPlain int value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, 0x01234567, 0xCAFEBABE); assertEquals(success, false, "failing weakCompareAndSetPlain int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x89ABCDEF, "failing weakCompareAndSetPlain int value"); + assertEquals(0x89ABCDEF, x, "failing weakCompareAndSetPlain int value"); } { @@ -238,14 +236,14 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x01234567, "success weakCompareAndSetAcquire int"); + assertEquals(0x01234567, x, "success weakCompareAndSetAcquire int"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, 0x89ABCDEF, 0xCAFEBABE); assertEquals(success, false, "failing weakCompareAndSetAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x01234567, "failing weakCompareAndSetAcquire int value"); + assertEquals(0x01234567, x, "failing weakCompareAndSetAcquire int value"); } { @@ -257,14 +255,14 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x89ABCDEF, "success weakCompareAndSetRelease int"); + assertEquals(0x89ABCDEF, x, "success weakCompareAndSetRelease int"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, 0x01234567, 0xCAFEBABE); assertEquals(success, false, "failing weakCompareAndSetRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x89ABCDEF, "failing weakCompareAndSetRelease int value"); + assertEquals(0x89ABCDEF, x, "failing weakCompareAndSetRelease int value"); } { @@ -276,22 +274,22 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x01234567, "success weakCompareAndSet int"); + assertEquals(0x01234567, x, "success weakCompareAndSet int"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, 0x89ABCDEF, 0xCAFEBABE); assertEquals(success, false, "failing weakCompareAndSet int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x01234567, "failing weakCompareAndSet int value"); + assertEquals(0x01234567, x, "failing weakCompareAndSet int value"); } // Compare set and get { int o = (int) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndSet int"); + assertEquals(0x01234567, o, "getAndSet int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x89ABCDEF, "getAndSet int value"); + assertEquals(0x89ABCDEF, x, "getAndSet int value"); } // get and add, add and get @@ -299,27 +297,27 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(recv, 0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(recv, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndAdd int"); + assertEquals(0x01234567, o, "getAndAdd int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (int)(0x01234567 + 0x89ABCDEF), "getAndAdd int value"); + assertEquals((int)(0x01234567 + 0x89ABCDEF), x, "getAndAdd int value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, 0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact(recv, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndAddAcquire int"); + assertEquals(0x01234567, o, "getAndAddAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (int)(0x01234567 + 0x89ABCDEF), "getAndAddAcquire int value"); + assertEquals((int)(0x01234567 + 0x89ABCDEF), x, "getAndAddAcquire int value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, 0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact(recv, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndAddRelease int"); + assertEquals(0x01234567, o, "getAndAddRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (int)(0x01234567 + 0x89ABCDEF), "getAndAddRelease int value"); + assertEquals((int)(0x01234567 + 0x89ABCDEF), x, "getAndAddRelease int value"); } // get and bitwise or @@ -327,27 +325,27 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(recv, 0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_BITWISE_OR).invokeExact(recv, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseOr int"); + assertEquals(0x01234567, o, "getAndBitwiseOr int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (int)(0x01234567 | 0x89ABCDEF), "getAndBitwiseOr int value"); + assertEquals((int)(0x01234567 | 0x89ABCDEF), x, "getAndBitwiseOr int value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, 0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_BITWISE_OR_ACQUIRE).invokeExact(recv, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseOrAcquire int"); + assertEquals(0x01234567, o, "getAndBitwiseOrAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (int)(0x01234567 | 0x89ABCDEF), "getAndBitwiseOrAcquire int value"); + assertEquals((int)(0x01234567 | 0x89ABCDEF), x, "getAndBitwiseOrAcquire int value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, 0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_BITWISE_OR_RELEASE).invokeExact(recv, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseOrRelease int"); + assertEquals(0x01234567, o, "getAndBitwiseOrRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (int)(0x01234567 | 0x89ABCDEF), "getAndBitwiseOrRelease int value"); + assertEquals((int)(0x01234567 | 0x89ABCDEF), x, "getAndBitwiseOrRelease int value"); } // get and bitwise and @@ -355,27 +353,27 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(recv, 0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_BITWISE_AND).invokeExact(recv, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseAnd int"); + assertEquals(0x01234567, o, "getAndBitwiseAnd int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (int)(0x01234567 & 0x89ABCDEF), "getAndBitwiseAnd int value"); + assertEquals((int)(0x01234567 & 0x89ABCDEF), x, "getAndBitwiseAnd int value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, 0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_BITWISE_AND_ACQUIRE).invokeExact(recv, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseAndAcquire int"); + assertEquals(0x01234567, o, "getAndBitwiseAndAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (int)(0x01234567 & 0x89ABCDEF), "getAndBitwiseAndAcquire int value"); + assertEquals((int)(0x01234567 & 0x89ABCDEF), x, "getAndBitwiseAndAcquire int value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, 0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_BITWISE_AND_RELEASE).invokeExact(recv, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseAndRelease int"); + assertEquals(0x01234567, o, "getAndBitwiseAndRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (int)(0x01234567 & 0x89ABCDEF), "getAndBitwiseAndRelease int value"); + assertEquals((int)(0x01234567 & 0x89ABCDEF), x, "getAndBitwiseAndRelease int value"); } // get and bitwise xor @@ -383,27 +381,27 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(recv, 0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_BITWISE_XOR).invokeExact(recv, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseXor int"); + assertEquals(0x01234567, o, "getAndBitwiseXor int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (int)(0x01234567 ^ 0x89ABCDEF), "getAndBitwiseXor int value"); + assertEquals((int)(0x01234567 ^ 0x89ABCDEF), x, "getAndBitwiseXor int value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, 0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_ACQUIRE).invokeExact(recv, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseXorAcquire int"); + assertEquals(0x01234567, o, "getAndBitwiseXorAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (int)(0x01234567 ^ 0x89ABCDEF), "getAndBitwiseXorAcquire int value"); + assertEquals((int)(0x01234567 ^ 0x89ABCDEF), x, "getAndBitwiseXorAcquire int value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, 0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_RELEASE).invokeExact(recv, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseXorRelease int"); + assertEquals(0x01234567, o, "getAndBitwiseXorRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (int)(0x01234567 ^ 0x89ABCDEF), "getAndBitwiseXorRelease int value"); + assertEquals((int)(0x01234567 ^ 0x89ABCDEF), x, "getAndBitwiseXorRelease int value"); } } @@ -418,7 +416,7 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { { hs.get(TestAccessMode.SET).invokeExact(0x01234567); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x01234567, "set int value"); + assertEquals(0x01234567, x, "set int value"); } @@ -426,21 +424,21 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact(0x89ABCDEF); int x = (int) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(); - assertEquals(x, 0x89ABCDEF, "setVolatile int value"); + assertEquals(0x89ABCDEF, x, "setVolatile int value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact(0x01234567); int x = (int) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(); - assertEquals(x, 0x01234567, "setRelease int value"); + assertEquals(0x01234567, x, "setRelease int value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact(0x89ABCDEF); int x = (int) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(); - assertEquals(x, 0x89ABCDEF, "setOpaque int value"); + assertEquals(0x89ABCDEF, x, "setOpaque int value"); } hs.get(TestAccessMode.SET).invokeExact(0x01234567); @@ -450,56 +448,56 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(0x01234567, 0x89ABCDEF); assertEquals(r, true, "success compareAndSet int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x89ABCDEF, "success compareAndSet int value"); + assertEquals(0x89ABCDEF, x, "success compareAndSet int value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(0x01234567, 0xCAFEBABE); assertEquals(r, false, "failing compareAndSet int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x89ABCDEF, "failing compareAndSet int value"); + assertEquals(0x89ABCDEF, x, "failing compareAndSet int value"); } { int r = (int) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(0x89ABCDEF, 0x01234567); assertEquals(r, 0x89ABCDEF, "success compareAndExchange int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x01234567, "success compareAndExchange int value"); + assertEquals(0x01234567, x, "success compareAndExchange int value"); } { int r = (int) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(0x89ABCDEF, 0xCAFEBABE); assertEquals(r, 0x01234567, "failing compareAndExchange int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x01234567, "failing compareAndExchange int value"); + assertEquals(0x01234567, x, "failing compareAndExchange int value"); } { int r = (int) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(0x01234567, 0x89ABCDEF); assertEquals(r, 0x01234567, "success compareAndExchangeAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x89ABCDEF, "success compareAndExchangeAcquire int value"); + assertEquals(0x89ABCDEF, x, "success compareAndExchangeAcquire int value"); } { int r = (int) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(0x01234567, 0xCAFEBABE); assertEquals(r, 0x89ABCDEF, "failing compareAndExchangeAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x89ABCDEF, "failing compareAndExchangeAcquire int value"); + assertEquals(0x89ABCDEF, x, "failing compareAndExchangeAcquire int value"); } { int r = (int) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(0x89ABCDEF, 0x01234567); assertEquals(r, 0x89ABCDEF, "success compareAndExchangeRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x01234567, "success compareAndExchangeRelease int value"); + assertEquals(0x01234567, x, "success compareAndExchangeRelease int value"); } { int r = (int) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(0x89ABCDEF, 0xCAFEBABE); assertEquals(r, 0x01234567, "failing compareAndExchangeRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x01234567, "failing compareAndExchangeRelease int value"); + assertEquals(0x01234567, x, "failing compareAndExchangeRelease int value"); } { @@ -511,14 +509,14 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x89ABCDEF, "success weakCompareAndSetPlain int value"); + assertEquals(0x89ABCDEF, x, "success weakCompareAndSetPlain int value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(0x01234567, 0xCAFEBABE); assertEquals(success, false, "failing weakCompareAndSetPlain int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x89ABCDEF, "failing weakCompareAndSetPlain int value"); + assertEquals(0x89ABCDEF, x, "failing weakCompareAndSetPlain int value"); } { @@ -530,7 +528,7 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x01234567, "success weakCompareAndSetAcquire int"); + assertEquals(0x01234567, x, "success weakCompareAndSetAcquire int"); } { @@ -538,7 +536,7 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { boolean success = (boolean) mh.invokeExact(0x89ABCDEF, 0xCAFEBABE); assertEquals(success, false, "failing weakCompareAndSetAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x01234567, "failing weakCompareAndSetAcquire int value"); + assertEquals(0x01234567, x, "failing weakCompareAndSetAcquire int value"); } { @@ -550,14 +548,14 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x89ABCDEF, "success weakCompareAndSetRelease int"); + assertEquals(0x89ABCDEF, x, "success weakCompareAndSetRelease int"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(0x01234567, 0xCAFEBABE); assertEquals(success, false, "failing weakCompareAndSetRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x89ABCDEF, "failing weakCompareAndSetRelease int value"); + assertEquals(0x89ABCDEF, x, "failing weakCompareAndSetRelease int value"); } { @@ -569,14 +567,14 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x01234567, "success weakCompareAndSet int"); + assertEquals(0x01234567, x, "success weakCompareAndSet int"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(0x89ABCDEF, 0xCAFEBABE); assertEquals(success, false, "failing weakCompareAndSet int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x01234567, "failing weakCompareAndSetRe int value"); + assertEquals(0x01234567, x, "failing weakCompareAndSetRe int value"); } // Compare set and get @@ -584,9 +582,9 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_SET).invokeExact(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndSet int"); + assertEquals(0x01234567, o, "getAndSet int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x89ABCDEF, "getAndSet int value"); + assertEquals(0x89ABCDEF, x, "getAndSet int value"); } // Compare set and get @@ -594,9 +592,9 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndSetAcquire int"); + assertEquals(0x01234567, o, "getAndSetAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x89ABCDEF, "getAndSetAcquire int value"); + assertEquals(0x89ABCDEF, x, "getAndSetAcquire int value"); } // Compare set and get @@ -604,9 +602,9 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndSetRelease int"); + assertEquals(0x01234567, o, "getAndSetRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x89ABCDEF, "getAndSetRelease int value"); + assertEquals(0x89ABCDEF, x, "getAndSetRelease int value"); } // get and add, add and get @@ -614,27 +612,27 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndAdd int"); + assertEquals(0x01234567, o, "getAndAdd int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (int)(0x01234567 + 0x89ABCDEF), "getAndAdd int value"); + assertEquals((int)(0x01234567 + 0x89ABCDEF), x, "getAndAdd int value"); } { hs.get(TestAccessMode.SET).invokeExact(0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndAddAcquire int"); + assertEquals(0x01234567, o, "getAndAddAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (int)(0x01234567 + 0x89ABCDEF), "getAndAddAcquire int value"); + assertEquals((int)(0x01234567 + 0x89ABCDEF), x, "getAndAddAcquire int value"); } { hs.get(TestAccessMode.SET).invokeExact(0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndAddRelease int"); + assertEquals(0x01234567, o, "getAndAddRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (int)(0x01234567 + 0x89ABCDEF), "getAndAddRelease int value"); + assertEquals((int)(0x01234567 + 0x89ABCDEF), x, "getAndAddRelease int value"); } // get and bitwise or @@ -642,27 +640,27 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_BITWISE_OR).invokeExact(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseOr int"); + assertEquals(0x01234567, o, "getAndBitwiseOr int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (int)(0x01234567 | 0x89ABCDEF), "getAndBitwiseOr int value"); + assertEquals((int)(0x01234567 | 0x89ABCDEF), x, "getAndBitwiseOr int value"); } { hs.get(TestAccessMode.SET).invokeExact(0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_BITWISE_OR_ACQUIRE).invokeExact(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseOrAcquire int"); + assertEquals(0x01234567, o, "getAndBitwiseOrAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (int)(0x01234567 | 0x89ABCDEF), "getAndBitwiseOrAcquire int value"); + assertEquals((int)(0x01234567 | 0x89ABCDEF), x, "getAndBitwiseOrAcquire int value"); } { hs.get(TestAccessMode.SET).invokeExact(0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_BITWISE_OR_RELEASE).invokeExact(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseOrRelease int"); + assertEquals(0x01234567, o, "getAndBitwiseOrRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (int)(0x01234567 | 0x89ABCDEF), "getAndBitwiseOrRelease int value"); + assertEquals((int)(0x01234567 | 0x89ABCDEF), x, "getAndBitwiseOrRelease int value"); } // get and bitwise and @@ -670,27 +668,27 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_BITWISE_AND).invokeExact(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseAnd int"); + assertEquals(0x01234567, o, "getAndBitwiseAnd int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (int)(0x01234567 & 0x89ABCDEF), "getAndBitwiseAnd int value"); + assertEquals((int)(0x01234567 & 0x89ABCDEF), x, "getAndBitwiseAnd int value"); } { hs.get(TestAccessMode.SET).invokeExact(0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_BITWISE_AND_ACQUIRE).invokeExact(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseAndAcquire int"); + assertEquals(0x01234567, o, "getAndBitwiseAndAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (int)(0x01234567 & 0x89ABCDEF), "getAndBitwiseAndAcquire int value"); + assertEquals((int)(0x01234567 & 0x89ABCDEF), x, "getAndBitwiseAndAcquire int value"); } { hs.get(TestAccessMode.SET).invokeExact(0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_BITWISE_AND_RELEASE).invokeExact(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseAndRelease int"); + assertEquals(0x01234567, o, "getAndBitwiseAndRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (int)(0x01234567 & 0x89ABCDEF), "getAndBitwiseAndRelease int value"); + assertEquals((int)(0x01234567 & 0x89ABCDEF), x, "getAndBitwiseAndRelease int value"); } // get and bitwise xor @@ -698,27 +696,27 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_BITWISE_XOR).invokeExact(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseXor int"); + assertEquals(0x01234567, o, "getAndBitwiseXor int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (int)(0x01234567 ^ 0x89ABCDEF), "getAndBitwiseXor int value"); + assertEquals((int)(0x01234567 ^ 0x89ABCDEF), x, "getAndBitwiseXor int value"); } { hs.get(TestAccessMode.SET).invokeExact(0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_ACQUIRE).invokeExact(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseXorAcquire int"); + assertEquals(0x01234567, o, "getAndBitwiseXorAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (int)(0x01234567 ^ 0x89ABCDEF), "getAndBitwiseXorAcquire int value"); + assertEquals((int)(0x01234567 ^ 0x89ABCDEF), x, "getAndBitwiseXorAcquire int value"); } { hs.get(TestAccessMode.SET).invokeExact(0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_RELEASE).invokeExact(0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseXorRelease int"); + assertEquals(0x01234567, o, "getAndBitwiseXorRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (int)(0x01234567 ^ 0x89ABCDEF), "getAndBitwiseXorRelease int value"); + assertEquals((int)(0x01234567 ^ 0x89ABCDEF), x, "getAndBitwiseXorRelease int value"); } } @@ -736,7 +734,7 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x01234567); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x01234567, "get int value"); + assertEquals(0x01234567, x, "get int value"); } @@ -744,21 +742,21 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact(array, i, 0x89ABCDEF); int x = (int) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(array, i); - assertEquals(x, 0x89ABCDEF, "setVolatile int value"); + assertEquals(0x89ABCDEF, x, "setVolatile int value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact(array, i, 0x01234567); int x = (int) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(array, i); - assertEquals(x, 0x01234567, "setRelease int value"); + assertEquals(0x01234567, x, "setRelease int value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact(array, i, 0x89ABCDEF); int x = (int) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(array, i); - assertEquals(x, 0x89ABCDEF, "setOpaque int value"); + assertEquals(0x89ABCDEF, x, "setOpaque int value"); } hs.get(TestAccessMode.SET).invokeExact(array, i, 0x01234567); @@ -768,56 +766,56 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, 0x01234567, 0x89ABCDEF); assertEquals(r, true, "success compareAndSet int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x89ABCDEF, "success compareAndSet int value"); + assertEquals(0x89ABCDEF, x, "success compareAndSet int value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, 0x01234567, 0xCAFEBABE); assertEquals(r, false, "failing compareAndSet int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x89ABCDEF, "failing compareAndSet int value"); + assertEquals(0x89ABCDEF, x, "failing compareAndSet int value"); } { int r = (int) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, 0x89ABCDEF, 0x01234567); assertEquals(r, 0x89ABCDEF, "success compareAndExchange int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x01234567, "success compareAndExchange int value"); + assertEquals(0x01234567, x, "success compareAndExchange int value"); } { int r = (int) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, 0x89ABCDEF, 0xCAFEBABE); assertEquals(r, 0x01234567, "failing compareAndExchange int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x01234567, "failing compareAndExchange int value"); + assertEquals(0x01234567, x, "failing compareAndExchange int value"); } { int r = (int) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, 0x01234567, 0x89ABCDEF); assertEquals(r, 0x01234567, "success compareAndExchangeAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x89ABCDEF, "success compareAndExchangeAcquire int value"); + assertEquals(0x89ABCDEF, x, "success compareAndExchangeAcquire int value"); } { int r = (int) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, 0x01234567, 0xCAFEBABE); assertEquals(r, 0x89ABCDEF, "failing compareAndExchangeAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x89ABCDEF, "failing compareAndExchangeAcquire int value"); + assertEquals(0x89ABCDEF, x, "failing compareAndExchangeAcquire int value"); } { int r = (int) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, 0x89ABCDEF, 0x01234567); assertEquals(r, 0x89ABCDEF, "success compareAndExchangeRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x01234567, "success compareAndExchangeRelease int value"); + assertEquals(0x01234567, x, "success compareAndExchangeRelease int value"); } { int r = (int) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, 0x89ABCDEF, 0xCAFEBABE); assertEquals(r, 0x01234567, "failing compareAndExchangeRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x01234567, "failing compareAndExchangeRelease int value"); + assertEquals(0x01234567, x, "failing compareAndExchangeRelease int value"); } { @@ -829,14 +827,14 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x89ABCDEF, "success weakCompareAndSetPlain int value"); + assertEquals(0x89ABCDEF, x, "success weakCompareAndSetPlain int value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, 0x01234567, 0xCAFEBABE); assertEquals(success, false, "failing weakCompareAndSetPlain int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x89ABCDEF, "failing weakCompareAndSetPlain int value"); + assertEquals(0x89ABCDEF, x, "failing weakCompareAndSetPlain int value"); } { @@ -848,14 +846,14 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x01234567, "success weakCompareAndSetAcquire int"); + assertEquals(0x01234567, x, "success weakCompareAndSetAcquire int"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 0x89ABCDEF, 0xCAFEBABE); assertEquals(success, false, "failing weakCompareAndSetAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x01234567, "failing weakCompareAndSetAcquire int value"); + assertEquals(0x01234567, x, "failing weakCompareAndSetAcquire int value"); } { @@ -867,14 +865,14 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x89ABCDEF, "success weakCompareAndSetRelease int"); + assertEquals(0x89ABCDEF, x, "success weakCompareAndSetRelease int"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 0x01234567, 0xCAFEBABE); assertEquals(success, false, "failing weakCompareAndSetAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x89ABCDEF, "failing weakCompareAndSetAcquire int value"); + assertEquals(0x89ABCDEF, x, "failing weakCompareAndSetAcquire int value"); } { @@ -886,14 +884,14 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x01234567, "success weakCompareAndSet int"); + assertEquals(0x01234567, x, "success weakCompareAndSet int"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, 0x89ABCDEF, 0xCAFEBABE); assertEquals(success, false, "failing weakCompareAndSet int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x01234567, "failing weakCompareAndSet int value"); + assertEquals(0x01234567, x, "failing weakCompareAndSet int value"); } // Compare set and get @@ -901,27 +899,27 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndSet int"); + assertEquals(0x01234567, o, "getAndSet int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x89ABCDEF, "getAndSet int value"); + assertEquals(0x89ABCDEF, x, "getAndSet int value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndSetAcquire int"); + assertEquals(0x01234567, o, "getAndSetAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x89ABCDEF, "getAndSetAcquire int value"); + assertEquals(0x89ABCDEF, x, "getAndSetAcquire int value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndSetRelease int"); + assertEquals(0x01234567, o, "getAndSetRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x89ABCDEF, "getAndSetRelease int value"); + assertEquals(0x89ABCDEF, x, "getAndSetRelease int value"); } // get and add, add and get @@ -929,27 +927,27 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndAdd int"); + assertEquals(0x01234567, o, "getAndAdd int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (int)(0x01234567 + 0x89ABCDEF), "getAndAdd int value"); + assertEquals((int)(0x01234567 + 0x89ABCDEF), x, "getAndAdd int value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndAddAcquire int"); + assertEquals(0x01234567, o, "getAndAddAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (int)(0x01234567 + 0x89ABCDEF), "getAndAddAcquire int value"); + assertEquals((int)(0x01234567 + 0x89ABCDEF), x, "getAndAddAcquire int value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndAddRelease int"); + assertEquals(0x01234567, o, "getAndAddRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (int)(0x01234567 + 0x89ABCDEF), "getAndAddRelease int value"); + assertEquals((int)(0x01234567 + 0x89ABCDEF), x, "getAndAddRelease int value"); } // get and bitwise or @@ -957,27 +955,27 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_BITWISE_OR).invokeExact(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseOr int"); + assertEquals(0x01234567, o, "getAndBitwiseOr int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (int)(0x01234567 | 0x89ABCDEF), "getAndBitwiseOr int value"); + assertEquals((int)(0x01234567 | 0x89ABCDEF), x, "getAndBitwiseOr int value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_BITWISE_OR_ACQUIRE).invokeExact(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseOrAcquire int"); + assertEquals(0x01234567, o, "getAndBitwiseOrAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (int)(0x01234567 | 0x89ABCDEF), "getAndBitwiseOrAcquire int value"); + assertEquals((int)(0x01234567 | 0x89ABCDEF), x, "getAndBitwiseOrAcquire int value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_BITWISE_OR_RELEASE).invokeExact(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseOrRelease int"); + assertEquals(0x01234567, o, "getAndBitwiseOrRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (int)(0x01234567 | 0x89ABCDEF), "getAndBitwiseOrRelease int value"); + assertEquals((int)(0x01234567 | 0x89ABCDEF), x, "getAndBitwiseOrRelease int value"); } // get and bitwise and @@ -985,27 +983,27 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_BITWISE_AND).invokeExact(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseAnd int"); + assertEquals(0x01234567, o, "getAndBitwiseAnd int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (int)(0x01234567 & 0x89ABCDEF), "getAndBitwiseAnd int value"); + assertEquals((int)(0x01234567 & 0x89ABCDEF), x, "getAndBitwiseAnd int value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_BITWISE_AND_ACQUIRE).invokeExact(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseAndAcquire int"); + assertEquals(0x01234567, o, "getAndBitwiseAndAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (int)(0x01234567 & 0x89ABCDEF), "getAndBitwiseAndAcquire int value"); + assertEquals((int)(0x01234567 & 0x89ABCDEF), x, "getAndBitwiseAndAcquire int value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_BITWISE_AND_RELEASE).invokeExact(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseAndRelease int"); + assertEquals(0x01234567, o, "getAndBitwiseAndRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (int)(0x01234567 & 0x89ABCDEF), "getAndBitwiseAndRelease int value"); + assertEquals((int)(0x01234567 & 0x89ABCDEF), x, "getAndBitwiseAndRelease int value"); } // get and bitwise xor @@ -1013,27 +1011,27 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_BITWISE_XOR).invokeExact(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseXor int"); + assertEquals(0x01234567, o, "getAndBitwiseXor int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (int)(0x01234567 ^ 0x89ABCDEF), "getAndBitwiseXor int value"); + assertEquals((int)(0x01234567 ^ 0x89ABCDEF), x, "getAndBitwiseXor int value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_ACQUIRE).invokeExact(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseXorAcquire int"); + assertEquals(0x01234567, o, "getAndBitwiseXorAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (int)(0x01234567 ^ 0x89ABCDEF), "getAndBitwiseXorAcquire int value"); + assertEquals((int)(0x01234567 ^ 0x89ABCDEF), x, "getAndBitwiseXorAcquire int value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x01234567); int o = (int) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_RELEASE).invokeExact(array, i, 0x89ABCDEF); - assertEquals(o, 0x01234567, "getAndBitwiseXorRelease int"); + assertEquals(0x01234567, o, "getAndBitwiseXorRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (int)(0x01234567 ^ 0x89ABCDEF), "getAndBitwiseXorRelease int value"); + assertEquals((int)(0x01234567 ^ 0x89ABCDEF), x, "getAndBitwiseXorRelease int value"); } } } diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessLong.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessLong.java index 0e73063395d..90f6dd12c47 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessLong.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessLong.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,22 +25,22 @@ * @test * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations * to hit compilation thresholds - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestMethodHandleAccessLong + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestMethodHandleAccessLong */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { static final long static_final_v = 0x0123456789ABCDEFL; @@ -60,7 +60,7 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { VarHandle vhArray; - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestMethodHandleAccessLong.class, "final_v", long.class); @@ -77,8 +77,6 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { vhArray = MethodHandles.arrayElementVarHandle(long[].class); } - - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -111,7 +109,8 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -120,13 +119,12 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { } } - static void testInstanceField(VarHandleTestMethodHandleAccessLong recv, Handles hs) throws Throwable { // Plain { hs.get(TestAccessMode.SET).invokeExact(recv, 0x0123456789ABCDEFL); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x0123456789ABCDEFL, "set long value"); + assertEquals(0x0123456789ABCDEFL, x, "set long value"); } @@ -134,21 +132,21 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact(recv, 0xCAFEBABECAFEBABEL); long x = (long) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(recv); - assertEquals(x, 0xCAFEBABECAFEBABEL, "setVolatile long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "setVolatile long value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact(recv, 0x0123456789ABCDEFL); long x = (long) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(recv); - assertEquals(x, 0x0123456789ABCDEFL, "setRelease long value"); + assertEquals(0x0123456789ABCDEFL, x, "setRelease long value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact(recv, 0xCAFEBABECAFEBABEL); long x = (long) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(recv); - assertEquals(x, 0xCAFEBABECAFEBABEL, "setOpaque long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "setOpaque long value"); } hs.get(TestAccessMode.SET).invokeExact(recv, 0x0123456789ABCDEFL); @@ -158,56 +156,56 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); assertEquals(r, true, "success compareAndSet long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0xCAFEBABECAFEBABEL, "success compareAndSet long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "success compareAndSet long value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, 0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); assertEquals(r, false, "failing compareAndSet long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0xCAFEBABECAFEBABEL, "failing compareAndSet long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "failing compareAndSet long value"); } { long r = (long) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); assertEquals(r, 0xCAFEBABECAFEBABEL, "success compareAndExchange long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x0123456789ABCDEFL, "success compareAndExchange long value"); + assertEquals(0x0123456789ABCDEFL, x, "success compareAndExchange long value"); } { long r = (long) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, 0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); assertEquals(r, 0x0123456789ABCDEFL, "failing compareAndExchange long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x0123456789ABCDEFL, "failing compareAndExchange long value"); + assertEquals(0x0123456789ABCDEFL, x, "failing compareAndExchange long value"); } { long r = (long) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); assertEquals(r, 0x0123456789ABCDEFL, "success compareAndExchangeAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0xCAFEBABECAFEBABEL, "success compareAndExchangeAcquire long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "success compareAndExchangeAcquire long value"); } { long r = (long) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, 0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); assertEquals(r, 0xCAFEBABECAFEBABEL, "failing compareAndExchangeAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0xCAFEBABECAFEBABEL, "failing compareAndExchangeAcquire long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "failing compareAndExchangeAcquire long value"); } { long r = (long) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); assertEquals(r, 0xCAFEBABECAFEBABEL, "success compareAndExchangeRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x0123456789ABCDEFL, "success compareAndExchangeRelease long value"); + assertEquals(0x0123456789ABCDEFL, x, "success compareAndExchangeRelease long value"); } { long r = (long) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, 0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); assertEquals(r, 0x0123456789ABCDEFL, "failing compareAndExchangeRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x0123456789ABCDEFL, "failing compareAndExchangeRelease long value"); + assertEquals(0x0123456789ABCDEFL, x, "failing compareAndExchangeRelease long value"); } { @@ -219,14 +217,14 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0xCAFEBABECAFEBABEL, "success weakCompareAndSetPlain long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "success weakCompareAndSetPlain long value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, 0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); assertEquals(success, false, "failing weakCompareAndSetPlain long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0xCAFEBABECAFEBABEL, "failing weakCompareAndSetPlain long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "failing weakCompareAndSetPlain long value"); } { @@ -238,14 +236,14 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x0123456789ABCDEFL, "success weakCompareAndSetAcquire long"); + assertEquals(0x0123456789ABCDEFL, x, "success weakCompareAndSetAcquire long"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, 0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); assertEquals(success, false, "failing weakCompareAndSetAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x0123456789ABCDEFL, "failing weakCompareAndSetAcquire long value"); + assertEquals(0x0123456789ABCDEFL, x, "failing weakCompareAndSetAcquire long value"); } { @@ -257,14 +255,14 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0xCAFEBABECAFEBABEL, "success weakCompareAndSetRelease long"); + assertEquals(0xCAFEBABECAFEBABEL, x, "success weakCompareAndSetRelease long"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, 0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); assertEquals(success, false, "failing weakCompareAndSetRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0xCAFEBABECAFEBABEL, "failing weakCompareAndSetRelease long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "failing weakCompareAndSetRelease long value"); } { @@ -276,22 +274,22 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x0123456789ABCDEFL, "success weakCompareAndSet long"); + assertEquals(0x0123456789ABCDEFL, x, "success weakCompareAndSet long"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, 0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); assertEquals(success, false, "failing weakCompareAndSet long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x0123456789ABCDEFL, "failing weakCompareAndSet long value"); + assertEquals(0x0123456789ABCDEFL, x, "failing weakCompareAndSet long value"); } // Compare set and get { long o = (long) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndSet long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndSet long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0xCAFEBABECAFEBABEL, "getAndSet long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "getAndSet long value"); } // get and add, add and get @@ -299,27 +297,27 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(recv, 0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(recv, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndAdd long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndAdd long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), "getAndAdd long value"); + assertEquals((long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), x, "getAndAdd long value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, 0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact(recv, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndAddAcquire long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndAddAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), "getAndAddAcquire long value"); + assertEquals((long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), x, "getAndAddAcquire long value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, 0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact(recv, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndAddRelease long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndAddRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), "getAndAddRelease long value"); + assertEquals((long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), x, "getAndAddRelease long value"); } // get and bitwise or @@ -327,27 +325,27 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(recv, 0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_BITWISE_OR).invokeExact(recv, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseOr long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseOr long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), "getAndBitwiseOr long value"); + assertEquals((long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), x, "getAndBitwiseOr long value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, 0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_BITWISE_OR_ACQUIRE).invokeExact(recv, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseOrAcquire long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseOrAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), "getAndBitwiseOrAcquire long value"); + assertEquals((long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), x, "getAndBitwiseOrAcquire long value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, 0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_BITWISE_OR_RELEASE).invokeExact(recv, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseOrRelease long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseOrRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), "getAndBitwiseOrRelease long value"); + assertEquals((long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), x, "getAndBitwiseOrRelease long value"); } // get and bitwise and @@ -355,27 +353,27 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(recv, 0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_BITWISE_AND).invokeExact(recv, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseAnd long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseAnd long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), "getAndBitwiseAnd long value"); + assertEquals((long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), x, "getAndBitwiseAnd long value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, 0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_BITWISE_AND_ACQUIRE).invokeExact(recv, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseAndAcquire long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseAndAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), "getAndBitwiseAndAcquire long value"); + assertEquals((long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), x, "getAndBitwiseAndAcquire long value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, 0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_BITWISE_AND_RELEASE).invokeExact(recv, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseAndRelease long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseAndRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), "getAndBitwiseAndRelease long value"); + assertEquals((long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), x, "getAndBitwiseAndRelease long value"); } // get and bitwise xor @@ -383,27 +381,27 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(recv, 0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_BITWISE_XOR).invokeExact(recv, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseXor long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseXor long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), "getAndBitwiseXor long value"); + assertEquals((long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), x, "getAndBitwiseXor long value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, 0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_ACQUIRE).invokeExact(recv, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseXorAcquire long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseXorAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), "getAndBitwiseXorAcquire long value"); + assertEquals((long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), x, "getAndBitwiseXorAcquire long value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, 0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_RELEASE).invokeExact(recv, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseXorRelease long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseXorRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), "getAndBitwiseXorRelease long value"); + assertEquals((long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), x, "getAndBitwiseXorRelease long value"); } } @@ -418,7 +416,7 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { { hs.get(TestAccessMode.SET).invokeExact(0x0123456789ABCDEFL); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x0123456789ABCDEFL, "set long value"); + assertEquals(0x0123456789ABCDEFL, x, "set long value"); } @@ -426,21 +424,21 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact(0xCAFEBABECAFEBABEL); long x = (long) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "setVolatile long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "setVolatile long value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact(0x0123456789ABCDEFL); long x = (long) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(); - assertEquals(x, 0x0123456789ABCDEFL, "setRelease long value"); + assertEquals(0x0123456789ABCDEFL, x, "setRelease long value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact(0xCAFEBABECAFEBABEL); long x = (long) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "setOpaque long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "setOpaque long value"); } hs.get(TestAccessMode.SET).invokeExact(0x0123456789ABCDEFL); @@ -450,56 +448,56 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); assertEquals(r, true, "success compareAndSet long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "success compareAndSet long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "success compareAndSet long value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); assertEquals(r, false, "failing compareAndSet long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "failing compareAndSet long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "failing compareAndSet long value"); } { long r = (long) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); assertEquals(r, 0xCAFEBABECAFEBABEL, "success compareAndExchange long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x0123456789ABCDEFL, "success compareAndExchange long value"); + assertEquals(0x0123456789ABCDEFL, x, "success compareAndExchange long value"); } { long r = (long) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); assertEquals(r, 0x0123456789ABCDEFL, "failing compareAndExchange long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x0123456789ABCDEFL, "failing compareAndExchange long value"); + assertEquals(0x0123456789ABCDEFL, x, "failing compareAndExchange long value"); } { long r = (long) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); assertEquals(r, 0x0123456789ABCDEFL, "success compareAndExchangeAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "success compareAndExchangeAcquire long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "success compareAndExchangeAcquire long value"); } { long r = (long) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); assertEquals(r, 0xCAFEBABECAFEBABEL, "failing compareAndExchangeAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "failing compareAndExchangeAcquire long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "failing compareAndExchangeAcquire long value"); } { long r = (long) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); assertEquals(r, 0xCAFEBABECAFEBABEL, "success compareAndExchangeRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x0123456789ABCDEFL, "success compareAndExchangeRelease long value"); + assertEquals(0x0123456789ABCDEFL, x, "success compareAndExchangeRelease long value"); } { long r = (long) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); assertEquals(r, 0x0123456789ABCDEFL, "failing compareAndExchangeRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x0123456789ABCDEFL, "failing compareAndExchangeRelease long value"); + assertEquals(0x0123456789ABCDEFL, x, "failing compareAndExchangeRelease long value"); } { @@ -511,14 +509,14 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "success weakCompareAndSetPlain long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "success weakCompareAndSetPlain long value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); assertEquals(success, false, "failing weakCompareAndSetPlain long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "failing weakCompareAndSetPlain long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "failing weakCompareAndSetPlain long value"); } { @@ -530,7 +528,7 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x0123456789ABCDEFL, "success weakCompareAndSetAcquire long"); + assertEquals(0x0123456789ABCDEFL, x, "success weakCompareAndSetAcquire long"); } { @@ -538,7 +536,7 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { boolean success = (boolean) mh.invokeExact(0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); assertEquals(success, false, "failing weakCompareAndSetAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x0123456789ABCDEFL, "failing weakCompareAndSetAcquire long value"); + assertEquals(0x0123456789ABCDEFL, x, "failing weakCompareAndSetAcquire long value"); } { @@ -550,14 +548,14 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "success weakCompareAndSetRelease long"); + assertEquals(0xCAFEBABECAFEBABEL, x, "success weakCompareAndSetRelease long"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); assertEquals(success, false, "failing weakCompareAndSetRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "failing weakCompareAndSetRelease long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "failing weakCompareAndSetRelease long value"); } { @@ -569,14 +567,14 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x0123456789ABCDEFL, "success weakCompareAndSet long"); + assertEquals(0x0123456789ABCDEFL, x, "success weakCompareAndSet long"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); assertEquals(success, false, "failing weakCompareAndSet long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x0123456789ABCDEFL, "failing weakCompareAndSetRe long value"); + assertEquals(0x0123456789ABCDEFL, x, "failing weakCompareAndSetRe long value"); } // Compare set and get @@ -584,9 +582,9 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_SET).invokeExact(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndSet long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndSet long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "getAndSet long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "getAndSet long value"); } // Compare set and get @@ -594,9 +592,9 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndSetAcquire long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndSetAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "getAndSetAcquire long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "getAndSetAcquire long value"); } // Compare set and get @@ -604,9 +602,9 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndSetRelease long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndSetRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "getAndSetRelease long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "getAndSetRelease long value"); } // get and add, add and get @@ -614,27 +612,27 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndAdd long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndAdd long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), "getAndAdd long value"); + assertEquals((long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), x, "getAndAdd long value"); } { hs.get(TestAccessMode.SET).invokeExact(0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndAddAcquire long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndAddAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), "getAndAddAcquire long value"); + assertEquals((long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), x, "getAndAddAcquire long value"); } { hs.get(TestAccessMode.SET).invokeExact(0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndAddRelease long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndAddRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), "getAndAddRelease long value"); + assertEquals((long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), x, "getAndAddRelease long value"); } // get and bitwise or @@ -642,27 +640,27 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_BITWISE_OR).invokeExact(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseOr long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseOr long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), "getAndBitwiseOr long value"); + assertEquals((long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), x, "getAndBitwiseOr long value"); } { hs.get(TestAccessMode.SET).invokeExact(0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_BITWISE_OR_ACQUIRE).invokeExact(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseOrAcquire long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseOrAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), "getAndBitwiseOrAcquire long value"); + assertEquals((long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), x, "getAndBitwiseOrAcquire long value"); } { hs.get(TestAccessMode.SET).invokeExact(0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_BITWISE_OR_RELEASE).invokeExact(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseOrRelease long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseOrRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), "getAndBitwiseOrRelease long value"); + assertEquals((long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), x, "getAndBitwiseOrRelease long value"); } // get and bitwise and @@ -670,27 +668,27 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_BITWISE_AND).invokeExact(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseAnd long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseAnd long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), "getAndBitwiseAnd long value"); + assertEquals((long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), x, "getAndBitwiseAnd long value"); } { hs.get(TestAccessMode.SET).invokeExact(0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_BITWISE_AND_ACQUIRE).invokeExact(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseAndAcquire long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseAndAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), "getAndBitwiseAndAcquire long value"); + assertEquals((long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), x, "getAndBitwiseAndAcquire long value"); } { hs.get(TestAccessMode.SET).invokeExact(0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_BITWISE_AND_RELEASE).invokeExact(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseAndRelease long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseAndRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), "getAndBitwiseAndRelease long value"); + assertEquals((long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), x, "getAndBitwiseAndRelease long value"); } // get and bitwise xor @@ -698,27 +696,27 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_BITWISE_XOR).invokeExact(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseXor long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseXor long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), "getAndBitwiseXor long value"); + assertEquals((long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), x, "getAndBitwiseXor long value"); } { hs.get(TestAccessMode.SET).invokeExact(0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_ACQUIRE).invokeExact(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseXorAcquire long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseXorAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), "getAndBitwiseXorAcquire long value"); + assertEquals((long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), x, "getAndBitwiseXorAcquire long value"); } { hs.get(TestAccessMode.SET).invokeExact(0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_RELEASE).invokeExact(0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseXorRelease long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseXorRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), "getAndBitwiseXorRelease long value"); + assertEquals((long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), x, "getAndBitwiseXorRelease long value"); } } @@ -736,7 +734,7 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x0123456789ABCDEFL); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x0123456789ABCDEFL, "get long value"); + assertEquals(0x0123456789ABCDEFL, x, "get long value"); } @@ -744,21 +742,21 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact(array, i, 0xCAFEBABECAFEBABEL); long x = (long) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "setVolatile long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "setVolatile long value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact(array, i, 0x0123456789ABCDEFL); long x = (long) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(array, i); - assertEquals(x, 0x0123456789ABCDEFL, "setRelease long value"); + assertEquals(0x0123456789ABCDEFL, x, "setRelease long value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact(array, i, 0xCAFEBABECAFEBABEL); long x = (long) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "setOpaque long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "setOpaque long value"); } hs.get(TestAccessMode.SET).invokeExact(array, i, 0x0123456789ABCDEFL); @@ -768,56 +766,56 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); assertEquals(r, true, "success compareAndSet long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "success compareAndSet long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "success compareAndSet long value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, 0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); assertEquals(r, false, "failing compareAndSet long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "failing compareAndSet long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "failing compareAndSet long value"); } { long r = (long) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); assertEquals(r, 0xCAFEBABECAFEBABEL, "success compareAndExchange long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x0123456789ABCDEFL, "success compareAndExchange long value"); + assertEquals(0x0123456789ABCDEFL, x, "success compareAndExchange long value"); } { long r = (long) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, 0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); assertEquals(r, 0x0123456789ABCDEFL, "failing compareAndExchange long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x0123456789ABCDEFL, "failing compareAndExchange long value"); + assertEquals(0x0123456789ABCDEFL, x, "failing compareAndExchange long value"); } { long r = (long) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); assertEquals(r, 0x0123456789ABCDEFL, "success compareAndExchangeAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "success compareAndExchangeAcquire long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "success compareAndExchangeAcquire long value"); } { long r = (long) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, 0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); assertEquals(r, 0xCAFEBABECAFEBABEL, "failing compareAndExchangeAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "failing compareAndExchangeAcquire long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "failing compareAndExchangeAcquire long value"); } { long r = (long) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); assertEquals(r, 0xCAFEBABECAFEBABEL, "success compareAndExchangeRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x0123456789ABCDEFL, "success compareAndExchangeRelease long value"); + assertEquals(0x0123456789ABCDEFL, x, "success compareAndExchangeRelease long value"); } { long r = (long) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, 0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); assertEquals(r, 0x0123456789ABCDEFL, "failing compareAndExchangeRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x0123456789ABCDEFL, "failing compareAndExchangeRelease long value"); + assertEquals(0x0123456789ABCDEFL, x, "failing compareAndExchangeRelease long value"); } { @@ -829,14 +827,14 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "success weakCompareAndSetPlain long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "success weakCompareAndSetPlain long value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, 0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); assertEquals(success, false, "failing weakCompareAndSetPlain long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "failing weakCompareAndSetPlain long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "failing weakCompareAndSetPlain long value"); } { @@ -848,14 +846,14 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x0123456789ABCDEFL, "success weakCompareAndSetAcquire long"); + assertEquals(0x0123456789ABCDEFL, x, "success weakCompareAndSetAcquire long"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); assertEquals(success, false, "failing weakCompareAndSetAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x0123456789ABCDEFL, "failing weakCompareAndSetAcquire long value"); + assertEquals(0x0123456789ABCDEFL, x, "failing weakCompareAndSetAcquire long value"); } { @@ -867,14 +865,14 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "success weakCompareAndSetRelease long"); + assertEquals(0xCAFEBABECAFEBABEL, x, "success weakCompareAndSetRelease long"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); assertEquals(success, false, "failing weakCompareAndSetAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "failing weakCompareAndSetAcquire long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "failing weakCompareAndSetAcquire long value"); } { @@ -886,14 +884,14 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x0123456789ABCDEFL, "success weakCompareAndSet long"); + assertEquals(0x0123456789ABCDEFL, x, "success weakCompareAndSet long"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, 0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); assertEquals(success, false, "failing weakCompareAndSet long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x0123456789ABCDEFL, "failing weakCompareAndSet long value"); + assertEquals(0x0123456789ABCDEFL, x, "failing weakCompareAndSet long value"); } // Compare set and get @@ -901,27 +899,27 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndSet long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndSet long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "getAndSet long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "getAndSet long value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndSetAcquire long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndSetAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "getAndSetAcquire long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "getAndSetAcquire long value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndSetRelease long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndSetRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "getAndSetRelease long value"); + assertEquals(0xCAFEBABECAFEBABEL, x, "getAndSetRelease long value"); } // get and add, add and get @@ -929,27 +927,27 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndAdd long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndAdd long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), "getAndAdd long value"); + assertEquals((long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), x, "getAndAdd long value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndAddAcquire long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndAddAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), "getAndAddAcquire long value"); + assertEquals((long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), x, "getAndAddAcquire long value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndAddRelease long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndAddRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), "getAndAddRelease long value"); + assertEquals((long)(0x0123456789ABCDEFL + 0xCAFEBABECAFEBABEL), x, "getAndAddRelease long value"); } // get and bitwise or @@ -957,27 +955,27 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_BITWISE_OR).invokeExact(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseOr long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseOr long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), "getAndBitwiseOr long value"); + assertEquals((long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), x, "getAndBitwiseOr long value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_BITWISE_OR_ACQUIRE).invokeExact(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseOrAcquire long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseOrAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), "getAndBitwiseOrAcquire long value"); + assertEquals((long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), x, "getAndBitwiseOrAcquire long value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_BITWISE_OR_RELEASE).invokeExact(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseOrRelease long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseOrRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), "getAndBitwiseOrRelease long value"); + assertEquals((long)(0x0123456789ABCDEFL | 0xCAFEBABECAFEBABEL), x, "getAndBitwiseOrRelease long value"); } // get and bitwise and @@ -985,27 +983,27 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_BITWISE_AND).invokeExact(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseAnd long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseAnd long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), "getAndBitwiseAnd long value"); + assertEquals((long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), x, "getAndBitwiseAnd long value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_BITWISE_AND_ACQUIRE).invokeExact(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseAndAcquire long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseAndAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), "getAndBitwiseAndAcquire long value"); + assertEquals((long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), x, "getAndBitwiseAndAcquire long value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_BITWISE_AND_RELEASE).invokeExact(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseAndRelease long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseAndRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), "getAndBitwiseAndRelease long value"); + assertEquals((long)(0x0123456789ABCDEFL & 0xCAFEBABECAFEBABEL), x, "getAndBitwiseAndRelease long value"); } // get and bitwise xor @@ -1013,27 +1011,27 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_BITWISE_XOR).invokeExact(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseXor long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseXor long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), "getAndBitwiseXor long value"); + assertEquals((long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), x, "getAndBitwiseXor long value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_ACQUIRE).invokeExact(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseXorAcquire long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseXorAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), "getAndBitwiseXorAcquire long value"); + assertEquals((long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), x, "getAndBitwiseXorAcquire long value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, 0x0123456789ABCDEFL); long o = (long) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_RELEASE).invokeExact(array, i, 0xCAFEBABECAFEBABEL); - assertEquals(o, 0x0123456789ABCDEFL, "getAndBitwiseXorRelease long"); + assertEquals(0x0123456789ABCDEFL, o, "getAndBitwiseXorRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), "getAndBitwiseXorRelease long value"); + assertEquals((long)(0x0123456789ABCDEFL ^ 0xCAFEBABECAFEBABEL), x, "getAndBitwiseXorRelease long value"); } } } diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessShort.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessShort.java index 8fb23d7dc55..d8f548fe2d6 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessShort.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessShort.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,22 +25,22 @@ * @test * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations * to hit compilation thresholds - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestMethodHandleAccessShort + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestMethodHandleAccessShort */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { static final short static_final_v = (short)0x0123; @@ -60,7 +60,7 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { VarHandle vhArray; - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestMethodHandleAccessShort.class, "final_v", short.class); @@ -77,8 +77,6 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { vhArray = MethodHandles.arrayElementVarHandle(short[].class); } - - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -111,7 +109,8 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -120,13 +119,12 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { } } - static void testInstanceField(VarHandleTestMethodHandleAccessShort recv, Handles hs) throws Throwable { // Plain { hs.get(TestAccessMode.SET).invokeExact(recv, (short)0x0123); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)0x0123, "set short value"); + assertEquals((short)0x0123, x, "set short value"); } @@ -134,21 +132,21 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact(recv, (short)0x4567); short x = (short) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(recv); - assertEquals(x, (short)0x4567, "setVolatile short value"); + assertEquals((short)0x4567, x, "setVolatile short value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact(recv, (short)0x0123); short x = (short) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(recv); - assertEquals(x, (short)0x0123, "setRelease short value"); + assertEquals((short)0x0123, x, "setRelease short value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact(recv, (short)0x4567); short x = (short) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(recv); - assertEquals(x, (short)0x4567, "setOpaque short value"); + assertEquals((short)0x4567, x, "setOpaque short value"); } hs.get(TestAccessMode.SET).invokeExact(recv, (short)0x0123); @@ -158,56 +156,56 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, (short)0x0123, (short)0x4567); assertEquals(r, true, "success compareAndSet short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)0x4567, "success compareAndSet short value"); + assertEquals((short)0x4567, x, "success compareAndSet short value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, (short)0x0123, (short)0x89AB); assertEquals(r, false, "failing compareAndSet short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)0x4567, "failing compareAndSet short value"); + assertEquals((short)0x4567, x, "failing compareAndSet short value"); } { short r = (short) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, (short)0x4567, (short)0x0123); assertEquals(r, (short)0x4567, "success compareAndExchange short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)0x0123, "success compareAndExchange short value"); + assertEquals((short)0x0123, x, "success compareAndExchange short value"); } { short r = (short) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, (short)0x4567, (short)0x89AB); assertEquals(r, (short)0x0123, "failing compareAndExchange short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)0x0123, "failing compareAndExchange short value"); + assertEquals((short)0x0123, x, "failing compareAndExchange short value"); } { short r = (short) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, (short)0x0123, (short)0x4567); assertEquals(r, (short)0x0123, "success compareAndExchangeAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)0x4567, "success compareAndExchangeAcquire short value"); + assertEquals((short)0x4567, x, "success compareAndExchangeAcquire short value"); } { short r = (short) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, (short)0x0123, (short)0x89AB); assertEquals(r, (short)0x4567, "failing compareAndExchangeAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)0x4567, "failing compareAndExchangeAcquire short value"); + assertEquals((short)0x4567, x, "failing compareAndExchangeAcquire short value"); } { short r = (short) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, (short)0x4567, (short)0x0123); assertEquals(r, (short)0x4567, "success compareAndExchangeRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)0x0123, "success compareAndExchangeRelease short value"); + assertEquals((short)0x0123, x, "success compareAndExchangeRelease short value"); } { short r = (short) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, (short)0x4567, (short)0x89AB); assertEquals(r, (short)0x0123, "failing compareAndExchangeRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)0x0123, "failing compareAndExchangeRelease short value"); + assertEquals((short)0x0123, x, "failing compareAndExchangeRelease short value"); } { @@ -219,14 +217,14 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)0x4567, "success weakCompareAndSetPlain short value"); + assertEquals((short)0x4567, x, "success weakCompareAndSetPlain short value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, (short)0x0123, (short)0x89AB); assertEquals(success, false, "failing weakCompareAndSetPlain short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)0x4567, "failing weakCompareAndSetPlain short value"); + assertEquals((short)0x4567, x, "failing weakCompareAndSetPlain short value"); } { @@ -238,14 +236,14 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)0x0123, "success weakCompareAndSetAcquire short"); + assertEquals((short)0x0123, x, "success weakCompareAndSetAcquire short"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, (short)0x4567, (short)0x89AB); assertEquals(success, false, "failing weakCompareAndSetAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)0x0123, "failing weakCompareAndSetAcquire short value"); + assertEquals((short)0x0123, x, "failing weakCompareAndSetAcquire short value"); } { @@ -257,14 +255,14 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)0x4567, "success weakCompareAndSetRelease short"); + assertEquals((short)0x4567, x, "success weakCompareAndSetRelease short"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, (short)0x0123, (short)0x89AB); assertEquals(success, false, "failing weakCompareAndSetRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)0x4567, "failing weakCompareAndSetRelease short value"); + assertEquals((short)0x4567, x, "failing weakCompareAndSetRelease short value"); } { @@ -276,22 +274,22 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)0x0123, "success weakCompareAndSet short"); + assertEquals((short)0x0123, x, "success weakCompareAndSet short"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, (short)0x4567, (short)0x89AB); assertEquals(success, false, "failing weakCompareAndSet short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)0x0123, "failing weakCompareAndSet short value"); + assertEquals((short)0x0123, x, "failing weakCompareAndSet short value"); } // Compare set and get { short o = (short) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndSet short"); + assertEquals((short)0x0123, o, "getAndSet short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)0x4567, "getAndSet short value"); + assertEquals((short)0x4567, x, "getAndSet short value"); } // get and add, add and get @@ -299,27 +297,27 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(recv, (short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(recv, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndAdd short"); + assertEquals((short)0x0123, o, "getAndAdd short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)((short)0x0123 + (short)0x4567), "getAndAdd short value"); + assertEquals((short)((short)0x0123 + (short)0x4567), x, "getAndAdd short value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, (short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact(recv, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndAddAcquire short"); + assertEquals((short)0x0123, o, "getAndAddAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)((short)0x0123 + (short)0x4567), "getAndAddAcquire short value"); + assertEquals((short)((short)0x0123 + (short)0x4567), x, "getAndAddAcquire short value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, (short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact(recv, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndAddRelease short"); + assertEquals((short)0x0123, o, "getAndAddRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)((short)0x0123 + (short)0x4567), "getAndAddRelease short value"); + assertEquals((short)((short)0x0123 + (short)0x4567), x, "getAndAddRelease short value"); } // get and bitwise or @@ -327,27 +325,27 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(recv, (short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_BITWISE_OR).invokeExact(recv, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseOr short"); + assertEquals((short)0x0123, o, "getAndBitwiseOr short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)((short)0x0123 | (short)0x4567), "getAndBitwiseOr short value"); + assertEquals((short)((short)0x0123 | (short)0x4567), x, "getAndBitwiseOr short value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, (short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_BITWISE_OR_ACQUIRE).invokeExact(recv, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseOrAcquire short"); + assertEquals((short)0x0123, o, "getAndBitwiseOrAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)((short)0x0123 | (short)0x4567), "getAndBitwiseOrAcquire short value"); + assertEquals((short)((short)0x0123 | (short)0x4567), x, "getAndBitwiseOrAcquire short value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, (short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_BITWISE_OR_RELEASE).invokeExact(recv, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseOrRelease short"); + assertEquals((short)0x0123, o, "getAndBitwiseOrRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)((short)0x0123 | (short)0x4567), "getAndBitwiseOrRelease short value"); + assertEquals((short)((short)0x0123 | (short)0x4567), x, "getAndBitwiseOrRelease short value"); } // get and bitwise and @@ -355,27 +353,27 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(recv, (short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_BITWISE_AND).invokeExact(recv, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseAnd short"); + assertEquals((short)0x0123, o, "getAndBitwiseAnd short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)((short)0x0123 & (short)0x4567), "getAndBitwiseAnd short value"); + assertEquals((short)((short)0x0123 & (short)0x4567), x, "getAndBitwiseAnd short value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, (short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_BITWISE_AND_ACQUIRE).invokeExact(recv, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseAndAcquire short"); + assertEquals((short)0x0123, o, "getAndBitwiseAndAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)((short)0x0123 & (short)0x4567), "getAndBitwiseAndAcquire short value"); + assertEquals((short)((short)0x0123 & (short)0x4567), x, "getAndBitwiseAndAcquire short value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, (short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_BITWISE_AND_RELEASE).invokeExact(recv, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseAndRelease short"); + assertEquals((short)0x0123, o, "getAndBitwiseAndRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)((short)0x0123 & (short)0x4567), "getAndBitwiseAndRelease short value"); + assertEquals((short)((short)0x0123 & (short)0x4567), x, "getAndBitwiseAndRelease short value"); } // get and bitwise xor @@ -383,27 +381,27 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(recv, (short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_BITWISE_XOR).invokeExact(recv, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseXor short"); + assertEquals((short)0x0123, o, "getAndBitwiseXor short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)((short)0x0123 ^ (short)0x4567), "getAndBitwiseXor short value"); + assertEquals((short)((short)0x0123 ^ (short)0x4567), x, "getAndBitwiseXor short value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, (short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_ACQUIRE).invokeExact(recv, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseXorAcquire short"); + assertEquals((short)0x0123, o, "getAndBitwiseXorAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)((short)0x0123 ^ (short)0x4567), "getAndBitwiseXorAcquire short value"); + assertEquals((short)((short)0x0123 ^ (short)0x4567), x, "getAndBitwiseXorAcquire short value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, (short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_RELEASE).invokeExact(recv, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseXorRelease short"); + assertEquals((short)0x0123, o, "getAndBitwiseXorRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)((short)0x0123 ^ (short)0x4567), "getAndBitwiseXorRelease short value"); + assertEquals((short)((short)0x0123 ^ (short)0x4567), x, "getAndBitwiseXorRelease short value"); } } @@ -418,7 +416,7 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { { hs.get(TestAccessMode.SET).invokeExact((short)0x0123); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)0x0123, "set short value"); + assertEquals((short)0x0123, x, "set short value"); } @@ -426,21 +424,21 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact((short)0x4567); short x = (short) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(); - assertEquals(x, (short)0x4567, "setVolatile short value"); + assertEquals((short)0x4567, x, "setVolatile short value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact((short)0x0123); short x = (short) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(); - assertEquals(x, (short)0x0123, "setRelease short value"); + assertEquals((short)0x0123, x, "setRelease short value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact((short)0x4567); short x = (short) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(); - assertEquals(x, (short)0x4567, "setOpaque short value"); + assertEquals((short)0x4567, x, "setOpaque short value"); } hs.get(TestAccessMode.SET).invokeExact((short)0x0123); @@ -450,56 +448,56 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact((short)0x0123, (short)0x4567); assertEquals(r, true, "success compareAndSet short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)0x4567, "success compareAndSet short value"); + assertEquals((short)0x4567, x, "success compareAndSet short value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact((short)0x0123, (short)0x89AB); assertEquals(r, false, "failing compareAndSet short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)0x4567, "failing compareAndSet short value"); + assertEquals((short)0x4567, x, "failing compareAndSet short value"); } { short r = (short) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact((short)0x4567, (short)0x0123); assertEquals(r, (short)0x4567, "success compareAndExchange short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)0x0123, "success compareAndExchange short value"); + assertEquals((short)0x0123, x, "success compareAndExchange short value"); } { short r = (short) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact((short)0x4567, (short)0x89AB); assertEquals(r, (short)0x0123, "failing compareAndExchange short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)0x0123, "failing compareAndExchange short value"); + assertEquals((short)0x0123, x, "failing compareAndExchange short value"); } { short r = (short) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact((short)0x0123, (short)0x4567); assertEquals(r, (short)0x0123, "success compareAndExchangeAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)0x4567, "success compareAndExchangeAcquire short value"); + assertEquals((short)0x4567, x, "success compareAndExchangeAcquire short value"); } { short r = (short) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact((short)0x0123, (short)0x89AB); assertEquals(r, (short)0x4567, "failing compareAndExchangeAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)0x4567, "failing compareAndExchangeAcquire short value"); + assertEquals((short)0x4567, x, "failing compareAndExchangeAcquire short value"); } { short r = (short) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact((short)0x4567, (short)0x0123); assertEquals(r, (short)0x4567, "success compareAndExchangeRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)0x0123, "success compareAndExchangeRelease short value"); + assertEquals((short)0x0123, x, "success compareAndExchangeRelease short value"); } { short r = (short) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact((short)0x4567, (short)0x89AB); assertEquals(r, (short)0x0123, "failing compareAndExchangeRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)0x0123, "failing compareAndExchangeRelease short value"); + assertEquals((short)0x0123, x, "failing compareAndExchangeRelease short value"); } { @@ -511,14 +509,14 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)0x4567, "success weakCompareAndSetPlain short value"); + assertEquals((short)0x4567, x, "success weakCompareAndSetPlain short value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact((short)0x0123, (short)0x89AB); assertEquals(success, false, "failing weakCompareAndSetPlain short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)0x4567, "failing weakCompareAndSetPlain short value"); + assertEquals((short)0x4567, x, "failing weakCompareAndSetPlain short value"); } { @@ -530,7 +528,7 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)0x0123, "success weakCompareAndSetAcquire short"); + assertEquals((short)0x0123, x, "success weakCompareAndSetAcquire short"); } { @@ -538,7 +536,7 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { boolean success = (boolean) mh.invokeExact((short)0x4567, (short)0x89AB); assertEquals(success, false, "failing weakCompareAndSetAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)0x0123, "failing weakCompareAndSetAcquire short value"); + assertEquals((short)0x0123, x, "failing weakCompareAndSetAcquire short value"); } { @@ -550,14 +548,14 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)0x4567, "success weakCompareAndSetRelease short"); + assertEquals((short)0x4567, x, "success weakCompareAndSetRelease short"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact((short)0x0123, (short)0x89AB); assertEquals(success, false, "failing weakCompareAndSetRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)0x4567, "failing weakCompareAndSetRelease short value"); + assertEquals((short)0x4567, x, "failing weakCompareAndSetRelease short value"); } { @@ -569,14 +567,14 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)0x0123, "success weakCompareAndSet short"); + assertEquals((short)0x0123, x, "success weakCompareAndSet short"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact((short)0x4567, (short)0x89AB); assertEquals(success, false, "failing weakCompareAndSet short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)0x0123, "failing weakCompareAndSetRe short value"); + assertEquals((short)0x0123, x, "failing weakCompareAndSetRe short value"); } // Compare set and get @@ -584,9 +582,9 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact((short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_SET).invokeExact((short)0x4567); - assertEquals(o, (short)0x0123, "getAndSet short"); + assertEquals((short)0x0123, o, "getAndSet short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)0x4567, "getAndSet short value"); + assertEquals((short)0x4567, x, "getAndSet short value"); } // Compare set and get @@ -594,9 +592,9 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact((short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact((short)0x4567); - assertEquals(o, (short)0x0123, "getAndSetAcquire short"); + assertEquals((short)0x0123, o, "getAndSetAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)0x4567, "getAndSetAcquire short value"); + assertEquals((short)0x4567, x, "getAndSetAcquire short value"); } // Compare set and get @@ -604,9 +602,9 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact((short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact((short)0x4567); - assertEquals(o, (short)0x0123, "getAndSetRelease short"); + assertEquals((short)0x0123, o, "getAndSetRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)0x4567, "getAndSetRelease short value"); + assertEquals((short)0x4567, x, "getAndSetRelease short value"); } // get and add, add and get @@ -614,27 +612,27 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact((short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_ADD).invokeExact((short)0x4567); - assertEquals(o, (short)0x0123, "getAndAdd short"); + assertEquals((short)0x0123, o, "getAndAdd short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)((short)0x0123 + (short)0x4567), "getAndAdd short value"); + assertEquals((short)((short)0x0123 + (short)0x4567), x, "getAndAdd short value"); } { hs.get(TestAccessMode.SET).invokeExact((short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact((short)0x4567); - assertEquals(o, (short)0x0123, "getAndAddAcquire short"); + assertEquals((short)0x0123, o, "getAndAddAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)((short)0x0123 + (short)0x4567), "getAndAddAcquire short value"); + assertEquals((short)((short)0x0123 + (short)0x4567), x, "getAndAddAcquire short value"); } { hs.get(TestAccessMode.SET).invokeExact((short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact((short)0x4567); - assertEquals(o, (short)0x0123, "getAndAddRelease short"); + assertEquals((short)0x0123, o, "getAndAddRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)((short)0x0123 + (short)0x4567), "getAndAddRelease short value"); + assertEquals((short)((short)0x0123 + (short)0x4567), x, "getAndAddRelease short value"); } // get and bitwise or @@ -642,27 +640,27 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact((short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_BITWISE_OR).invokeExact((short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseOr short"); + assertEquals((short)0x0123, o, "getAndBitwiseOr short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)((short)0x0123 | (short)0x4567), "getAndBitwiseOr short value"); + assertEquals((short)((short)0x0123 | (short)0x4567), x, "getAndBitwiseOr short value"); } { hs.get(TestAccessMode.SET).invokeExact((short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_BITWISE_OR_ACQUIRE).invokeExact((short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseOrAcquire short"); + assertEquals((short)0x0123, o, "getAndBitwiseOrAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)((short)0x0123 | (short)0x4567), "getAndBitwiseOrAcquire short value"); + assertEquals((short)((short)0x0123 | (short)0x4567), x, "getAndBitwiseOrAcquire short value"); } { hs.get(TestAccessMode.SET).invokeExact((short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_BITWISE_OR_RELEASE).invokeExact((short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseOrRelease short"); + assertEquals((short)0x0123, o, "getAndBitwiseOrRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)((short)0x0123 | (short)0x4567), "getAndBitwiseOrRelease short value"); + assertEquals((short)((short)0x0123 | (short)0x4567), x, "getAndBitwiseOrRelease short value"); } // get and bitwise and @@ -670,27 +668,27 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact((short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_BITWISE_AND).invokeExact((short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseAnd short"); + assertEquals((short)0x0123, o, "getAndBitwiseAnd short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)((short)0x0123 & (short)0x4567), "getAndBitwiseAnd short value"); + assertEquals((short)((short)0x0123 & (short)0x4567), x, "getAndBitwiseAnd short value"); } { hs.get(TestAccessMode.SET).invokeExact((short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_BITWISE_AND_ACQUIRE).invokeExact((short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseAndAcquire short"); + assertEquals((short)0x0123, o, "getAndBitwiseAndAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)((short)0x0123 & (short)0x4567), "getAndBitwiseAndAcquire short value"); + assertEquals((short)((short)0x0123 & (short)0x4567), x, "getAndBitwiseAndAcquire short value"); } { hs.get(TestAccessMode.SET).invokeExact((short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_BITWISE_AND_RELEASE).invokeExact((short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseAndRelease short"); + assertEquals((short)0x0123, o, "getAndBitwiseAndRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)((short)0x0123 & (short)0x4567), "getAndBitwiseAndRelease short value"); + assertEquals((short)((short)0x0123 & (short)0x4567), x, "getAndBitwiseAndRelease short value"); } // get and bitwise xor @@ -698,27 +696,27 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact((short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_BITWISE_XOR).invokeExact((short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseXor short"); + assertEquals((short)0x0123, o, "getAndBitwiseXor short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)((short)0x0123 ^ (short)0x4567), "getAndBitwiseXor short value"); + assertEquals((short)((short)0x0123 ^ (short)0x4567), x, "getAndBitwiseXor short value"); } { hs.get(TestAccessMode.SET).invokeExact((short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_ACQUIRE).invokeExact((short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseXorAcquire short"); + assertEquals((short)0x0123, o, "getAndBitwiseXorAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)((short)0x0123 ^ (short)0x4567), "getAndBitwiseXorAcquire short value"); + assertEquals((short)((short)0x0123 ^ (short)0x4567), x, "getAndBitwiseXorAcquire short value"); } { hs.get(TestAccessMode.SET).invokeExact((short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_RELEASE).invokeExact((short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseXorRelease short"); + assertEquals((short)0x0123, o, "getAndBitwiseXorRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)((short)0x0123 ^ (short)0x4567), "getAndBitwiseXorRelease short value"); + assertEquals((short)((short)0x0123 ^ (short)0x4567), x, "getAndBitwiseXorRelease short value"); } } @@ -736,7 +734,7 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { { hs.get(TestAccessMode.SET).invokeExact(array, i, (short)0x0123); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)0x0123, "get short value"); + assertEquals((short)0x0123, x, "get short value"); } @@ -744,21 +742,21 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact(array, i, (short)0x4567); short x = (short) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(array, i); - assertEquals(x, (short)0x4567, "setVolatile short value"); + assertEquals((short)0x4567, x, "setVolatile short value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact(array, i, (short)0x0123); short x = (short) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(array, i); - assertEquals(x, (short)0x0123, "setRelease short value"); + assertEquals((short)0x0123, x, "setRelease short value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact(array, i, (short)0x4567); short x = (short) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(array, i); - assertEquals(x, (short)0x4567, "setOpaque short value"); + assertEquals((short)0x4567, x, "setOpaque short value"); } hs.get(TestAccessMode.SET).invokeExact(array, i, (short)0x0123); @@ -768,56 +766,56 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, (short)0x0123, (short)0x4567); assertEquals(r, true, "success compareAndSet short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)0x4567, "success compareAndSet short value"); + assertEquals((short)0x4567, x, "success compareAndSet short value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, (short)0x0123, (short)0x89AB); assertEquals(r, false, "failing compareAndSet short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)0x4567, "failing compareAndSet short value"); + assertEquals((short)0x4567, x, "failing compareAndSet short value"); } { short r = (short) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, (short)0x4567, (short)0x0123); assertEquals(r, (short)0x4567, "success compareAndExchange short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)0x0123, "success compareAndExchange short value"); + assertEquals((short)0x0123, x, "success compareAndExchange short value"); } { short r = (short) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, (short)0x4567, (short)0x89AB); assertEquals(r, (short)0x0123, "failing compareAndExchange short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)0x0123, "failing compareAndExchange short value"); + assertEquals((short)0x0123, x, "failing compareAndExchange short value"); } { short r = (short) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, (short)0x0123, (short)0x4567); assertEquals(r, (short)0x0123, "success compareAndExchangeAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)0x4567, "success compareAndExchangeAcquire short value"); + assertEquals((short)0x4567, x, "success compareAndExchangeAcquire short value"); } { short r = (short) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, (short)0x0123, (short)0x89AB); assertEquals(r, (short)0x4567, "failing compareAndExchangeAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)0x4567, "failing compareAndExchangeAcquire short value"); + assertEquals((short)0x4567, x, "failing compareAndExchangeAcquire short value"); } { short r = (short) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, (short)0x4567, (short)0x0123); assertEquals(r, (short)0x4567, "success compareAndExchangeRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)0x0123, "success compareAndExchangeRelease short value"); + assertEquals((short)0x0123, x, "success compareAndExchangeRelease short value"); } { short r = (short) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, (short)0x4567, (short)0x89AB); assertEquals(r, (short)0x0123, "failing compareAndExchangeRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)0x0123, "failing compareAndExchangeRelease short value"); + assertEquals((short)0x0123, x, "failing compareAndExchangeRelease short value"); } { @@ -829,14 +827,14 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)0x4567, "success weakCompareAndSetPlain short value"); + assertEquals((short)0x4567, x, "success weakCompareAndSetPlain short value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, (short)0x0123, (short)0x89AB); assertEquals(success, false, "failing weakCompareAndSetPlain short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)0x4567, "failing weakCompareAndSetPlain short value"); + assertEquals((short)0x4567, x, "failing weakCompareAndSetPlain short value"); } { @@ -848,14 +846,14 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)0x0123, "success weakCompareAndSetAcquire short"); + assertEquals((short)0x0123, x, "success weakCompareAndSetAcquire short"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, (short)0x4567, (short)0x89AB); assertEquals(success, false, "failing weakCompareAndSetAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)0x0123, "failing weakCompareAndSetAcquire short value"); + assertEquals((short)0x0123, x, "failing weakCompareAndSetAcquire short value"); } { @@ -867,14 +865,14 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)0x4567, "success weakCompareAndSetRelease short"); + assertEquals((short)0x4567, x, "success weakCompareAndSetRelease short"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, (short)0x0123, (short)0x89AB); assertEquals(success, false, "failing weakCompareAndSetAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)0x4567, "failing weakCompareAndSetAcquire short value"); + assertEquals((short)0x4567, x, "failing weakCompareAndSetAcquire short value"); } { @@ -886,14 +884,14 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)0x0123, "success weakCompareAndSet short"); + assertEquals((short)0x0123, x, "success weakCompareAndSet short"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, (short)0x4567, (short)0x89AB); assertEquals(success, false, "failing weakCompareAndSet short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)0x0123, "failing weakCompareAndSet short value"); + assertEquals((short)0x0123, x, "failing weakCompareAndSet short value"); } // Compare set and get @@ -901,27 +899,27 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, (short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndSet short"); + assertEquals((short)0x0123, o, "getAndSet short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)0x4567, "getAndSet short value"); + assertEquals((short)0x4567, x, "getAndSet short value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, (short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndSetAcquire short"); + assertEquals((short)0x0123, o, "getAndSetAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)0x4567, "getAndSetAcquire short value"); + assertEquals((short)0x4567, x, "getAndSetAcquire short value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, (short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndSetRelease short"); + assertEquals((short)0x0123, o, "getAndSetRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)0x4567, "getAndSetRelease short value"); + assertEquals((short)0x4567, x, "getAndSetRelease short value"); } // get and add, add and get @@ -929,27 +927,27 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, (short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndAdd short"); + assertEquals((short)0x0123, o, "getAndAdd short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)((short)0x0123 + (short)0x4567), "getAndAdd short value"); + assertEquals((short)((short)0x0123 + (short)0x4567), x, "getAndAdd short value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, (short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndAddAcquire short"); + assertEquals((short)0x0123, o, "getAndAddAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)((short)0x0123 + (short)0x4567), "getAndAddAcquire short value"); + assertEquals((short)((short)0x0123 + (short)0x4567), x, "getAndAddAcquire short value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, (short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndAddRelease short"); + assertEquals((short)0x0123, o, "getAndAddRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)((short)0x0123 + (short)0x4567), "getAndAddRelease short value"); + assertEquals((short)((short)0x0123 + (short)0x4567), x, "getAndAddRelease short value"); } // get and bitwise or @@ -957,27 +955,27 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, (short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_BITWISE_OR).invokeExact(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseOr short"); + assertEquals((short)0x0123, o, "getAndBitwiseOr short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)((short)0x0123 | (short)0x4567), "getAndBitwiseOr short value"); + assertEquals((short)((short)0x0123 | (short)0x4567), x, "getAndBitwiseOr short value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, (short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_BITWISE_OR_ACQUIRE).invokeExact(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseOrAcquire short"); + assertEquals((short)0x0123, o, "getAndBitwiseOrAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)((short)0x0123 | (short)0x4567), "getAndBitwiseOrAcquire short value"); + assertEquals((short)((short)0x0123 | (short)0x4567), x, "getAndBitwiseOrAcquire short value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, (short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_BITWISE_OR_RELEASE).invokeExact(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseOrRelease short"); + assertEquals((short)0x0123, o, "getAndBitwiseOrRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)((short)0x0123 | (short)0x4567), "getAndBitwiseOrRelease short value"); + assertEquals((short)((short)0x0123 | (short)0x4567), x, "getAndBitwiseOrRelease short value"); } // get and bitwise and @@ -985,27 +983,27 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, (short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_BITWISE_AND).invokeExact(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseAnd short"); + assertEquals((short)0x0123, o, "getAndBitwiseAnd short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)((short)0x0123 & (short)0x4567), "getAndBitwiseAnd short value"); + assertEquals((short)((short)0x0123 & (short)0x4567), x, "getAndBitwiseAnd short value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, (short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_BITWISE_AND_ACQUIRE).invokeExact(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseAndAcquire short"); + assertEquals((short)0x0123, o, "getAndBitwiseAndAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)((short)0x0123 & (short)0x4567), "getAndBitwiseAndAcquire short value"); + assertEquals((short)((short)0x0123 & (short)0x4567), x, "getAndBitwiseAndAcquire short value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, (short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_BITWISE_AND_RELEASE).invokeExact(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseAndRelease short"); + assertEquals((short)0x0123, o, "getAndBitwiseAndRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)((short)0x0123 & (short)0x4567), "getAndBitwiseAndRelease short value"); + assertEquals((short)((short)0x0123 & (short)0x4567), x, "getAndBitwiseAndRelease short value"); } // get and bitwise xor @@ -1013,27 +1011,27 @@ public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, (short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_BITWISE_XOR).invokeExact(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseXor short"); + assertEquals((short)0x0123, o, "getAndBitwiseXor short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)((short)0x0123 ^ (short)0x4567), "getAndBitwiseXor short value"); + assertEquals((short)((short)0x0123 ^ (short)0x4567), x, "getAndBitwiseXor short value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, (short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_ACQUIRE).invokeExact(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseXorAcquire short"); + assertEquals((short)0x0123, o, "getAndBitwiseXorAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)((short)0x0123 ^ (short)0x4567), "getAndBitwiseXorAcquire short value"); + assertEquals((short)((short)0x0123 ^ (short)0x4567), x, "getAndBitwiseXorAcquire short value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, (short)0x0123); short o = (short) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_RELEASE).invokeExact(array, i, (short)0x4567); - assertEquals(o, (short)0x0123, "getAndBitwiseXorRelease short"); + assertEquals((short)0x0123, o, "getAndBitwiseXorRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)((short)0x0123 ^ (short)0x4567), "getAndBitwiseXorRelease short value"); + assertEquals((short)((short)0x0123 ^ (short)0x4567), x, "getAndBitwiseXorRelease short value"); } } } diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessString.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessString.java index 8ccede760c9..35723f63d27 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessString.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessString.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,22 +25,22 @@ * @test * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations * to hit compilation thresholds - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestMethodHandleAccessString + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestMethodHandleAccessString */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { static final String static_final_v = "foo"; @@ -60,7 +60,7 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { VarHandle vhArray; - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestMethodHandleAccessString.class, "final_v", String.class); @@ -77,8 +77,6 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { vhArray = MethodHandles.arrayElementVarHandle(String[].class); } - - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -111,7 +109,8 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -120,13 +119,12 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { } } - static void testInstanceField(VarHandleTestMethodHandleAccessString recv, Handles hs) throws Throwable { // Plain { hs.get(TestAccessMode.SET).invokeExact(recv, "foo"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, "foo", "set String value"); + assertEquals("foo", x, "set String value"); } @@ -134,21 +132,21 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact(recv, "bar"); String x = (String) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(recv); - assertEquals(x, "bar", "setVolatile String value"); + assertEquals("bar", x, "setVolatile String value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact(recv, "foo"); String x = (String) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(recv); - assertEquals(x, "foo", "setRelease String value"); + assertEquals("foo", x, "setRelease String value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact(recv, "bar"); String x = (String) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(recv); - assertEquals(x, "bar", "setOpaque String value"); + assertEquals("bar", x, "setOpaque String value"); } hs.get(TestAccessMode.SET).invokeExact(recv, "foo"); @@ -158,56 +156,56 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, "foo", "bar"); assertEquals(r, true, "success compareAndSet String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, "bar", "success compareAndSet String value"); + assertEquals("bar", x, "success compareAndSet String value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, "foo", "baz"); assertEquals(r, false, "failing compareAndSet String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, "bar", "failing compareAndSet String value"); + assertEquals("bar", x, "failing compareAndSet String value"); } { String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, "bar", "foo"); assertEquals(r, "bar", "success compareAndExchange String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, "foo", "success compareAndExchange String value"); + assertEquals("foo", x, "success compareAndExchange String value"); } { String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, "bar", "baz"); assertEquals(r, "foo", "failing compareAndExchange String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, "foo", "failing compareAndExchange String value"); + assertEquals("foo", x, "failing compareAndExchange String value"); } { String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, "foo", "bar"); assertEquals(r, "foo", "success compareAndExchangeAcquire String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, "bar", "success compareAndExchangeAcquire String value"); + assertEquals("bar", x, "success compareAndExchangeAcquire String value"); } { String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, "foo", "baz"); assertEquals(r, "bar", "failing compareAndExchangeAcquire String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, "bar", "failing compareAndExchangeAcquire String value"); + assertEquals("bar", x, "failing compareAndExchangeAcquire String value"); } { String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, "bar", "foo"); assertEquals(r, "bar", "success compareAndExchangeRelease String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, "foo", "success compareAndExchangeRelease String value"); + assertEquals("foo", x, "success compareAndExchangeRelease String value"); } { String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, "bar", "baz"); assertEquals(r, "foo", "failing compareAndExchangeRelease String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, "foo", "failing compareAndExchangeRelease String value"); + assertEquals("foo", x, "failing compareAndExchangeRelease String value"); } { @@ -219,14 +217,14 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, "bar", "success weakCompareAndSetPlain String value"); + assertEquals("bar", x, "success weakCompareAndSetPlain String value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, "foo", "baz"); assertEquals(success, false, "failing weakCompareAndSetPlain String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, "bar", "failing weakCompareAndSetPlain String value"); + assertEquals("bar", x, "failing weakCompareAndSetPlain String value"); } { @@ -238,14 +236,14 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, "foo", "success weakCompareAndSetAcquire String"); + assertEquals("foo", x, "success weakCompareAndSetAcquire String"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, "bar", "baz"); assertEquals(success, false, "failing weakCompareAndSetAcquire String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, "foo", "failing weakCompareAndSetAcquire String value"); + assertEquals("foo", x, "failing weakCompareAndSetAcquire String value"); } { @@ -257,14 +255,14 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, "bar", "success weakCompareAndSetRelease String"); + assertEquals("bar", x, "success weakCompareAndSetRelease String"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, "foo", "baz"); assertEquals(success, false, "failing weakCompareAndSetRelease String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, "bar", "failing weakCompareAndSetRelease String value"); + assertEquals("bar", x, "failing weakCompareAndSetRelease String value"); } { @@ -276,22 +274,22 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, "foo", "success weakCompareAndSet String"); + assertEquals("foo", x, "success weakCompareAndSet String"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, "bar", "baz"); assertEquals(success, false, "failing weakCompareAndSet String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, "foo", "failing weakCompareAndSet String value"); + assertEquals("foo", x, "failing weakCompareAndSet String value"); } // Compare set and get { String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, "bar"); - assertEquals(o, "foo", "getAndSet String"); + assertEquals("foo", o, "getAndSet String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, "bar", "getAndSet String value"); + assertEquals("bar", x, "getAndSet String value"); } @@ -318,7 +316,7 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { { hs.get(TestAccessMode.SET).invokeExact("foo"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, "foo", "set String value"); + assertEquals("foo", x, "set String value"); } @@ -326,21 +324,21 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact("bar"); String x = (String) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(); - assertEquals(x, "bar", "setVolatile String value"); + assertEquals("bar", x, "setVolatile String value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact("foo"); String x = (String) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(); - assertEquals(x, "foo", "setRelease String value"); + assertEquals("foo", x, "setRelease String value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact("bar"); String x = (String) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(); - assertEquals(x, "bar", "setOpaque String value"); + assertEquals("bar", x, "setOpaque String value"); } hs.get(TestAccessMode.SET).invokeExact("foo"); @@ -350,56 +348,56 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact("foo", "bar"); assertEquals(r, true, "success compareAndSet String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, "bar", "success compareAndSet String value"); + assertEquals("bar", x, "success compareAndSet String value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact("foo", "baz"); assertEquals(r, false, "failing compareAndSet String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, "bar", "failing compareAndSet String value"); + assertEquals("bar", x, "failing compareAndSet String value"); } { String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact("bar", "foo"); assertEquals(r, "bar", "success compareAndExchange String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, "foo", "success compareAndExchange String value"); + assertEquals("foo", x, "success compareAndExchange String value"); } { String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact("bar", "baz"); assertEquals(r, "foo", "failing compareAndExchange String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, "foo", "failing compareAndExchange String value"); + assertEquals("foo", x, "failing compareAndExchange String value"); } { String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact("foo", "bar"); assertEquals(r, "foo", "success compareAndExchangeAcquire String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, "bar", "success compareAndExchangeAcquire String value"); + assertEquals("bar", x, "success compareAndExchangeAcquire String value"); } { String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact("foo", "baz"); assertEquals(r, "bar", "failing compareAndExchangeAcquire String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, "bar", "failing compareAndExchangeAcquire String value"); + assertEquals("bar", x, "failing compareAndExchangeAcquire String value"); } { String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact("bar", "foo"); assertEquals(r, "bar", "success compareAndExchangeRelease String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, "foo", "success compareAndExchangeRelease String value"); + assertEquals("foo", x, "success compareAndExchangeRelease String value"); } { String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact("bar", "baz"); assertEquals(r, "foo", "failing compareAndExchangeRelease String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, "foo", "failing compareAndExchangeRelease String value"); + assertEquals("foo", x, "failing compareAndExchangeRelease String value"); } { @@ -411,14 +409,14 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, "bar", "success weakCompareAndSetPlain String value"); + assertEquals("bar", x, "success weakCompareAndSetPlain String value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact("foo", "baz"); assertEquals(success, false, "failing weakCompareAndSetPlain String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, "bar", "failing weakCompareAndSetPlain String value"); + assertEquals("bar", x, "failing weakCompareAndSetPlain String value"); } { @@ -430,7 +428,7 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, "foo", "success weakCompareAndSetAcquire String"); + assertEquals("foo", x, "success weakCompareAndSetAcquire String"); } { @@ -438,7 +436,7 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { boolean success = (boolean) mh.invokeExact("bar", "baz"); assertEquals(success, false, "failing weakCompareAndSetAcquire String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, "foo", "failing weakCompareAndSetAcquire String value"); + assertEquals("foo", x, "failing weakCompareAndSetAcquire String value"); } { @@ -450,14 +448,14 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, "bar", "success weakCompareAndSetRelease String"); + assertEquals("bar", x, "success weakCompareAndSetRelease String"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact("foo", "baz"); assertEquals(success, false, "failing weakCompareAndSetRelease String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, "bar", "failing weakCompareAndSetRelease String value"); + assertEquals("bar", x, "failing weakCompareAndSetRelease String value"); } { @@ -469,14 +467,14 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, "foo", "success weakCompareAndSet String"); + assertEquals("foo", x, "success weakCompareAndSet String"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact("bar", "baz"); assertEquals(success, false, "failing weakCompareAndSet String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, "foo", "failing weakCompareAndSetRe String value"); + assertEquals("foo", x, "failing weakCompareAndSetRe String value"); } // Compare set and get @@ -484,9 +482,9 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact("foo"); String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact("bar"); - assertEquals(o, "foo", "getAndSet String"); + assertEquals("foo", o, "getAndSet String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, "bar", "getAndSet String value"); + assertEquals("bar", x, "getAndSet String value"); } // Compare set and get @@ -494,9 +492,9 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact("foo"); String o = (String) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact("bar"); - assertEquals(o, "foo", "getAndSetAcquire String"); + assertEquals("foo", o, "getAndSetAcquire String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, "bar", "getAndSetAcquire String value"); + assertEquals("bar", x, "getAndSetAcquire String value"); } // Compare set and get @@ -504,9 +502,9 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact("foo"); String o = (String) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact("bar"); - assertEquals(o, "foo", "getAndSetRelease String"); + assertEquals("foo", o, "getAndSetRelease String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, "bar", "getAndSetRelease String value"); + assertEquals("bar", x, "getAndSetRelease String value"); } @@ -536,7 +534,7 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { { hs.get(TestAccessMode.SET).invokeExact(array, i, "foo"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, "foo", "get String value"); + assertEquals("foo", x, "get String value"); } @@ -544,21 +542,21 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact(array, i, "bar"); String x = (String) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(array, i); - assertEquals(x, "bar", "setVolatile String value"); + assertEquals("bar", x, "setVolatile String value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact(array, i, "foo"); String x = (String) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(array, i); - assertEquals(x, "foo", "setRelease String value"); + assertEquals("foo", x, "setRelease String value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact(array, i, "bar"); String x = (String) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(array, i); - assertEquals(x, "bar", "setOpaque String value"); + assertEquals("bar", x, "setOpaque String value"); } hs.get(TestAccessMode.SET).invokeExact(array, i, "foo"); @@ -568,56 +566,56 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, "foo", "bar"); assertEquals(r, true, "success compareAndSet String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, "bar", "success compareAndSet String value"); + assertEquals("bar", x, "success compareAndSet String value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, "foo", "baz"); assertEquals(r, false, "failing compareAndSet String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, "bar", "failing compareAndSet String value"); + assertEquals("bar", x, "failing compareAndSet String value"); } { String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, "bar", "foo"); assertEquals(r, "bar", "success compareAndExchange String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, "foo", "success compareAndExchange String value"); + assertEquals("foo", x, "success compareAndExchange String value"); } { String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, "bar", "baz"); assertEquals(r, "foo", "failing compareAndExchange String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, "foo", "failing compareAndExchange String value"); + assertEquals("foo", x, "failing compareAndExchange String value"); } { String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, "foo", "bar"); assertEquals(r, "foo", "success compareAndExchangeAcquire String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, "bar", "success compareAndExchangeAcquire String value"); + assertEquals("bar", x, "success compareAndExchangeAcquire String value"); } { String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, "foo", "baz"); assertEquals(r, "bar", "failing compareAndExchangeAcquire String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, "bar", "failing compareAndExchangeAcquire String value"); + assertEquals("bar", x, "failing compareAndExchangeAcquire String value"); } { String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, "bar", "foo"); assertEquals(r, "bar", "success compareAndExchangeRelease String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, "foo", "success compareAndExchangeRelease String value"); + assertEquals("foo", x, "success compareAndExchangeRelease String value"); } { String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, "bar", "baz"); assertEquals(r, "foo", "failing compareAndExchangeRelease String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, "foo", "failing compareAndExchangeRelease String value"); + assertEquals("foo", x, "failing compareAndExchangeRelease String value"); } { @@ -629,14 +627,14 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, "bar", "success weakCompareAndSetPlain String value"); + assertEquals("bar", x, "success weakCompareAndSetPlain String value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, "foo", "baz"); assertEquals(success, false, "failing weakCompareAndSetPlain String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, "bar", "failing weakCompareAndSetPlain String value"); + assertEquals("bar", x, "failing weakCompareAndSetPlain String value"); } { @@ -648,14 +646,14 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, "foo", "success weakCompareAndSetAcquire String"); + assertEquals("foo", x, "success weakCompareAndSetAcquire String"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, "bar", "baz"); assertEquals(success, false, "failing weakCompareAndSetAcquire String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, "foo", "failing weakCompareAndSetAcquire String value"); + assertEquals("foo", x, "failing weakCompareAndSetAcquire String value"); } { @@ -667,14 +665,14 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, "bar", "success weakCompareAndSetRelease String"); + assertEquals("bar", x, "success weakCompareAndSetRelease String"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, "foo", "baz"); assertEquals(success, false, "failing weakCompareAndSetAcquire String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, "bar", "failing weakCompareAndSetAcquire String value"); + assertEquals("bar", x, "failing weakCompareAndSetAcquire String value"); } { @@ -686,14 +684,14 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, "foo", "success weakCompareAndSet String"); + assertEquals("foo", x, "success weakCompareAndSet String"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, "bar", "baz"); assertEquals(success, false, "failing weakCompareAndSet String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, "foo", "failing weakCompareAndSet String value"); + assertEquals("foo", x, "failing weakCompareAndSet String value"); } // Compare set and get @@ -701,27 +699,27 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, "foo"); String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, "bar"); - assertEquals(o, "foo", "getAndSet String"); + assertEquals("foo", o, "getAndSet String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, "bar", "getAndSet String value"); + assertEquals("bar", x, "getAndSet String value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, "foo"); String o = (String) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact(array, i, "bar"); - assertEquals(o, "foo", "getAndSetAcquire String"); + assertEquals("foo", o, "getAndSetAcquire String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, "bar", "getAndSetAcquire String value"); + assertEquals("bar", x, "getAndSetAcquire String value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, "foo"); String o = (String) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact(array, i, "bar"); - assertEquals(o, "foo", "getAndSetRelease String"); + assertEquals("foo", o, "getAndSetRelease String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, "bar", "getAndSetRelease String value"); + assertEquals("bar", x, "getAndSetRelease String value"); } diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeBoolean.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeBoolean.java index eb6327d4c55..b10466a1fc7 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeBoolean.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeBoolean.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,26 +24,26 @@ /* * @test * @bug 8156486 - * @run testng/othervm VarHandleTestMethodTypeBoolean - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=true -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeBoolean - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=false VarHandleTestMethodTypeBoolean - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeBoolean + * @run junit/othervm VarHandleTestMethodTypeBoolean + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=true -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeBoolean + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=false VarHandleTestMethodTypeBoolean + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeBoolean */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; - import static java.lang.invoke.MethodType.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestMethodTypeBoolean extends VarHandleBaseTest { static final boolean static_final_v = true; @@ -63,7 +63,7 @@ public class VarHandleTestMethodTypeBoolean extends VarHandleBaseTest { VarHandle vhArray; - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestMethodTypeBoolean.class, "final_v", boolean.class); @@ -80,7 +80,6 @@ public class VarHandleTestMethodTypeBoolean extends VarHandleBaseTest { vhArray = MethodHandles.arrayElementVarHandle(boolean[].class); } - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -115,7 +114,8 @@ public class VarHandleTestMethodTypeBoolean extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -124,7 +124,6 @@ public class VarHandleTestMethodTypeBoolean extends VarHandleBaseTest { } } - static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeBoolean recv, VarHandle vh) throws Throwable { // Get // Incorrect argument types diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeByte.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeByte.java index 08b834699af..ce8686ebd74 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeByte.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeByte.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,26 +24,26 @@ /* * @test * @bug 8156486 - * @run testng/othervm VarHandleTestMethodTypeByte - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=true -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeByte - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=false VarHandleTestMethodTypeByte - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeByte + * @run junit/othervm VarHandleTestMethodTypeByte + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=true -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeByte + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=false VarHandleTestMethodTypeByte + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeByte */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; - import static java.lang.invoke.MethodType.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestMethodTypeByte extends VarHandleBaseTest { static final byte static_final_v = (byte)0x01; @@ -63,7 +63,7 @@ public class VarHandleTestMethodTypeByte extends VarHandleBaseTest { VarHandle vhArray; - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestMethodTypeByte.class, "final_v", byte.class); @@ -80,7 +80,6 @@ public class VarHandleTestMethodTypeByte extends VarHandleBaseTest { vhArray = MethodHandles.arrayElementVarHandle(byte[].class); } - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -115,7 +114,8 @@ public class VarHandleTestMethodTypeByte extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -124,7 +124,6 @@ public class VarHandleTestMethodTypeByte extends VarHandleBaseTest { } } - static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeByte recv, VarHandle vh) throws Throwable { // Get // Incorrect argument types diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeChar.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeChar.java index 25aa62825b7..d89af7f212c 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeChar.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeChar.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,26 +24,26 @@ /* * @test * @bug 8156486 - * @run testng/othervm VarHandleTestMethodTypeChar - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=true -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeChar - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=false VarHandleTestMethodTypeChar - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeChar + * @run junit/othervm VarHandleTestMethodTypeChar + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=true -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeChar + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=false VarHandleTestMethodTypeChar + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeChar */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; - import static java.lang.invoke.MethodType.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestMethodTypeChar extends VarHandleBaseTest { static final char static_final_v = '\u0123'; @@ -63,7 +63,7 @@ public class VarHandleTestMethodTypeChar extends VarHandleBaseTest { VarHandle vhArray; - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestMethodTypeChar.class, "final_v", char.class); @@ -80,7 +80,6 @@ public class VarHandleTestMethodTypeChar extends VarHandleBaseTest { vhArray = MethodHandles.arrayElementVarHandle(char[].class); } - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -115,7 +114,8 @@ public class VarHandleTestMethodTypeChar extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -124,7 +124,6 @@ public class VarHandleTestMethodTypeChar extends VarHandleBaseTest { } } - static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeChar recv, VarHandle vh) throws Throwable { // Get // Incorrect argument types diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeDouble.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeDouble.java index c3f8d22435b..0363a996ceb 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeDouble.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeDouble.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,26 +24,26 @@ /* * @test * @bug 8156486 - * @run testng/othervm VarHandleTestMethodTypeDouble - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=true -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeDouble - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=false VarHandleTestMethodTypeDouble - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeDouble + * @run junit/othervm VarHandleTestMethodTypeDouble + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=true -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeDouble + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=false VarHandleTestMethodTypeDouble + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeDouble */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; - import static java.lang.invoke.MethodType.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestMethodTypeDouble extends VarHandleBaseTest { static final double static_final_v = 1.0d; @@ -63,7 +63,7 @@ public class VarHandleTestMethodTypeDouble extends VarHandleBaseTest { VarHandle vhArray; - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestMethodTypeDouble.class, "final_v", double.class); @@ -80,7 +80,6 @@ public class VarHandleTestMethodTypeDouble extends VarHandleBaseTest { vhArray = MethodHandles.arrayElementVarHandle(double[].class); } - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -115,7 +114,8 @@ public class VarHandleTestMethodTypeDouble extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -124,7 +124,6 @@ public class VarHandleTestMethodTypeDouble extends VarHandleBaseTest { } } - static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeDouble recv, VarHandle vh) throws Throwable { // Get // Incorrect argument types diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeFloat.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeFloat.java index 0d05270b3ac..c8b965e41df 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeFloat.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeFloat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,26 +24,26 @@ /* * @test * @bug 8156486 - * @run testng/othervm VarHandleTestMethodTypeFloat - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=true -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeFloat - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=false VarHandleTestMethodTypeFloat - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeFloat + * @run junit/othervm VarHandleTestMethodTypeFloat + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=true -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeFloat + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=false VarHandleTestMethodTypeFloat + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeFloat */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; - import static java.lang.invoke.MethodType.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestMethodTypeFloat extends VarHandleBaseTest { static final float static_final_v = 1.0f; @@ -63,7 +63,7 @@ public class VarHandleTestMethodTypeFloat extends VarHandleBaseTest { VarHandle vhArray; - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestMethodTypeFloat.class, "final_v", float.class); @@ -80,7 +80,6 @@ public class VarHandleTestMethodTypeFloat extends VarHandleBaseTest { vhArray = MethodHandles.arrayElementVarHandle(float[].class); } - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -115,7 +114,8 @@ public class VarHandleTestMethodTypeFloat extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -124,7 +124,6 @@ public class VarHandleTestMethodTypeFloat extends VarHandleBaseTest { } } - static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeFloat recv, VarHandle vh) throws Throwable { // Get // Incorrect argument types diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeInt.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeInt.java index a431c0a889e..e09427c55c7 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeInt.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeInt.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,26 +24,26 @@ /* * @test * @bug 8156486 - * @run testng/othervm VarHandleTestMethodTypeInt - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=true -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeInt - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=false VarHandleTestMethodTypeInt - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeInt + * @run junit/othervm VarHandleTestMethodTypeInt + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=true -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeInt + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=false VarHandleTestMethodTypeInt + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeInt */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; - import static java.lang.invoke.MethodType.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestMethodTypeInt extends VarHandleBaseTest { static final int static_final_v = 0x01234567; @@ -63,7 +63,7 @@ public class VarHandleTestMethodTypeInt extends VarHandleBaseTest { VarHandle vhArray; - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestMethodTypeInt.class, "final_v", int.class); @@ -80,7 +80,6 @@ public class VarHandleTestMethodTypeInt extends VarHandleBaseTest { vhArray = MethodHandles.arrayElementVarHandle(int[].class); } - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -115,7 +114,8 @@ public class VarHandleTestMethodTypeInt extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -124,7 +124,6 @@ public class VarHandleTestMethodTypeInt extends VarHandleBaseTest { } } - static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeInt recv, VarHandle vh) throws Throwable { // Get // Incorrect argument types diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeLong.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeLong.java index 53b9257d700..5944e935877 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeLong.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeLong.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,26 +24,26 @@ /* * @test * @bug 8156486 - * @run testng/othervm VarHandleTestMethodTypeLong - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=true -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeLong - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=false VarHandleTestMethodTypeLong - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeLong + * @run junit/othervm VarHandleTestMethodTypeLong + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=true -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeLong + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=false VarHandleTestMethodTypeLong + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeLong */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; - import static java.lang.invoke.MethodType.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestMethodTypeLong extends VarHandleBaseTest { static final long static_final_v = 0x0123456789ABCDEFL; @@ -63,7 +63,7 @@ public class VarHandleTestMethodTypeLong extends VarHandleBaseTest { VarHandle vhArray; - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestMethodTypeLong.class, "final_v", long.class); @@ -80,7 +80,6 @@ public class VarHandleTestMethodTypeLong extends VarHandleBaseTest { vhArray = MethodHandles.arrayElementVarHandle(long[].class); } - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -115,7 +114,8 @@ public class VarHandleTestMethodTypeLong extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -124,7 +124,6 @@ public class VarHandleTestMethodTypeLong extends VarHandleBaseTest { } } - static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeLong recv, VarHandle vh) throws Throwable { // Get // Incorrect argument types diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeShort.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeShort.java index 10dd5832c9b..fdb30ee88aa 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeShort.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeShort.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,26 +24,26 @@ /* * @test * @bug 8156486 - * @run testng/othervm VarHandleTestMethodTypeShort - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=true -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeShort - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=false VarHandleTestMethodTypeShort - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeShort + * @run junit/othervm VarHandleTestMethodTypeShort + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=true -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeShort + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=false VarHandleTestMethodTypeShort + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeShort */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; - import static java.lang.invoke.MethodType.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestMethodTypeShort extends VarHandleBaseTest { static final short static_final_v = (short)0x0123; @@ -63,7 +63,7 @@ public class VarHandleTestMethodTypeShort extends VarHandleBaseTest { VarHandle vhArray; - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestMethodTypeShort.class, "final_v", short.class); @@ -80,7 +80,6 @@ public class VarHandleTestMethodTypeShort extends VarHandleBaseTest { vhArray = MethodHandles.arrayElementVarHandle(short[].class); } - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -115,7 +114,8 @@ public class VarHandleTestMethodTypeShort extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -124,7 +124,6 @@ public class VarHandleTestMethodTypeShort extends VarHandleBaseTest { } } - static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeShort recv, VarHandle vh) throws Throwable { // Get // Incorrect argument types diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeString.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeString.java index d823a21d69f..2a5284ca36e 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeString.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodTypeString.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,26 +24,26 @@ /* * @test * @bug 8156486 - * @run testng/othervm VarHandleTestMethodTypeString - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=true -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeString - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=false VarHandleTestMethodTypeString - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeString + * @run junit/othervm VarHandleTestMethodTypeString + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=true -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeString + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=false VarHandleTestMethodTypeString + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodTypeString */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; - import static java.lang.invoke.MethodType.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestMethodTypeString extends VarHandleBaseTest { static final String static_final_v = "foo"; @@ -63,7 +63,7 @@ public class VarHandleTestMethodTypeString extends VarHandleBaseTest { VarHandle vhArray; - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestMethodTypeString.class, "final_v", String.class); @@ -80,7 +80,6 @@ public class VarHandleTestMethodTypeString extends VarHandleBaseTest { vhArray = MethodHandles.arrayElementVarHandle(String[].class); } - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -115,7 +114,8 @@ public class VarHandleTestMethodTypeString extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -124,7 +124,6 @@ public class VarHandleTestMethodTypeString extends VarHandleBaseTest { } } - static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeString recv, VarHandle vh) throws Throwable { // Get // Incorrect argument types diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestReflection.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestReflection.java index b20e18d263e..2c22fd5595b 100644 --- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestReflection.java +++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestReflection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,11 +23,9 @@ /* * @test - * @run testng VarHandleTestReflection + * @run junit VarHandleTestReflection */ -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandleInfo; @@ -36,11 +34,16 @@ import java.lang.invoke.VarHandle; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.stream.Stream; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import static org.junit.jupiter.api.Assertions.assertThrows; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestReflection extends VarHandleBaseTest { String string; - @DataProvider public static Object[][] accessModesProvider() { return Stream.of(VarHandle.AccessMode.values()). map(am -> new Object[]{am}). @@ -52,17 +55,19 @@ public class VarHandleTestReflection extends VarHandleBaseTest { findVarHandle(VarHandleTestReflection.class, "string", String.class); } - @Test(dataProvider = "accessModesProvider", expectedExceptions = IllegalArgumentException.class) + @ParameterizedTest + @MethodSource("accessModesProvider") public void methodInvocationArgumentMismatch(VarHandle.AccessMode accessMode) throws Exception { VarHandle v = handle(); // Try a reflective invoke using a Method, with no arguments Method vhm = VarHandle.class.getMethod(accessMode.methodName(), Object[].class); - vhm.invoke(v, new Object[]{}); + assertThrows(IllegalArgumentException.class, () -> vhm.invoke(v, new Object[]{})); } - @Test(dataProvider = "accessModesProvider") + @ParameterizedTest + @MethodSource("accessModesProvider") public void methodInvocationMatchingArguments(VarHandle.AccessMode accessMode) throws Exception { VarHandle v = handle(); @@ -70,17 +75,15 @@ public class VarHandleTestReflection extends VarHandleBaseTest { Method vhm = VarHandle.class.getMethod(accessMode.methodName(), Object[].class); Object arg = new Object[0]; - try { - vhm.invoke(v, arg); - } catch (InvocationTargetException e) { - if (!(e.getCause() instanceof UnsupportedOperationException)) { - throw new RuntimeException("expected UnsupportedOperationException but got: " - + e.getCause().getClass().getName(), e); - } + var e = assertThrows(InvocationTargetException.class, () -> vhm.invoke(v, arg)); + if (!(e.getCause() instanceof UnsupportedOperationException)) { + throw new RuntimeException("expected UnsupportedOperationException but got: " + + e.getCause().getClass().getName(), e); } } - @Test(dataProvider = "accessModesProvider", expectedExceptions = UnsupportedOperationException.class) + @ParameterizedTest + @MethodSource("accessModesProvider") public void methodHandleInvoke(VarHandle.AccessMode accessMode) throws Throwable { VarHandle v = handle(); @@ -90,10 +93,13 @@ public class VarHandleTestReflection extends VarHandleBaseTest { VarHandle.class.getMethod(accessMode.methodName(), Object[].class)); // Use invoke to avoid WrongMethodTypeException for // non-signature-polymorphic return types - Object o = (Object) mh.invoke(v, new Object[]{}); + assertThrows(UnsupportedOperationException.class, () -> { + Object o = (Object) mh.invoke(v, new Object[]{}); + }); } - @Test(dataProvider = "accessModesProvider", expectedExceptions = IllegalArgumentException.class) + @ParameterizedTest + @MethodSource("accessModesProvider") public void methodInvocationFromMethodInfo(VarHandle.AccessMode accessMode) throws Exception { VarHandle v = handle(); @@ -104,10 +110,13 @@ public class VarHandleTestReflection extends VarHandleBaseTest { VarHandle.class.getMethod(accessMode.methodName(), Object[].class)); MethodHandleInfo info = MethodHandles.lookup().revealDirect(mh); Method im = info.reflectAs(Method.class, MethodHandles.lookup()); - im.invoke(v, new Object[]{}); + assertThrows(IllegalArgumentException.class, () -> { + im.invoke(v, new Object[]{}); + }); } - @Test(dataProvider = "accessModesProvider", expectedExceptions = IllegalArgumentException.class) + @ParameterizedTest + @MethodSource("accessModesProvider") public void reflectAsFromVarHandleInvoker(VarHandle.AccessMode accessMode) throws Exception { VarHandle v = handle(); @@ -116,10 +125,11 @@ public class VarHandleTestReflection extends VarHandleBaseTest { MethodHandleInfo info = MethodHandles.lookup().revealDirect(mh); - info.reflectAs(Method.class, MethodHandles.lookup()); + assertThrows(IllegalArgumentException.class, () -> info.reflectAs(Method.class, MethodHandles.lookup())); } - @Test(dataProvider = "accessModesProvider", expectedExceptions = IllegalArgumentException.class) + @ParameterizedTest + @MethodSource("accessModesProvider") public void reflectAsFromFindVirtual(VarHandle.AccessMode accessMode) throws Exception { VarHandle v = handle(); @@ -128,6 +138,6 @@ public class VarHandleTestReflection extends VarHandleBaseTest { MethodHandleInfo info = MethodHandles.lookup().revealDirect(mh); - info.reflectAs(Method.class, MethodHandles.lookup()); + assertThrows(IllegalArgumentException.class, () -> info.reflectAs(Method.class, MethodHandles.lookup())); } } diff --git a/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template b/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template index f3c90c5e8cc..b18dbb6e1b0 100644 --- a/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template +++ b/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,28 +23,30 @@ /* * @test - * @run testng/othervm -Diters=10 -Xint VarHandleTestAccess$Type$ + * @run junit/othervm -Diters=10 -Xint VarHandleTestAccess$Type$ * * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations * to hit compilation thresholds * - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestAccess$Type$ - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestAccess$Type$ - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestAccess$Type$ + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestAccess$Type$ + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestAccess$Type$ + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestAccess$Type$ */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { static final $type$ static_final_v = $value1$; @@ -115,7 +117,7 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { return vhs.toArray(new VarHandle[0]); } - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestAccess$Type$.class, "final_v", $type$.class); @@ -135,8 +137,6 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { #end[String] } - - @DataProvider public Object[][] varHandlesProvider() throws Exception { List vhs = new ArrayList<>(); vhs.add(vhField); @@ -166,7 +166,8 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { } } - @Test(dataProvider = "varHandlesProvider") + @ParameterizedTest + @MethodSource("varHandlesProvider") public void testIsAccessModeSupported(VarHandle vh) { assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET)); @@ -236,8 +237,6 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { #end[Bitwise] } - - @DataProvider public Object[][] typesProvider() throws Exception { List types = new ArrayList<>(); types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccess$Type$.class)}); @@ -247,16 +246,16 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { return types.stream().toArray(Object[][]::new); } - @Test(dataProvider = "typesProvider") + @ParameterizedTest + @MethodSource("typesProvider") public void testTypes(VarHandle vh, List> pts) { - assertEquals(vh.varType(), $type$.class); + assertEquals($type$.class, vh.varType()); - assertEquals(vh.coordinateTypes(), pts); + assertEquals(pts, vh.coordinateTypes()); testTypes(vh); } - @Test public void testLookupInstanceToStatic() { checkIAE("Lookup of static final field to instance final field", () -> { @@ -283,8 +282,6 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { }); } - - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -335,7 +332,8 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -348,26 +346,26 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { // Plain { $type$ x = ($type$) vh.get(recv); - assertEquals(x, $value1$, "get $type$ value"); + assertEquals($value1$, x, "get $type$ value"); } // Volatile { $type$ x = ($type$) vh.getVolatile(recv); - assertEquals(x, $value1$, "getVolatile $type$ value"); + assertEquals($value1$, x, "getVolatile $type$ value"); } // Lazy { $type$ x = ($type$) vh.getAcquire(recv); - assertEquals(x, $value1$, "getRelease $type$ value"); + assertEquals($value1$, x, "getRelease $type$ value"); } // Opaque { $type$ x = ($type$) vh.getOpaque(recv); - assertEquals(x, $value1$, "getOpaque $type$ value"); + assertEquals($value1$, x, "getOpaque $type$ value"); } } @@ -492,26 +490,26 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { // Plain { $type$ x = ($type$) vh.get(); - assertEquals(x, $value1$, "get $type$ value"); + assertEquals($value1$, x, "get $type$ value"); } // Volatile { $type$ x = ($type$) vh.getVolatile(); - assertEquals(x, $value1$, "getVolatile $type$ value"); + assertEquals($value1$, x, "getVolatile $type$ value"); } // Lazy { $type$ x = ($type$) vh.getAcquire(); - assertEquals(x, $value1$, "getRelease $type$ value"); + assertEquals($value1$, x, "getRelease $type$ value"); } // Opaque { $type$ x = ($type$) vh.getOpaque(); - assertEquals(x, $value1$, "getOpaque $type$ value"); + assertEquals($value1$, x, "getOpaque $type$ value"); } } @@ -637,7 +635,7 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { { vh.set(recv, $value1$); $type$ x = ($type$) vh.get(recv); - assertEquals(x, $value1$, "set $type$ value"); + assertEquals($value1$, x, "set $type$ value"); } @@ -645,21 +643,21 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { { vh.setVolatile(recv, $value2$); $type$ x = ($type$) vh.getVolatile(recv); - assertEquals(x, $value2$, "setVolatile $type$ value"); + assertEquals($value2$, x, "setVolatile $type$ value"); } // Lazy { vh.setRelease(recv, $value1$); $type$ x = ($type$) vh.getAcquire(recv); - assertEquals(x, $value1$, "setRelease $type$ value"); + assertEquals($value1$, x, "setRelease $type$ value"); } // Opaque { vh.setOpaque(recv, $value2$); $type$ x = ($type$) vh.getOpaque(recv); - assertEquals(x, $value2$, "setOpaque $type$ value"); + assertEquals($value2$, x, "setOpaque $type$ value"); } #if[CAS] @@ -670,56 +668,56 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { boolean r = vh.compareAndSet(recv, $value1$, $value2$); assertEquals(r, true, "success compareAndSet $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, $value2$, "success compareAndSet $type$ value"); + assertEquals($value2$, x, "success compareAndSet $type$ value"); } { boolean r = vh.compareAndSet(recv, $value1$, $value3$); assertEquals(r, false, "failing compareAndSet $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, $value2$, "failing compareAndSet $type$ value"); + assertEquals($value2$, x, "failing compareAndSet $type$ value"); } { $type$ r = ($type$) vh.compareAndExchange(recv, $value2$, $value1$); assertEquals(r, $value2$, "success compareAndExchange $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, $value1$, "success compareAndExchange $type$ value"); + assertEquals($value1$, x, "success compareAndExchange $type$ value"); } { $type$ r = ($type$) vh.compareAndExchange(recv, $value2$, $value3$); assertEquals(r, $value1$, "failing compareAndExchange $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, $value1$, "failing compareAndExchange $type$ value"); + assertEquals($value1$, x, "failing compareAndExchange $type$ value"); } { $type$ r = ($type$) vh.compareAndExchangeAcquire(recv, $value1$, $value2$); assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value"); + assertEquals($value2$, x, "success compareAndExchangeAcquire $type$ value"); } { $type$ r = ($type$) vh.compareAndExchangeAcquire(recv, $value1$, $value3$); assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value"); + assertEquals($value2$, x, "failing compareAndExchangeAcquire $type$ value"); } { $type$ r = ($type$) vh.compareAndExchangeRelease(recv, $value2$, $value1$); assertEquals(r, $value2$, "success compareAndExchangeRelease $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value"); + assertEquals($value1$, x, "success compareAndExchangeRelease $type$ value"); } { $type$ r = ($type$) vh.compareAndExchangeRelease(recv, $value2$, $value3$); assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value"); + assertEquals($value1$, x, "failing compareAndExchangeRelease $type$ value"); } { @@ -730,14 +728,14 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, $value2$, "success weakCompareAndSetPlain $type$ value"); + assertEquals($value2$, x, "success weakCompareAndSetPlain $type$ value"); } { boolean success = vh.weakCompareAndSetPlain(recv, $value1$, $value3$); assertEquals(success, false, "failing weakCompareAndSetPlain $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, $value2$, "failing weakCompareAndSetPlain $type$ value"); + assertEquals($value2$, x, "failing weakCompareAndSetPlain $type$ value"); } { @@ -748,14 +746,14 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, $value1$, "success weakCompareAndSetAcquire $type$"); + assertEquals($value1$, x, "success weakCompareAndSetAcquire $type$"); } { boolean success = vh.weakCompareAndSetAcquire(recv, $value2$, $value3$); assertEquals(success, false, "failing weakCompareAndSetAcquire $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, $value1$, "failing weakCompareAndSetAcquire $type$ value"); + assertEquals($value1$, x, "failing weakCompareAndSetAcquire $type$ value"); } { @@ -766,14 +764,14 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, $value2$, "success weakCompareAndSetRelease $type$"); + assertEquals($value2$, x, "success weakCompareAndSetRelease $type$"); } { boolean success = vh.weakCompareAndSetRelease(recv, $value1$, $value3$); assertEquals(success, false, "failing weakCompareAndSetRelease $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, $value2$, "failing weakCompareAndSetRelease $type$ value"); + assertEquals($value2$, x, "failing weakCompareAndSetRelease $type$ value"); } { @@ -784,14 +782,14 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, $value1$, "success weakCompareAndSet $type$ value"); + assertEquals($value1$, x, "success weakCompareAndSet $type$ value"); } { boolean success = vh.weakCompareAndSet(recv, $value2$, $value3$); assertEquals(success, false, "failing weakCompareAndSet $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, $value1$, "failing weakCompareAndSet $type$ value"); + assertEquals($value1$, x, "failing weakCompareAndSet $type$ value"); } // Compare set and get @@ -799,27 +797,27 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { vh.set(recv, $value1$); $type$ o = ($type$) vh.getAndSet(recv, $value2$); - assertEquals(o, $value1$, "getAndSet $type$"); + assertEquals($value1$, o, "getAndSet $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, $value2$, "getAndSet $type$ value"); + assertEquals($value2$, x, "getAndSet $type$ value"); } { vh.set(recv, $value1$); $type$ o = ($type$) vh.getAndSetAcquire(recv, $value2$); - assertEquals(o, $value1$, "getAndSetAcquire $type$"); + assertEquals($value1$, o, "getAndSetAcquire $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, $value2$, "getAndSetAcquire $type$ value"); + assertEquals($value2$, x, "getAndSetAcquire $type$ value"); } { vh.set(recv, $value1$); $type$ o = ($type$) vh.getAndSetRelease(recv, $value2$); - assertEquals(o, $value1$, "getAndSetRelease $type$"); + assertEquals($value1$, o, "getAndSetRelease $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, $value2$, "getAndSetRelease $type$ value"); + assertEquals($value2$, x, "getAndSetRelease $type$ value"); } #end[CAS] @@ -829,27 +827,27 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { vh.set(recv, $value1$); $type$ o = ($type$) vh.getAndAdd(recv, $value2$); - assertEquals(o, $value1$, "getAndAdd $type$"); + assertEquals($value1$, o, "getAndAdd $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, ($type$)($value1$ + $value2$), "getAndAdd $type$ value"); + assertEquals(($type$)($value1$ + $value2$), x, "getAndAdd $type$ value"); } { vh.set(recv, $value1$); $type$ o = ($type$) vh.getAndAddAcquire(recv, $value2$); - assertEquals(o, $value1$, "getAndAddAcquire $type$"); + assertEquals($value1$, o, "getAndAddAcquire $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, ($type$)($value1$ + $value2$), "getAndAddAcquire $type$ value"); + assertEquals(($type$)($value1$ + $value2$), x, "getAndAddAcquire $type$ value"); } { vh.set(recv, $value1$); $type$ o = ($type$) vh.getAndAddRelease(recv, $value2$); - assertEquals(o, $value1$, "getAndAddRelease$type$"); + assertEquals($value1$, o, "getAndAddRelease$type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, ($type$)($value1$ + $value2$), "getAndAddRelease $type$ value"); + assertEquals(($type$)($value1$ + $value2$), x, "getAndAddRelease $type$ value"); } #end[AtomicAdd] @@ -859,27 +857,27 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { vh.set(recv, $value1$); $type$ o = ($type$) vh.getAndBitwiseOr(recv, $value2$); - assertEquals(o, $value1$, "getAndBitwiseOr $type$"); + assertEquals($value1$, o, "getAndBitwiseOr $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, ($type$)($value1$ | $value2$), "getAndBitwiseOr $type$ value"); + assertEquals(($type$)($value1$ | $value2$), x, "getAndBitwiseOr $type$ value"); } { vh.set(recv, $value1$); $type$ o = ($type$) vh.getAndBitwiseOrAcquire(recv, $value2$); - assertEquals(o, $value1$, "getAndBitwiseOrAcquire $type$"); + assertEquals($value1$, o, "getAndBitwiseOrAcquire $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, ($type$)($value1$ | $value2$), "getAndBitwiseOrAcquire $type$ value"); + assertEquals(($type$)($value1$ | $value2$), x, "getAndBitwiseOrAcquire $type$ value"); } { vh.set(recv, $value1$); $type$ o = ($type$) vh.getAndBitwiseOrRelease(recv, $value2$); - assertEquals(o, $value1$, "getAndBitwiseOrRelease $type$"); + assertEquals($value1$, o, "getAndBitwiseOrRelease $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, ($type$)($value1$ | $value2$), "getAndBitwiseOrRelease $type$ value"); + assertEquals(($type$)($value1$ | $value2$), x, "getAndBitwiseOrRelease $type$ value"); } // get and bitwise and @@ -887,27 +885,27 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { vh.set(recv, $value1$); $type$ o = ($type$) vh.getAndBitwiseAnd(recv, $value2$); - assertEquals(o, $value1$, "getAndBitwiseAnd $type$"); + assertEquals($value1$, o, "getAndBitwiseAnd $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, ($type$)($value1$ & $value2$), "getAndBitwiseAnd $type$ value"); + assertEquals(($type$)($value1$ & $value2$), x, "getAndBitwiseAnd $type$ value"); } { vh.set(recv, $value1$); $type$ o = ($type$) vh.getAndBitwiseAndAcquire(recv, $value2$); - assertEquals(o, $value1$, "getAndBitwiseAndAcquire $type$"); + assertEquals($value1$, o, "getAndBitwiseAndAcquire $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, ($type$)($value1$ & $value2$), "getAndBitwiseAndAcquire $type$ value"); + assertEquals(($type$)($value1$ & $value2$), x, "getAndBitwiseAndAcquire $type$ value"); } { vh.set(recv, $value1$); $type$ o = ($type$) vh.getAndBitwiseAndRelease(recv, $value2$); - assertEquals(o, $value1$, "getAndBitwiseAndRelease $type$"); + assertEquals($value1$, o, "getAndBitwiseAndRelease $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, ($type$)($value1$ & $value2$), "getAndBitwiseAndRelease $type$ value"); + assertEquals(($type$)($value1$ & $value2$), x, "getAndBitwiseAndRelease $type$ value"); } // get and bitwise xor @@ -915,27 +913,27 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { vh.set(recv, $value1$); $type$ o = ($type$) vh.getAndBitwiseXor(recv, $value2$); - assertEquals(o, $value1$, "getAndBitwiseXor $type$"); + assertEquals($value1$, o, "getAndBitwiseXor $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, ($type$)($value1$ ^ $value2$), "getAndBitwiseXor $type$ value"); + assertEquals(($type$)($value1$ ^ $value2$), x, "getAndBitwiseXor $type$ value"); } { vh.set(recv, $value1$); $type$ o = ($type$) vh.getAndBitwiseXorAcquire(recv, $value2$); - assertEquals(o, $value1$, "getAndBitwiseXorAcquire $type$"); + assertEquals($value1$, o, "getAndBitwiseXorAcquire $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, ($type$)($value1$ ^ $value2$), "getAndBitwiseXorAcquire $type$ value"); + assertEquals(($type$)($value1$ ^ $value2$), x, "getAndBitwiseXorAcquire $type$ value"); } { vh.set(recv, $value1$); $type$ o = ($type$) vh.getAndBitwiseXorRelease(recv, $value2$); - assertEquals(o, $value1$, "getAndBitwiseXorRelease $type$"); + assertEquals($value1$, o, "getAndBitwiseXorRelease $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, ($type$)($value1$ ^ $value2$), "getAndBitwiseXorRelease $type$ value"); + assertEquals(($type$)($value1$ ^ $value2$), x, "getAndBitwiseXorRelease $type$ value"); } #end[Bitwise] } @@ -1046,7 +1044,7 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { { vh.set($value1$); $type$ x = ($type$) vh.get(); - assertEquals(x, $value1$, "set $type$ value"); + assertEquals($value1$, x, "set $type$ value"); } @@ -1054,21 +1052,21 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { { vh.setVolatile($value2$); $type$ x = ($type$) vh.getVolatile(); - assertEquals(x, $value2$, "setVolatile $type$ value"); + assertEquals($value2$, x, "setVolatile $type$ value"); } // Lazy { vh.setRelease($value1$); $type$ x = ($type$) vh.getAcquire(); - assertEquals(x, $value1$, "setRelease $type$ value"); + assertEquals($value1$, x, "setRelease $type$ value"); } // Opaque { vh.setOpaque($value2$); $type$ x = ($type$) vh.getOpaque(); - assertEquals(x, $value2$, "setOpaque $type$ value"); + assertEquals($value2$, x, "setOpaque $type$ value"); } #if[CAS] @@ -1079,56 +1077,56 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { boolean r = vh.compareAndSet($value1$, $value2$); assertEquals(r, true, "success compareAndSet $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, $value2$, "success compareAndSet $type$ value"); + assertEquals($value2$, x, "success compareAndSet $type$ value"); } { boolean r = vh.compareAndSet($value1$, $value3$); assertEquals(r, false, "failing compareAndSet $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, $value2$, "failing compareAndSet $type$ value"); + assertEquals($value2$, x, "failing compareAndSet $type$ value"); } { $type$ r = ($type$) vh.compareAndExchange($value2$, $value1$); assertEquals(r, $value2$, "success compareAndExchange $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, $value1$, "success compareAndExchange $type$ value"); + assertEquals($value1$, x, "success compareAndExchange $type$ value"); } { $type$ r = ($type$) vh.compareAndExchange($value2$, $value3$); assertEquals(r, $value1$, "failing compareAndExchange $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, $value1$, "failing compareAndExchange $type$ value"); + assertEquals($value1$, x, "failing compareAndExchange $type$ value"); } { $type$ r = ($type$) vh.compareAndExchangeAcquire($value1$, $value2$); assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value"); + assertEquals($value2$, x, "success compareAndExchangeAcquire $type$ value"); } { $type$ r = ($type$) vh.compareAndExchangeAcquire($value1$, $value3$); assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value"); + assertEquals($value2$, x, "failing compareAndExchangeAcquire $type$ value"); } { $type$ r = ($type$) vh.compareAndExchangeRelease($value2$, $value1$); assertEquals(r, $value2$, "success compareAndExchangeRelease $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value"); + assertEquals($value1$, x, "success compareAndExchangeRelease $type$ value"); } { $type$ r = ($type$) vh.compareAndExchangeRelease($value2$, $value3$); assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value"); + assertEquals($value1$, x, "failing compareAndExchangeRelease $type$ value"); } { @@ -1139,14 +1137,14 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, $value2$, "success weakCompareAndSetPlain $type$ value"); + assertEquals($value2$, x, "success weakCompareAndSetPlain $type$ value"); } { boolean success = vh.weakCompareAndSetPlain($value1$, $value3$); assertEquals(success, false, "failing weakCompareAndSetPlain $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, $value2$, "failing weakCompareAndSetPlain $type$ value"); + assertEquals($value2$, x, "failing weakCompareAndSetPlain $type$ value"); } { @@ -1157,14 +1155,14 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, $value1$, "success weakCompareAndSetAcquire $type$"); + assertEquals($value1$, x, "success weakCompareAndSetAcquire $type$"); } { boolean success = vh.weakCompareAndSetAcquire($value2$, $value3$); assertEquals(success, false, "failing weakCompareAndSetAcquire $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, $value1$, "failing weakCompareAndSetAcquire $type$ value"); + assertEquals($value1$, x, "failing weakCompareAndSetAcquire $type$ value"); } { @@ -1175,14 +1173,14 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, $value2$, "success weakCompareAndSetRelease $type$"); + assertEquals($value2$, x, "success weakCompareAndSetRelease $type$"); } { boolean success = vh.weakCompareAndSetRelease($value1$, $value3$); assertEquals(success, false, "failing weakCompareAndSetRelease $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, $value2$, "failing weakCompareAndSetRelease $type$ value"); + assertEquals($value2$, x, "failing weakCompareAndSetRelease $type$ value"); } { @@ -1193,14 +1191,14 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, $value1$, "success weakCompareAndSet $type$"); + assertEquals($value1$, x, "success weakCompareAndSet $type$"); } { boolean success = vh.weakCompareAndSet($value2$, $value3$); assertEquals(success, false, "failing weakCompareAndSet $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, $value1$, "failing weakCompareAndSet $type$ value"); + assertEquals($value1$, x, "failing weakCompareAndSet $type$ value"); } // Compare set and get @@ -1208,27 +1206,27 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { vh.set($value1$); $type$ o = ($type$) vh.getAndSet($value2$); - assertEquals(o, $value1$, "getAndSet $type$"); + assertEquals($value1$, o, "getAndSet $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, $value2$, "getAndSet $type$ value"); + assertEquals($value2$, x, "getAndSet $type$ value"); } { vh.set($value1$); $type$ o = ($type$) vh.getAndSetAcquire($value2$); - assertEquals(o, $value1$, "getAndSetAcquire $type$"); + assertEquals($value1$, o, "getAndSetAcquire $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, $value2$, "getAndSetAcquire $type$ value"); + assertEquals($value2$, x, "getAndSetAcquire $type$ value"); } { vh.set($value1$); $type$ o = ($type$) vh.getAndSetRelease($value2$); - assertEquals(o, $value1$, "getAndSetRelease $type$"); + assertEquals($value1$, o, "getAndSetRelease $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, $value2$, "getAndSetRelease $type$ value"); + assertEquals($value2$, x, "getAndSetRelease $type$ value"); } #end[CAS] @@ -1238,27 +1236,27 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { vh.set($value1$); $type$ o = ($type$) vh.getAndAdd($value2$); - assertEquals(o, $value1$, "getAndAdd $type$"); + assertEquals($value1$, o, "getAndAdd $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, ($type$)($value1$ + $value2$), "getAndAdd $type$ value"); + assertEquals(($type$)($value1$ + $value2$), x, "getAndAdd $type$ value"); } { vh.set($value1$); $type$ o = ($type$) vh.getAndAddAcquire($value2$); - assertEquals(o, $value1$, "getAndAddAcquire $type$"); + assertEquals($value1$, o, "getAndAddAcquire $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, ($type$)($value1$ + $value2$), "getAndAddAcquire $type$ value"); + assertEquals(($type$)($value1$ + $value2$), x, "getAndAddAcquire $type$ value"); } { vh.set($value1$); $type$ o = ($type$) vh.getAndAddRelease($value2$); - assertEquals(o, $value1$, "getAndAddRelease$type$"); + assertEquals($value1$, o, "getAndAddRelease$type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, ($type$)($value1$ + $value2$), "getAndAddRelease $type$ value"); + assertEquals(($type$)($value1$ + $value2$), x, "getAndAddRelease $type$ value"); } #end[AtomicAdd] @@ -1268,27 +1266,27 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { vh.set($value1$); $type$ o = ($type$) vh.getAndBitwiseOr($value2$); - assertEquals(o, $value1$, "getAndBitwiseOr $type$"); + assertEquals($value1$, o, "getAndBitwiseOr $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, ($type$)($value1$ | $value2$), "getAndBitwiseOr $type$ value"); + assertEquals(($type$)($value1$ | $value2$), x, "getAndBitwiseOr $type$ value"); } { vh.set($value1$); $type$ o = ($type$) vh.getAndBitwiseOrAcquire($value2$); - assertEquals(o, $value1$, "getAndBitwiseOrAcquire $type$"); + assertEquals($value1$, o, "getAndBitwiseOrAcquire $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, ($type$)($value1$ | $value2$), "getAndBitwiseOrAcquire $type$ value"); + assertEquals(($type$)($value1$ | $value2$), x, "getAndBitwiseOrAcquire $type$ value"); } { vh.set($value1$); $type$ o = ($type$) vh.getAndBitwiseOrRelease($value2$); - assertEquals(o, $value1$, "getAndBitwiseOrRelease $type$"); + assertEquals($value1$, o, "getAndBitwiseOrRelease $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, ($type$)($value1$ | $value2$), "getAndBitwiseOrRelease $type$ value"); + assertEquals(($type$)($value1$ | $value2$), x, "getAndBitwiseOrRelease $type$ value"); } // get and bitwise and @@ -1296,27 +1294,27 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { vh.set($value1$); $type$ o = ($type$) vh.getAndBitwiseAnd($value2$); - assertEquals(o, $value1$, "getAndBitwiseAnd $type$"); + assertEquals($value1$, o, "getAndBitwiseAnd $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, ($type$)($value1$ & $value2$), "getAndBitwiseAnd $type$ value"); + assertEquals(($type$)($value1$ & $value2$), x, "getAndBitwiseAnd $type$ value"); } { vh.set($value1$); $type$ o = ($type$) vh.getAndBitwiseAndAcquire($value2$); - assertEquals(o, $value1$, "getAndBitwiseAndAcquire $type$"); + assertEquals($value1$, o, "getAndBitwiseAndAcquire $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, ($type$)($value1$ & $value2$), "getAndBitwiseAndAcquire $type$ value"); + assertEquals(($type$)($value1$ & $value2$), x, "getAndBitwiseAndAcquire $type$ value"); } { vh.set($value1$); $type$ o = ($type$) vh.getAndBitwiseAndRelease($value2$); - assertEquals(o, $value1$, "getAndBitwiseAndRelease $type$"); + assertEquals($value1$, o, "getAndBitwiseAndRelease $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, ($type$)($value1$ & $value2$), "getAndBitwiseAndRelease $type$ value"); + assertEquals(($type$)($value1$ & $value2$), x, "getAndBitwiseAndRelease $type$ value"); } // get and bitwise xor @@ -1324,27 +1322,27 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { vh.set($value1$); $type$ o = ($type$) vh.getAndBitwiseXor($value2$); - assertEquals(o, $value1$, "getAndBitwiseXor $type$"); + assertEquals($value1$, o, "getAndBitwiseXor $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, ($type$)($value1$ ^ $value2$), "getAndBitwiseXor $type$ value"); + assertEquals(($type$)($value1$ ^ $value2$), x, "getAndBitwiseXor $type$ value"); } { vh.set($value1$); $type$ o = ($type$) vh.getAndBitwiseXorAcquire($value2$); - assertEquals(o, $value1$, "getAndBitwiseXorAcquire $type$"); + assertEquals($value1$, o, "getAndBitwiseXorAcquire $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, ($type$)($value1$ ^ $value2$), "getAndBitwiseXorAcquire $type$ value"); + assertEquals(($type$)($value1$ ^ $value2$), x, "getAndBitwiseXorAcquire $type$ value"); } { vh.set($value1$); $type$ o = ($type$) vh.getAndBitwiseXorRelease($value2$); - assertEquals(o, $value1$, "getAndBitwiseXorRelease $type$"); + assertEquals($value1$, o, "getAndBitwiseXorRelease $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, ($type$)($value1$ ^ $value2$), "getAndBitwiseXorRelease $type$ value"); + assertEquals(($type$)($value1$ ^ $value2$), x, "getAndBitwiseXorRelease $type$ value"); } #end[Bitwise] } @@ -1458,7 +1456,7 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { { vh.set(array, i, $value1$); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, $value1$, "get $type$ value"); + assertEquals($value1$, x, "get $type$ value"); } @@ -1466,21 +1464,21 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { { vh.setVolatile(array, i, $value2$); $type$ x = ($type$) vh.getVolatile(array, i); - assertEquals(x, $value2$, "setVolatile $type$ value"); + assertEquals($value2$, x, "setVolatile $type$ value"); } // Lazy { vh.setRelease(array, i, $value1$); $type$ x = ($type$) vh.getAcquire(array, i); - assertEquals(x, $value1$, "setRelease $type$ value"); + assertEquals($value1$, x, "setRelease $type$ value"); } // Opaque { vh.setOpaque(array, i, $value2$); $type$ x = ($type$) vh.getOpaque(array, i); - assertEquals(x, $value2$, "setOpaque $type$ value"); + assertEquals($value2$, x, "setOpaque $type$ value"); } #if[CAS] @@ -1491,56 +1489,56 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { boolean r = vh.compareAndSet(array, i, $value1$, $value2$); assertEquals(r, true, "success compareAndSet $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, $value2$, "success compareAndSet $type$ value"); + assertEquals($value2$, x, "success compareAndSet $type$ value"); } { boolean r = vh.compareAndSet(array, i, $value1$, $value3$); assertEquals(r, false, "failing compareAndSet $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, $value2$, "failing compareAndSet $type$ value"); + assertEquals($value2$, x, "failing compareAndSet $type$ value"); } { $type$ r = ($type$) vh.compareAndExchange(array, i, $value2$, $value1$); assertEquals(r, $value2$, "success compareAndExchange $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, $value1$, "success compareAndExchange $type$ value"); + assertEquals($value1$, x, "success compareAndExchange $type$ value"); } { $type$ r = ($type$) vh.compareAndExchange(array, i, $value2$, $value3$); assertEquals(r, $value1$, "failing compareAndExchange $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, $value1$, "failing compareAndExchange $type$ value"); + assertEquals($value1$, x, "failing compareAndExchange $type$ value"); } { $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, $value1$, $value2$); assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value"); + assertEquals($value2$, x, "success compareAndExchangeAcquire $type$ value"); } { $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, $value1$, $value3$); assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value"); + assertEquals($value2$, x, "failing compareAndExchangeAcquire $type$ value"); } { $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, $value2$, $value1$); assertEquals(r, $value2$, "success compareAndExchangeRelease $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value"); + assertEquals($value1$, x, "success compareAndExchangeRelease $type$ value"); } { $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, $value2$, $value3$); assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value"); + assertEquals($value1$, x, "failing compareAndExchangeRelease $type$ value"); } { @@ -1551,14 +1549,14 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, $value2$, "success weakCompareAndSetPlain $type$ value"); + assertEquals($value2$, x, "success weakCompareAndSetPlain $type$ value"); } { boolean success = vh.weakCompareAndSetPlain(array, i, $value1$, $value3$); assertEquals(success, false, "failing weakCompareAndSetPlain $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, $value2$, "failing weakCompareAndSetPlain $type$ value"); + assertEquals($value2$, x, "failing weakCompareAndSetPlain $type$ value"); } { @@ -1569,14 +1567,14 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, $value1$, "success weakCompareAndSetAcquire $type$"); + assertEquals($value1$, x, "success weakCompareAndSetAcquire $type$"); } { boolean success = vh.weakCompareAndSetAcquire(array, i, $value2$, $value3$); assertEquals(success, false, "failing weakCompareAndSetAcquire $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, $value1$, "failing weakCompareAndSetAcquire $type$ value"); + assertEquals($value1$, x, "failing weakCompareAndSetAcquire $type$ value"); } { @@ -1587,14 +1585,14 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, $value2$, "success weakCompareAndSetRelease $type$"); + assertEquals($value2$, x, "success weakCompareAndSetRelease $type$"); } { boolean success = vh.weakCompareAndSetRelease(array, i, $value1$, $value3$); assertEquals(success, false, "failing weakCompareAndSetRelease $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, $value2$, "failing weakCompareAndSetRelease $type$ value"); + assertEquals($value2$, x, "failing weakCompareAndSetRelease $type$ value"); } { @@ -1605,14 +1603,14 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, $value1$, "success weakCompareAndSet $type$"); + assertEquals($value1$, x, "success weakCompareAndSet $type$"); } { boolean success = vh.weakCompareAndSet(array, i, $value2$, $value3$); assertEquals(success, false, "failing weakCompareAndSet $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, $value1$, "failing weakCompareAndSet $type$ value"); + assertEquals($value1$, x, "failing weakCompareAndSet $type$ value"); } // Compare set and get @@ -1620,27 +1618,27 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { vh.set(array, i, $value1$); $type$ o = ($type$) vh.getAndSet(array, i, $value2$); - assertEquals(o, $value1$, "getAndSet $type$"); + assertEquals($value1$, o, "getAndSet $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, $value2$, "getAndSet $type$ value"); + assertEquals($value2$, x, "getAndSet $type$ value"); } { vh.set(array, i, $value1$); $type$ o = ($type$) vh.getAndSetAcquire(array, i, $value2$); - assertEquals(o, $value1$, "getAndSetAcquire $type$"); + assertEquals($value1$, o, "getAndSetAcquire $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, $value2$, "getAndSetAcquire $type$ value"); + assertEquals($value2$, x, "getAndSetAcquire $type$ value"); } { vh.set(array, i, $value1$); $type$ o = ($type$) vh.getAndSetRelease(array, i, $value2$); - assertEquals(o, $value1$, "getAndSetRelease $type$"); + assertEquals($value1$, o, "getAndSetRelease $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, $value2$, "getAndSetRelease $type$ value"); + assertEquals($value2$, x, "getAndSetRelease $type$ value"); } #end[CAS] @@ -1650,27 +1648,27 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { vh.set(array, i, $value1$); $type$ o = ($type$) vh.getAndAdd(array, i, $value2$); - assertEquals(o, $value1$, "getAndAdd $type$"); + assertEquals($value1$, o, "getAndAdd $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, ($type$)($value1$ + $value2$), "getAndAdd $type$ value"); + assertEquals(($type$)($value1$ + $value2$), x, "getAndAdd $type$ value"); } { vh.set(array, i, $value1$); $type$ o = ($type$) vh.getAndAddAcquire(array, i, $value2$); - assertEquals(o, $value1$, "getAndAddAcquire $type$"); + assertEquals($value1$, o, "getAndAddAcquire $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, ($type$)($value1$ + $value2$), "getAndAddAcquire $type$ value"); + assertEquals(($type$)($value1$ + $value2$), x, "getAndAddAcquire $type$ value"); } { vh.set(array, i, $value1$); $type$ o = ($type$) vh.getAndAddRelease(array, i, $value2$); - assertEquals(o, $value1$, "getAndAddRelease$type$"); + assertEquals($value1$, o, "getAndAddRelease$type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, ($type$)($value1$ + $value2$), "getAndAddRelease $type$ value"); + assertEquals(($type$)($value1$ + $value2$), x, "getAndAddRelease $type$ value"); } #end[AtomicAdd] @@ -1680,27 +1678,27 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { vh.set(array, i, $value1$); $type$ o = ($type$) vh.getAndBitwiseOr(array, i, $value2$); - assertEquals(o, $value1$, "getAndBitwiseOr $type$"); + assertEquals($value1$, o, "getAndBitwiseOr $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, ($type$)($value1$ | $value2$), "getAndBitwiseOr $type$ value"); + assertEquals(($type$)($value1$ | $value2$), x, "getAndBitwiseOr $type$ value"); } { vh.set(array, i, $value1$); $type$ o = ($type$) vh.getAndBitwiseOrAcquire(array, i, $value2$); - assertEquals(o, $value1$, "getAndBitwiseOrAcquire $type$"); + assertEquals($value1$, o, "getAndBitwiseOrAcquire $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, ($type$)($value1$ | $value2$), "getAndBitwiseOrAcquire $type$ value"); + assertEquals(($type$)($value1$ | $value2$), x, "getAndBitwiseOrAcquire $type$ value"); } { vh.set(array, i, $value1$); $type$ o = ($type$) vh.getAndBitwiseOrRelease(array, i, $value2$); - assertEquals(o, $value1$, "getAndBitwiseOrRelease $type$"); + assertEquals($value1$, o, "getAndBitwiseOrRelease $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, ($type$)($value1$ | $value2$), "getAndBitwiseOrRelease $type$ value"); + assertEquals(($type$)($value1$ | $value2$), x, "getAndBitwiseOrRelease $type$ value"); } // get and bitwise and @@ -1708,27 +1706,27 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { vh.set(array, i, $value1$); $type$ o = ($type$) vh.getAndBitwiseAnd(array, i, $value2$); - assertEquals(o, $value1$, "getAndBitwiseAnd $type$"); + assertEquals($value1$, o, "getAndBitwiseAnd $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, ($type$)($value1$ & $value2$), "getAndBitwiseAnd $type$ value"); + assertEquals(($type$)($value1$ & $value2$), x, "getAndBitwiseAnd $type$ value"); } { vh.set(array, i, $value1$); $type$ o = ($type$) vh.getAndBitwiseAndAcquire(array, i, $value2$); - assertEquals(o, $value1$, "getAndBitwiseAndAcquire $type$"); + assertEquals($value1$, o, "getAndBitwiseAndAcquire $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, ($type$)($value1$ & $value2$), "getAndBitwiseAndAcquire $type$ value"); + assertEquals(($type$)($value1$ & $value2$), x, "getAndBitwiseAndAcquire $type$ value"); } { vh.set(array, i, $value1$); $type$ o = ($type$) vh.getAndBitwiseAndRelease(array, i, $value2$); - assertEquals(o, $value1$, "getAndBitwiseAndRelease $type$"); + assertEquals($value1$, o, "getAndBitwiseAndRelease $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, ($type$)($value1$ & $value2$), "getAndBitwiseAndRelease $type$ value"); + assertEquals(($type$)($value1$ & $value2$), x, "getAndBitwiseAndRelease $type$ value"); } // get and bitwise xor @@ -1736,27 +1734,27 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { vh.set(array, i, $value1$); $type$ o = ($type$) vh.getAndBitwiseXor(array, i, $value2$); - assertEquals(o, $value1$, "getAndBitwiseXor $type$"); + assertEquals($value1$, o, "getAndBitwiseXor $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, ($type$)($value1$ ^ $value2$), "getAndBitwiseXor $type$ value"); + assertEquals(($type$)($value1$ ^ $value2$), x, "getAndBitwiseXor $type$ value"); } { vh.set(array, i, $value1$); $type$ o = ($type$) vh.getAndBitwiseXorAcquire(array, i, $value2$); - assertEquals(o, $value1$, "getAndBitwiseXorAcquire $type$"); + assertEquals($value1$, o, "getAndBitwiseXorAcquire $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, ($type$)($value1$ ^ $value2$), "getAndBitwiseXorAcquire $type$ value"); + assertEquals(($type$)($value1$ ^ $value2$), x, "getAndBitwiseXorAcquire $type$ value"); } { vh.set(array, i, $value1$); $type$ o = ($type$) vh.getAndBitwiseXorRelease(array, i, $value2$); - assertEquals(o, $value1$, "getAndBitwiseXorRelease $type$"); + assertEquals($value1$, o, "getAndBitwiseXorRelease $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, ($type$)($value1$ ^ $value2$), "getAndBitwiseXorRelease $type$ value"); + assertEquals(($type$)($value1$ ^ $value2$), x, "getAndBitwiseXorRelease $type$ value"); } #end[Bitwise] } diff --git a/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template b/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template index c21709d6d37..9a40bfb2780 100644 --- a/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template +++ b/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,25 +26,25 @@ * @bug 8154556 * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations * to hit compilation thresholds - * @run testng/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAs$Type$ - * @run testng/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestByteArrayAs$Type$ - * @run testng/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestByteArrayAs$Type$ + * @run junit/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAs$Type$ + * @run junit/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestByteArrayAs$Type$ + * @run junit/othervm/timeout=360 -Diters=2000 -XX:CompileThresholdScaling=0.1 -XX:-TieredCompilation VarHandleTestByteArrayAs$Type$ */ -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; -import java.util.Arrays; -import java.util.EnumSet; import java.util.List; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest { static final int SIZE = $BoxType$.BYTES; @@ -111,7 +111,8 @@ public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest { } } - @Test(dataProvider = "varHandlesProvider") + @ParameterizedTest + @MethodSource("VarHandleBaseByteArrayTest#varHandlesProvider") public void testIsAccessModeSupported(VarHandleSource vhs) { VarHandle vh = vhs.s; @@ -206,17 +207,16 @@ public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest { #end[Bitwise] } - @Test(dataProvider = "typesProvider") + @ParameterizedTest + @MethodSource("typesProvider") public void testTypes(VarHandle vh, List> pts) { - assertEquals(vh.varType(), $type$.class); + assertEquals($type$.class, vh.varType()); - assertEquals(vh.coordinateTypes(), pts); + assertEquals(pts, vh.coordinateTypes()); testTypes(vh); } - - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -278,7 +278,8 @@ public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -287,7 +288,6 @@ public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest { } } - static void testArrayNPE(ByteArraySource bs, VarHandleSource vhs) { VarHandle vh = vhs.s; byte[] array = null; @@ -1272,7 +1272,7 @@ public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest { { vh.set(array, i, VALUE_1); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_1, "get $type$ value"); + assertEquals(VALUE_1, x, "get $type$ value"); } } } @@ -1291,7 +1291,7 @@ public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest { { vh.set(array, i, VALUE_1); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_1, "get $type$ value"); + assertEquals(VALUE_1, x, "get $type$ value"); } if (iAligned) { @@ -1299,21 +1299,21 @@ public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest { { vh.setVolatile(array, i, VALUE_2); $type$ x = ($type$) vh.getVolatile(array, i); - assertEquals(x, VALUE_2, "setVolatile $type$ value"); + assertEquals(VALUE_2, x, "setVolatile $type$ value"); } // Lazy { vh.setRelease(array, i, VALUE_1); $type$ x = ($type$) vh.getAcquire(array, i); - assertEquals(x, VALUE_1, "setRelease $type$ value"); + assertEquals(VALUE_1, x, "setRelease $type$ value"); } // Opaque { vh.setOpaque(array, i, VALUE_2); $type$ x = ($type$) vh.getOpaque(array, i); - assertEquals(x, VALUE_2, "setOpaque $type$ value"); + assertEquals(VALUE_2, x, "setOpaque $type$ value"); } #if[CAS] @@ -1324,56 +1324,56 @@ public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest { boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2); assertEquals(r, true, "success compareAndSet $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_2, "success compareAndSet $type$ value"); + assertEquals(VALUE_2, x, "success compareAndSet $type$ value"); } { boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3); assertEquals(r, false, "failing compareAndSet $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_2, "failing compareAndSet $type$ value"); + assertEquals(VALUE_2, x, "failing compareAndSet $type$ value"); } { $type$ r = ($type$) vh.compareAndExchange(array, i, VALUE_2, VALUE_1); assertEquals(r, VALUE_2, "success compareAndExchange $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_1, "success compareAndExchange $type$ value"); + assertEquals(VALUE_1, x, "success compareAndExchange $type$ value"); } { $type$ r = ($type$) vh.compareAndExchange(array, i, VALUE_2, VALUE_3); assertEquals(r, VALUE_1, "failing compareAndExchange $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_1, "failing compareAndExchange $type$ value"); + assertEquals(VALUE_1, x, "failing compareAndExchange $type$ value"); } { $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2); assertEquals(r, VALUE_1, "success compareAndExchangeAcquire $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_2, "success compareAndExchangeAcquire $type$ value"); + assertEquals(VALUE_2, x, "success compareAndExchangeAcquire $type$ value"); } { $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3); assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire $type$ value"); + assertEquals(VALUE_2, x, "failing compareAndExchangeAcquire $type$ value"); } { $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1); assertEquals(r, VALUE_2, "success compareAndExchangeRelease $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_1, "success compareAndExchangeRelease $type$ value"); + assertEquals(VALUE_1, x, "success compareAndExchangeRelease $type$ value"); } { $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3); assertEquals(r, VALUE_1, "failing compareAndExchangeRelease $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_1, "failing compareAndExchangeRelease $type$ value"); + assertEquals(VALUE_1, x, "failing compareAndExchangeRelease $type$ value"); } { @@ -1384,14 +1384,14 @@ public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest { } assertEquals(success, true, "success weakCompareAndSetPlain $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_2, "success weakCompareAndSetPlain $type$ value"); + assertEquals(VALUE_2, x, "success weakCompareAndSetPlain $type$ value"); } { boolean success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_3); assertEquals(success, false, "failing weakCompareAndSetPlain $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_2, "failing weakCompareAndSetPlain $type$ value"); + assertEquals(VALUE_2, x, "failing weakCompareAndSetPlain $type$ value"); } { @@ -1402,14 +1402,14 @@ public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest { } assertEquals(success, true, "success weakCompareAndSetAcquire $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_1, "success weakCompareAndSetAcquire $type$"); + assertEquals(VALUE_1, x, "success weakCompareAndSetAcquire $type$"); } { boolean success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_3); assertEquals(success, false, "failing weakCompareAndSetAcquire $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_1, "failing weakCompareAndSetAcquire $type$ value"); + assertEquals(VALUE_1, x, "failing weakCompareAndSetAcquire $type$ value"); } { @@ -1420,14 +1420,14 @@ public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest { } assertEquals(success, true, "success weakCompareAndSetRelease $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_2, "success weakCompareAndSetRelease $type$"); + assertEquals(VALUE_2, x, "success weakCompareAndSetRelease $type$"); } { boolean success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_3); assertEquals(success, false, "failing weakCompareAndSetRelease $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_2, "failing weakCompareAndSetRelease $type$ value"); + assertEquals(VALUE_2, x, "failing weakCompareAndSetRelease $type$ value"); } { @@ -1438,14 +1438,14 @@ public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest { } assertEquals(success, true, "success weakCompareAndSet $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_1, "success weakCompareAndSet $type$"); + assertEquals(VALUE_1, x, "success weakCompareAndSet $type$"); } { boolean success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_3); assertEquals(success, false, "failing weakCompareAndSet $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_1, "failing weakCompareAndSet $type$ value"); + assertEquals(VALUE_1, x, "failing weakCompareAndSet $type$ value"); } // Compare set and get @@ -1453,27 +1453,27 @@ public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest { vh.set(array, i, VALUE_1); $type$ o = ($type$) vh.getAndSet(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndSet $type$"); + assertEquals(VALUE_1, o, "getAndSet $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_2, "getAndSet $type$ value"); + assertEquals(VALUE_2, x, "getAndSet $type$ value"); } { vh.set(array, i, VALUE_1); $type$ o = ($type$) vh.getAndSetAcquire(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndSetAcquire $type$"); + assertEquals(VALUE_1, o, "getAndSetAcquire $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_2, "getAndSetAcquire $type$ value"); + assertEquals(VALUE_2, x, "getAndSetAcquire $type$ value"); } { vh.set(array, i, VALUE_1); $type$ o = ($type$) vh.getAndSetRelease(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndSetRelease $type$"); + assertEquals(VALUE_1, o, "getAndSetRelease $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_2, "getAndSetRelease $type$ value"); + assertEquals(VALUE_2, x, "getAndSetRelease $type$ value"); } #end[CAS] @@ -1483,27 +1483,27 @@ public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest { vh.set(array, i, VALUE_1); $type$ o = ($type$) vh.getAndAdd(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndAdd $type$"); + assertEquals(VALUE_1, o, "getAndAdd $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_1 + VALUE_2, "getAndAdd $type$ value"); + assertEquals(VALUE_1 + VALUE_2, x, "getAndAdd $type$ value"); } { vh.set(array, i, VALUE_1); $type$ o = ($type$) vh.getAndAddAcquire(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndAddAcquire $type$"); + assertEquals(VALUE_1, o, "getAndAddAcquire $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_1 + VALUE_2, "getAndAddAcquire $type$ value"); + assertEquals(VALUE_1 + VALUE_2, x, "getAndAddAcquire $type$ value"); } { vh.set(array, i, VALUE_1); $type$ o = ($type$) vh.getAndAddRelease(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndAddRelease $type$"); + assertEquals(VALUE_1, o, "getAndAddRelease $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_1 + VALUE_2, "getAndAddRelease $type$ value"); + assertEquals(VALUE_1 + VALUE_2, x, "getAndAddRelease $type$ value"); } #end[AtomicAdd] @@ -1513,27 +1513,27 @@ public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest { vh.set(array, i, VALUE_1); $type$ o = ($type$) vh.getAndBitwiseOr(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndBitwiseOr $type$"); + assertEquals(VALUE_1, o, "getAndBitwiseOr $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_1 | VALUE_2, "getAndBitwiseOr $type$ value"); + assertEquals(VALUE_1 | VALUE_2, x, "getAndBitwiseOr $type$ value"); } { vh.set(array, i, VALUE_1); $type$ o = ($type$) vh.getAndBitwiseOrAcquire(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndBitwiseOrAcquire $type$"); + assertEquals(VALUE_1, o, "getAndBitwiseOrAcquire $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_1 | VALUE_2, "getAndBitwiseOrAcquire $type$ value"); + assertEquals(VALUE_1 | VALUE_2, x, "getAndBitwiseOrAcquire $type$ value"); } { vh.set(array, i, VALUE_1); $type$ o = ($type$) vh.getAndBitwiseOrRelease(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndBitwiseOrRelease $type$"); + assertEquals(VALUE_1, o, "getAndBitwiseOrRelease $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_1 | VALUE_2, "getAndBitwiseOrRelease $type$ value"); + assertEquals(VALUE_1 | VALUE_2, x, "getAndBitwiseOrRelease $type$ value"); } // get and bitwise and @@ -1541,27 +1541,27 @@ public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest { vh.set(array, i, VALUE_1); $type$ o = ($type$) vh.getAndBitwiseAnd(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndBitwiseAnd $type$"); + assertEquals(VALUE_1, o, "getAndBitwiseAnd $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_1 & VALUE_2, "getAndBitwiseAnd $type$ value"); + assertEquals(VALUE_1 & VALUE_2, x, "getAndBitwiseAnd $type$ value"); } { vh.set(array, i, VALUE_1); $type$ o = ($type$) vh.getAndBitwiseAndAcquire(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndBitwiseAndAcquire $type$"); + assertEquals(VALUE_1, o, "getAndBitwiseAndAcquire $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_1 & VALUE_2, "getAndBitwiseAndAcquire $type$ value"); + assertEquals(VALUE_1 & VALUE_2, x, "getAndBitwiseAndAcquire $type$ value"); } { vh.set(array, i, VALUE_1); $type$ o = ($type$) vh.getAndBitwiseAndRelease(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndBitwiseAndRelease $type$"); + assertEquals(VALUE_1, o, "getAndBitwiseAndRelease $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_1 & VALUE_2, "getAndBitwiseAndRelease $type$ value"); + assertEquals(VALUE_1 & VALUE_2, x, "getAndBitwiseAndRelease $type$ value"); } // get and bitwise xor @@ -1569,27 +1569,27 @@ public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest { vh.set(array, i, VALUE_1); $type$ o = ($type$) vh.getAndBitwiseXor(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndBitwiseXor $type$"); + assertEquals(VALUE_1, o, "getAndBitwiseXor $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_1 ^ VALUE_2, "getAndBitwiseXor $type$ value"); + assertEquals(VALUE_1 ^ VALUE_2, x, "getAndBitwiseXor $type$ value"); } { vh.set(array, i, VALUE_1); $type$ o = ($type$) vh.getAndBitwiseXorAcquire(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndBitwiseXorAcquire $type$"); + assertEquals(VALUE_1, o, "getAndBitwiseXorAcquire $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_1 ^ VALUE_2, "getAndBitwiseXorAcquire $type$ value"); + assertEquals(VALUE_1 ^ VALUE_2, x, "getAndBitwiseXorAcquire $type$ value"); } { vh.set(array, i, VALUE_1); $type$ o = ($type$) vh.getAndBitwiseXorRelease(array, i, VALUE_2); - assertEquals(o, VALUE_1, "getAndBitwiseXorRelease $type$"); + assertEquals(VALUE_1, o, "getAndBitwiseXorRelease $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_1 ^ VALUE_2, "getAndBitwiseXorRelease $type$ value"); + assertEquals(VALUE_1 ^ VALUE_2, x, "getAndBitwiseXorRelease $type$ value"); } #end[Bitwise] } @@ -1614,26 +1614,26 @@ public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest { // Plain { $type$ x = ($type$) vh.get(array, i); - assertEquals(x, v, "get $type$ value"); + assertEquals(v, x, "get $type$ value"); } if (iAligned) { // Volatile { $type$ x = ($type$) vh.getVolatile(array, i); - assertEquals(x, v, "getVolatile $type$ value"); + assertEquals(v, x, "getVolatile $type$ value"); } // Lazy { $type$ x = ($type$) vh.getAcquire(array, i); - assertEquals(x, v, "getRelease $type$ value"); + assertEquals(v, x, "getRelease $type$ value"); } // Opaque { $type$ x = ($type$) vh.getOpaque(array, i); - assertEquals(x, v, "getOpaque $type$ value"); + assertEquals(v, x, "getOpaque $type$ value"); } } } diff --git a/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestMethodHandleAccess.java.template b/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestMethodHandleAccess.java.template index 4a9fa7c4fe8..a347b232d7e 100644 --- a/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestMethodHandleAccess.java.template +++ b/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestMethodHandleAccess.java.template @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,22 +25,22 @@ * @test * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations * to hit compilation thresholds - * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestMethodHandleAccess$Type$ + * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestMethodHandleAccess$Type$ */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { static final $type$ static_final_v = $value1$; @@ -60,7 +60,7 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { VarHandle vhArray; - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestMethodHandleAccess$Type$.class, "final_v", $type$.class); @@ -77,8 +77,6 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { vhArray = MethodHandles.arrayElementVarHandle($type$[].class); } - - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -111,7 +109,8 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -120,13 +119,12 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { } } - static void testInstanceField(VarHandleTestMethodHandleAccess$Type$ recv, Handles hs) throws Throwable { // Plain { hs.get(TestAccessMode.SET).invokeExact(recv, $value1$); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, $value1$, "set $type$ value"); + assertEquals($value1$, x, "set $type$ value"); } @@ -134,21 +132,21 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact(recv, $value2$); $type$ x = ($type$) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(recv); - assertEquals(x, $value2$, "setVolatile $type$ value"); + assertEquals($value2$, x, "setVolatile $type$ value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact(recv, $value1$); $type$ x = ($type$) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(recv); - assertEquals(x, $value1$, "setRelease $type$ value"); + assertEquals($value1$, x, "setRelease $type$ value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact(recv, $value2$); $type$ x = ($type$) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(recv); - assertEquals(x, $value2$, "setOpaque $type$ value"); + assertEquals($value2$, x, "setOpaque $type$ value"); } #if[CAS] @@ -159,56 +157,56 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, $value1$, $value2$); assertEquals(r, true, "success compareAndSet $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, $value2$, "success compareAndSet $type$ value"); + assertEquals($value2$, x, "success compareAndSet $type$ value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, $value1$, $value3$); assertEquals(r, false, "failing compareAndSet $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, $value2$, "failing compareAndSet $type$ value"); + assertEquals($value2$, x, "failing compareAndSet $type$ value"); } { $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, $value2$, $value1$); assertEquals(r, $value2$, "success compareAndExchange $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, $value1$, "success compareAndExchange $type$ value"); + assertEquals($value1$, x, "success compareAndExchange $type$ value"); } { $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, $value2$, $value3$); assertEquals(r, $value1$, "failing compareAndExchange $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, $value1$, "failing compareAndExchange $type$ value"); + assertEquals($value1$, x, "failing compareAndExchange $type$ value"); } { $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, $value1$, $value2$); assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value"); + assertEquals($value2$, x, "success compareAndExchangeAcquire $type$ value"); } { $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, $value1$, $value3$); assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value"); + assertEquals($value2$, x, "failing compareAndExchangeAcquire $type$ value"); } { $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, $value2$, $value1$); assertEquals(r, $value2$, "success compareAndExchangeRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value"); + assertEquals($value1$, x, "success compareAndExchangeRelease $type$ value"); } { $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, $value2$, $value3$); assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value"); + assertEquals($value1$, x, "failing compareAndExchangeRelease $type$ value"); } { @@ -220,14 +218,14 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, $value2$, "success weakCompareAndSetPlain $type$ value"); + assertEquals($value2$, x, "success weakCompareAndSetPlain $type$ value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, $value1$, $value3$); assertEquals(success, false, "failing weakCompareAndSetPlain $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, $value2$, "failing weakCompareAndSetPlain $type$ value"); + assertEquals($value2$, x, "failing weakCompareAndSetPlain $type$ value"); } { @@ -239,14 +237,14 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, $value1$, "success weakCompareAndSetAcquire $type$"); + assertEquals($value1$, x, "success weakCompareAndSetAcquire $type$"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, $value2$, $value3$); assertEquals(success, false, "failing weakCompareAndSetAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, $value1$, "failing weakCompareAndSetAcquire $type$ value"); + assertEquals($value1$, x, "failing weakCompareAndSetAcquire $type$ value"); } { @@ -258,14 +256,14 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, $value2$, "success weakCompareAndSetRelease $type$"); + assertEquals($value2$, x, "success weakCompareAndSetRelease $type$"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, $value1$, $value3$); assertEquals(success, false, "failing weakCompareAndSetRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, $value2$, "failing weakCompareAndSetRelease $type$ value"); + assertEquals($value2$, x, "failing weakCompareAndSetRelease $type$ value"); } { @@ -277,22 +275,22 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, $value1$, "success weakCompareAndSet $type$"); + assertEquals($value1$, x, "success weakCompareAndSet $type$"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, $value2$, $value3$); assertEquals(success, false, "failing weakCompareAndSet $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, $value1$, "failing weakCompareAndSet $type$ value"); + assertEquals($value1$, x, "failing weakCompareAndSet $type$ value"); } // Compare set and get { $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, $value2$); - assertEquals(o, $value1$, "getAndSet $type$"); + assertEquals($value1$, o, "getAndSet $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, $value2$, "getAndSet $type$ value"); + assertEquals($value2$, x, "getAndSet $type$ value"); } #end[CAS] @@ -302,27 +300,27 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(recv, $value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(recv, $value2$); - assertEquals(o, $value1$, "getAndAdd $type$"); + assertEquals($value1$, o, "getAndAdd $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, ($type$)($value1$ + $value2$), "getAndAdd $type$ value"); + assertEquals(($type$)($value1$ + $value2$), x, "getAndAdd $type$ value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, $value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact(recv, $value2$); - assertEquals(o, $value1$, "getAndAddAcquire $type$"); + assertEquals($value1$, o, "getAndAddAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, ($type$)($value1$ + $value2$), "getAndAddAcquire $type$ value"); + assertEquals(($type$)($value1$ + $value2$), x, "getAndAddAcquire $type$ value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, $value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact(recv, $value2$); - assertEquals(o, $value1$, "getAndAddRelease $type$"); + assertEquals($value1$, o, "getAndAddRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, ($type$)($value1$ + $value2$), "getAndAddRelease $type$ value"); + assertEquals(($type$)($value1$ + $value2$), x, "getAndAddRelease $type$ value"); } #end[AtomicAdd] @@ -332,27 +330,27 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(recv, $value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_OR).invokeExact(recv, $value2$); - assertEquals(o, $value1$, "getAndBitwiseOr $type$"); + assertEquals($value1$, o, "getAndBitwiseOr $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, ($type$)($value1$ | $value2$), "getAndBitwiseOr $type$ value"); + assertEquals(($type$)($value1$ | $value2$), x, "getAndBitwiseOr $type$ value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, $value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_OR_ACQUIRE).invokeExact(recv, $value2$); - assertEquals(o, $value1$, "getAndBitwiseOrAcquire $type$"); + assertEquals($value1$, o, "getAndBitwiseOrAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, ($type$)($value1$ | $value2$), "getAndBitwiseOrAcquire $type$ value"); + assertEquals(($type$)($value1$ | $value2$), x, "getAndBitwiseOrAcquire $type$ value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, $value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_OR_RELEASE).invokeExact(recv, $value2$); - assertEquals(o, $value1$, "getAndBitwiseOrRelease $type$"); + assertEquals($value1$, o, "getAndBitwiseOrRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, ($type$)($value1$ | $value2$), "getAndBitwiseOrRelease $type$ value"); + assertEquals(($type$)($value1$ | $value2$), x, "getAndBitwiseOrRelease $type$ value"); } // get and bitwise and @@ -360,27 +358,27 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(recv, $value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_AND).invokeExact(recv, $value2$); - assertEquals(o, $value1$, "getAndBitwiseAnd $type$"); + assertEquals($value1$, o, "getAndBitwiseAnd $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, ($type$)($value1$ & $value2$), "getAndBitwiseAnd $type$ value"); + assertEquals(($type$)($value1$ & $value2$), x, "getAndBitwiseAnd $type$ value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, $value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_AND_ACQUIRE).invokeExact(recv, $value2$); - assertEquals(o, $value1$, "getAndBitwiseAndAcquire $type$"); + assertEquals($value1$, o, "getAndBitwiseAndAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, ($type$)($value1$ & $value2$), "getAndBitwiseAndAcquire $type$ value"); + assertEquals(($type$)($value1$ & $value2$), x, "getAndBitwiseAndAcquire $type$ value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, $value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_AND_RELEASE).invokeExact(recv, $value2$); - assertEquals(o, $value1$, "getAndBitwiseAndRelease $type$"); + assertEquals($value1$, o, "getAndBitwiseAndRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, ($type$)($value1$ & $value2$), "getAndBitwiseAndRelease $type$ value"); + assertEquals(($type$)($value1$ & $value2$), x, "getAndBitwiseAndRelease $type$ value"); } // get and bitwise xor @@ -388,27 +386,27 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(recv, $value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_XOR).invokeExact(recv, $value2$); - assertEquals(o, $value1$, "getAndBitwiseXor $type$"); + assertEquals($value1$, o, "getAndBitwiseXor $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, ($type$)($value1$ ^ $value2$), "getAndBitwiseXor $type$ value"); + assertEquals(($type$)($value1$ ^ $value2$), x, "getAndBitwiseXor $type$ value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, $value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_ACQUIRE).invokeExact(recv, $value2$); - assertEquals(o, $value1$, "getAndBitwiseXorAcquire $type$"); + assertEquals($value1$, o, "getAndBitwiseXorAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, ($type$)($value1$ ^ $value2$), "getAndBitwiseXorAcquire $type$ value"); + assertEquals(($type$)($value1$ ^ $value2$), x, "getAndBitwiseXorAcquire $type$ value"); } { hs.get(TestAccessMode.SET).invokeExact(recv, $value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_RELEASE).invokeExact(recv, $value2$); - assertEquals(o, $value1$, "getAndBitwiseXorRelease $type$"); + assertEquals($value1$, o, "getAndBitwiseXorRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, ($type$)($value1$ ^ $value2$), "getAndBitwiseXorRelease $type$ value"); + assertEquals(($type$)($value1$ ^ $value2$), x, "getAndBitwiseXorRelease $type$ value"); } #end[Bitwise] } @@ -457,7 +455,7 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { { hs.get(TestAccessMode.SET).invokeExact($value1$); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, $value1$, "set $type$ value"); + assertEquals($value1$, x, "set $type$ value"); } @@ -465,21 +463,21 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact($value2$); $type$ x = ($type$) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(); - assertEquals(x, $value2$, "setVolatile $type$ value"); + assertEquals($value2$, x, "setVolatile $type$ value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact($value1$); $type$ x = ($type$) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(); - assertEquals(x, $value1$, "setRelease $type$ value"); + assertEquals($value1$, x, "setRelease $type$ value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact($value2$); $type$ x = ($type$) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(); - assertEquals(x, $value2$, "setOpaque $type$ value"); + assertEquals($value2$, x, "setOpaque $type$ value"); } #if[CAS] @@ -490,56 +488,56 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact($value1$, $value2$); assertEquals(r, true, "success compareAndSet $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, $value2$, "success compareAndSet $type$ value"); + assertEquals($value2$, x, "success compareAndSet $type$ value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact($value1$, $value3$); assertEquals(r, false, "failing compareAndSet $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, $value2$, "failing compareAndSet $type$ value"); + assertEquals($value2$, x, "failing compareAndSet $type$ value"); } { $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact($value2$, $value1$); assertEquals(r, $value2$, "success compareAndExchange $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, $value1$, "success compareAndExchange $type$ value"); + assertEquals($value1$, x, "success compareAndExchange $type$ value"); } { $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact($value2$, $value3$); assertEquals(r, $value1$, "failing compareAndExchange $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, $value1$, "failing compareAndExchange $type$ value"); + assertEquals($value1$, x, "failing compareAndExchange $type$ value"); } { $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact($value1$, $value2$); assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value"); + assertEquals($value2$, x, "success compareAndExchangeAcquire $type$ value"); } { $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact($value1$, $value3$); assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value"); + assertEquals($value2$, x, "failing compareAndExchangeAcquire $type$ value"); } { $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact($value2$, $value1$); assertEquals(r, $value2$, "success compareAndExchangeRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value"); + assertEquals($value1$, x, "success compareAndExchangeRelease $type$ value"); } { $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact($value2$, $value3$); assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value"); + assertEquals($value1$, x, "failing compareAndExchangeRelease $type$ value"); } { @@ -551,14 +549,14 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, $value2$, "success weakCompareAndSetPlain $type$ value"); + assertEquals($value2$, x, "success weakCompareAndSetPlain $type$ value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact($value1$, $value3$); assertEquals(success, false, "failing weakCompareAndSetPlain $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, $value2$, "failing weakCompareAndSetPlain $type$ value"); + assertEquals($value2$, x, "failing weakCompareAndSetPlain $type$ value"); } { @@ -570,7 +568,7 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, $value1$, "success weakCompareAndSetAcquire $type$"); + assertEquals($value1$, x, "success weakCompareAndSetAcquire $type$"); } { @@ -578,7 +576,7 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { boolean success = (boolean) mh.invokeExact($value2$, $value3$); assertEquals(success, false, "failing weakCompareAndSetAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, $value1$, "failing weakCompareAndSetAcquire $type$ value"); + assertEquals($value1$, x, "failing weakCompareAndSetAcquire $type$ value"); } { @@ -590,14 +588,14 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, $value2$, "success weakCompareAndSetRelease $type$"); + assertEquals($value2$, x, "success weakCompareAndSetRelease $type$"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact($value1$, $value3$); assertEquals(success, false, "failing weakCompareAndSetRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, $value2$, "failing weakCompareAndSetRelease $type$ value"); + assertEquals($value2$, x, "failing weakCompareAndSetRelease $type$ value"); } { @@ -609,14 +607,14 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, $value1$, "success weakCompareAndSet $type$"); + assertEquals($value1$, x, "success weakCompareAndSet $type$"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact($value2$, $value3$); assertEquals(success, false, "failing weakCompareAndSet $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, $value1$, "failing weakCompareAndSetRe $type$ value"); + assertEquals($value1$, x, "failing weakCompareAndSetRe $type$ value"); } // Compare set and get @@ -624,9 +622,9 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact($value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET).invokeExact($value2$); - assertEquals(o, $value1$, "getAndSet $type$"); + assertEquals($value1$, o, "getAndSet $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, $value2$, "getAndSet $type$ value"); + assertEquals($value2$, x, "getAndSet $type$ value"); } // Compare set and get @@ -634,9 +632,9 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact($value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact($value2$); - assertEquals(o, $value1$, "getAndSetAcquire $type$"); + assertEquals($value1$, o, "getAndSetAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, $value2$, "getAndSetAcquire $type$ value"); + assertEquals($value2$, x, "getAndSetAcquire $type$ value"); } // Compare set and get @@ -644,9 +642,9 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact($value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact($value2$); - assertEquals(o, $value1$, "getAndSetRelease $type$"); + assertEquals($value1$, o, "getAndSetRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, $value2$, "getAndSetRelease $type$ value"); + assertEquals($value2$, x, "getAndSetRelease $type$ value"); } #end[CAS] @@ -656,27 +654,27 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact($value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_ADD).invokeExact($value2$); - assertEquals(o, $value1$, "getAndAdd $type$"); + assertEquals($value1$, o, "getAndAdd $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, ($type$)($value1$ + $value2$), "getAndAdd $type$ value"); + assertEquals(($type$)($value1$ + $value2$), x, "getAndAdd $type$ value"); } { hs.get(TestAccessMode.SET).invokeExact($value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact($value2$); - assertEquals(o, $value1$, "getAndAddAcquire $type$"); + assertEquals($value1$, o, "getAndAddAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, ($type$)($value1$ + $value2$), "getAndAddAcquire $type$ value"); + assertEquals(($type$)($value1$ + $value2$), x, "getAndAddAcquire $type$ value"); } { hs.get(TestAccessMode.SET).invokeExact($value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact($value2$); - assertEquals(o, $value1$, "getAndAddRelease $type$"); + assertEquals($value1$, o, "getAndAddRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, ($type$)($value1$ + $value2$), "getAndAddRelease $type$ value"); + assertEquals(($type$)($value1$ + $value2$), x, "getAndAddRelease $type$ value"); } #end[AtomicAdd] @@ -686,27 +684,27 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact($value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_OR).invokeExact($value2$); - assertEquals(o, $value1$, "getAndBitwiseOr $type$"); + assertEquals($value1$, o, "getAndBitwiseOr $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, ($type$)($value1$ | $value2$), "getAndBitwiseOr $type$ value"); + assertEquals(($type$)($value1$ | $value2$), x, "getAndBitwiseOr $type$ value"); } { hs.get(TestAccessMode.SET).invokeExact($value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_OR_ACQUIRE).invokeExact($value2$); - assertEquals(o, $value1$, "getAndBitwiseOrAcquire $type$"); + assertEquals($value1$, o, "getAndBitwiseOrAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, ($type$)($value1$ | $value2$), "getAndBitwiseOrAcquire $type$ value"); + assertEquals(($type$)($value1$ | $value2$), x, "getAndBitwiseOrAcquire $type$ value"); } { hs.get(TestAccessMode.SET).invokeExact($value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_OR_RELEASE).invokeExact($value2$); - assertEquals(o, $value1$, "getAndBitwiseOrRelease $type$"); + assertEquals($value1$, o, "getAndBitwiseOrRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, ($type$)($value1$ | $value2$), "getAndBitwiseOrRelease $type$ value"); + assertEquals(($type$)($value1$ | $value2$), x, "getAndBitwiseOrRelease $type$ value"); } // get and bitwise and @@ -714,27 +712,27 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact($value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_AND).invokeExact($value2$); - assertEquals(o, $value1$, "getAndBitwiseAnd $type$"); + assertEquals($value1$, o, "getAndBitwiseAnd $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, ($type$)($value1$ & $value2$), "getAndBitwiseAnd $type$ value"); + assertEquals(($type$)($value1$ & $value2$), x, "getAndBitwiseAnd $type$ value"); } { hs.get(TestAccessMode.SET).invokeExact($value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_AND_ACQUIRE).invokeExact($value2$); - assertEquals(o, $value1$, "getAndBitwiseAndAcquire $type$"); + assertEquals($value1$, o, "getAndBitwiseAndAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, ($type$)($value1$ & $value2$), "getAndBitwiseAndAcquire $type$ value"); + assertEquals(($type$)($value1$ & $value2$), x, "getAndBitwiseAndAcquire $type$ value"); } { hs.get(TestAccessMode.SET).invokeExact($value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_AND_RELEASE).invokeExact($value2$); - assertEquals(o, $value1$, "getAndBitwiseAndRelease $type$"); + assertEquals($value1$, o, "getAndBitwiseAndRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, ($type$)($value1$ & $value2$), "getAndBitwiseAndRelease $type$ value"); + assertEquals(($type$)($value1$ & $value2$), x, "getAndBitwiseAndRelease $type$ value"); } // get and bitwise xor @@ -742,27 +740,27 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact($value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_XOR).invokeExact($value2$); - assertEquals(o, $value1$, "getAndBitwiseXor $type$"); + assertEquals($value1$, o, "getAndBitwiseXor $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, ($type$)($value1$ ^ $value2$), "getAndBitwiseXor $type$ value"); + assertEquals(($type$)($value1$ ^ $value2$), x, "getAndBitwiseXor $type$ value"); } { hs.get(TestAccessMode.SET).invokeExact($value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_ACQUIRE).invokeExact($value2$); - assertEquals(o, $value1$, "getAndBitwiseXorAcquire $type$"); + assertEquals($value1$, o, "getAndBitwiseXorAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, ($type$)($value1$ ^ $value2$), "getAndBitwiseXorAcquire $type$ value"); + assertEquals(($type$)($value1$ ^ $value2$), x, "getAndBitwiseXorAcquire $type$ value"); } { hs.get(TestAccessMode.SET).invokeExact($value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_RELEASE).invokeExact($value2$); - assertEquals(o, $value1$, "getAndBitwiseXorRelease $type$"); + assertEquals($value1$, o, "getAndBitwiseXorRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, ($type$)($value1$ ^ $value2$), "getAndBitwiseXorRelease $type$ value"); + assertEquals(($type$)($value1$ ^ $value2$), x, "getAndBitwiseXorRelease $type$ value"); } #end[Bitwise] } @@ -814,7 +812,7 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { { hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, $value1$, "get $type$ value"); + assertEquals($value1$, x, "get $type$ value"); } @@ -822,21 +820,21 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { { hs.get(TestAccessMode.SET_VOLATILE).invokeExact(array, i, $value2$); $type$ x = ($type$) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(array, i); - assertEquals(x, $value2$, "setVolatile $type$ value"); + assertEquals($value2$, x, "setVolatile $type$ value"); } // Lazy { hs.get(TestAccessMode.SET_RELEASE).invokeExact(array, i, $value1$); $type$ x = ($type$) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(array, i); - assertEquals(x, $value1$, "setRelease $type$ value"); + assertEquals($value1$, x, "setRelease $type$ value"); } // Opaque { hs.get(TestAccessMode.SET_OPAQUE).invokeExact(array, i, $value2$); $type$ x = ($type$) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(array, i); - assertEquals(x, $value2$, "setOpaque $type$ value"); + assertEquals($value2$, x, "setOpaque $type$ value"); } #if[CAS] @@ -847,56 +845,56 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, $value1$, $value2$); assertEquals(r, true, "success compareAndSet $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, $value2$, "success compareAndSet $type$ value"); + assertEquals($value2$, x, "success compareAndSet $type$ value"); } { boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, $value1$, $value3$); assertEquals(r, false, "failing compareAndSet $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, $value2$, "failing compareAndSet $type$ value"); + assertEquals($value2$, x, "failing compareAndSet $type$ value"); } { $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, $value2$, $value1$); assertEquals(r, $value2$, "success compareAndExchange $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, $value1$, "success compareAndExchange $type$ value"); + assertEquals($value1$, x, "success compareAndExchange $type$ value"); } { $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, $value2$, $value3$); assertEquals(r, $value1$, "failing compareAndExchange $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, $value1$, "failing compareAndExchange $type$ value"); + assertEquals($value1$, x, "failing compareAndExchange $type$ value"); } { $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, $value1$, $value2$); assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value"); + assertEquals($value2$, x, "success compareAndExchangeAcquire $type$ value"); } { $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, $value1$, $value3$); assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value"); + assertEquals($value2$, x, "failing compareAndExchangeAcquire $type$ value"); } { $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, $value2$, $value1$); assertEquals(r, $value2$, "success compareAndExchangeRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value"); + assertEquals($value1$, x, "success compareAndExchangeRelease $type$ value"); } { $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, $value2$, $value3$); assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value"); + assertEquals($value1$, x, "failing compareAndExchangeRelease $type$ value"); } { @@ -908,14 +906,14 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetPlain $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, $value2$, "success weakCompareAndSetPlain $type$ value"); + assertEquals($value2$, x, "success weakCompareAndSetPlain $type$ value"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, $value1$, $value3$); assertEquals(success, false, "failing weakCompareAndSetPlain $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, $value2$, "failing weakCompareAndSetPlain $type$ value"); + assertEquals($value2$, x, "failing weakCompareAndSetPlain $type$ value"); } { @@ -927,14 +925,14 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, $value1$, "success weakCompareAndSetAcquire $type$"); + assertEquals($value1$, x, "success weakCompareAndSetAcquire $type$"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, $value2$, $value3$); assertEquals(success, false, "failing weakCompareAndSetAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, $value1$, "failing weakCompareAndSetAcquire $type$ value"); + assertEquals($value1$, x, "failing weakCompareAndSetAcquire $type$ value"); } { @@ -946,14 +944,14 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSetRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, $value2$, "success weakCompareAndSetRelease $type$"); + assertEquals($value2$, x, "success weakCompareAndSetRelease $type$"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, $value1$, $value3$); assertEquals(success, false, "failing weakCompareAndSetAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, $value2$, "failing weakCompareAndSetAcquire $type$ value"); + assertEquals($value2$, x, "failing weakCompareAndSetAcquire $type$ value"); } { @@ -965,14 +963,14 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { } assertEquals(success, true, "success weakCompareAndSet $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, $value1$, "success weakCompareAndSet $type$"); + assertEquals($value1$, x, "success weakCompareAndSet $type$"); } { boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, $value2$, $value3$); assertEquals(success, false, "failing weakCompareAndSet $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, $value1$, "failing weakCompareAndSet $type$ value"); + assertEquals($value1$, x, "failing weakCompareAndSet $type$ value"); } // Compare set and get @@ -980,27 +978,27 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, $value2$); - assertEquals(o, $value1$, "getAndSet $type$"); + assertEquals($value1$, o, "getAndSet $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, $value2$, "getAndSet $type$ value"); + assertEquals($value2$, x, "getAndSet $type$ value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact(array, i, $value2$); - assertEquals(o, $value1$, "getAndSetAcquire $type$"); + assertEquals($value1$, o, "getAndSetAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, $value2$, "getAndSetAcquire $type$ value"); + assertEquals($value2$, x, "getAndSetAcquire $type$ value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact(array, i, $value2$); - assertEquals(o, $value1$, "getAndSetRelease $type$"); + assertEquals($value1$, o, "getAndSetRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, $value2$, "getAndSetRelease $type$ value"); + assertEquals($value2$, x, "getAndSetRelease $type$ value"); } #end[CAS] @@ -1010,27 +1008,27 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(array, i, $value2$); - assertEquals(o, $value1$, "getAndAdd $type$"); + assertEquals($value1$, o, "getAndAdd $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, ($type$)($value1$ + $value2$), "getAndAdd $type$ value"); + assertEquals(($type$)($value1$ + $value2$), x, "getAndAdd $type$ value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact(array, i, $value2$); - assertEquals(o, $value1$, "getAndAddAcquire $type$"); + assertEquals($value1$, o, "getAndAddAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, ($type$)($value1$ + $value2$), "getAndAddAcquire $type$ value"); + assertEquals(($type$)($value1$ + $value2$), x, "getAndAddAcquire $type$ value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact(array, i, $value2$); - assertEquals(o, $value1$, "getAndAddRelease $type$"); + assertEquals($value1$, o, "getAndAddRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, ($type$)($value1$ + $value2$), "getAndAddRelease $type$ value"); + assertEquals(($type$)($value1$ + $value2$), x, "getAndAddRelease $type$ value"); } #end[AtomicAdd] @@ -1040,27 +1038,27 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_OR).invokeExact(array, i, $value2$); - assertEquals(o, $value1$, "getAndBitwiseOr $type$"); + assertEquals($value1$, o, "getAndBitwiseOr $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, ($type$)($value1$ | $value2$), "getAndBitwiseOr $type$ value"); + assertEquals(($type$)($value1$ | $value2$), x, "getAndBitwiseOr $type$ value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_OR_ACQUIRE).invokeExact(array, i, $value2$); - assertEquals(o, $value1$, "getAndBitwiseOrAcquire $type$"); + assertEquals($value1$, o, "getAndBitwiseOrAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, ($type$)($value1$ | $value2$), "getAndBitwiseOrAcquire $type$ value"); + assertEquals(($type$)($value1$ | $value2$), x, "getAndBitwiseOrAcquire $type$ value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_OR_RELEASE).invokeExact(array, i, $value2$); - assertEquals(o, $value1$, "getAndBitwiseOrRelease $type$"); + assertEquals($value1$, o, "getAndBitwiseOrRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, ($type$)($value1$ | $value2$), "getAndBitwiseOrRelease $type$ value"); + assertEquals(($type$)($value1$ | $value2$), x, "getAndBitwiseOrRelease $type$ value"); } // get and bitwise and @@ -1068,27 +1066,27 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_AND).invokeExact(array, i, $value2$); - assertEquals(o, $value1$, "getAndBitwiseAnd $type$"); + assertEquals($value1$, o, "getAndBitwiseAnd $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, ($type$)($value1$ & $value2$), "getAndBitwiseAnd $type$ value"); + assertEquals(($type$)($value1$ & $value2$), x, "getAndBitwiseAnd $type$ value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_AND_ACQUIRE).invokeExact(array, i, $value2$); - assertEquals(o, $value1$, "getAndBitwiseAndAcquire $type$"); + assertEquals($value1$, o, "getAndBitwiseAndAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, ($type$)($value1$ & $value2$), "getAndBitwiseAndAcquire $type$ value"); + assertEquals(($type$)($value1$ & $value2$), x, "getAndBitwiseAndAcquire $type$ value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_AND_RELEASE).invokeExact(array, i, $value2$); - assertEquals(o, $value1$, "getAndBitwiseAndRelease $type$"); + assertEquals($value1$, o, "getAndBitwiseAndRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, ($type$)($value1$ & $value2$), "getAndBitwiseAndRelease $type$ value"); + assertEquals(($type$)($value1$ & $value2$), x, "getAndBitwiseAndRelease $type$ value"); } // get and bitwise xor @@ -1096,27 +1094,27 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_XOR).invokeExact(array, i, $value2$); - assertEquals(o, $value1$, "getAndBitwiseXor $type$"); + assertEquals($value1$, o, "getAndBitwiseXor $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, ($type$)($value1$ ^ $value2$), "getAndBitwiseXor $type$ value"); + assertEquals(($type$)($value1$ ^ $value2$), x, "getAndBitwiseXor $type$ value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_ACQUIRE).invokeExact(array, i, $value2$); - assertEquals(o, $value1$, "getAndBitwiseXorAcquire $type$"); + assertEquals($value1$, o, "getAndBitwiseXorAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, ($type$)($value1$ ^ $value2$), "getAndBitwiseXorAcquire $type$ value"); + assertEquals(($type$)($value1$ ^ $value2$), x, "getAndBitwiseXorAcquire $type$ value"); } { hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$); $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_RELEASE).invokeExact(array, i, $value2$); - assertEquals(o, $value1$, "getAndBitwiseXorRelease $type$"); + assertEquals($value1$, o, "getAndBitwiseXorRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, ($type$)($value1$ ^ $value2$), "getAndBitwiseXorRelease $type$ value"); + assertEquals(($type$)($value1$ ^ $value2$), x, "getAndBitwiseXorRelease $type$ value"); } #end[Bitwise] } diff --git a/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestMethodType.java.template b/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestMethodType.java.template index 85ecf9bb95c..77531cc309f 100644 --- a/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestMethodType.java.template +++ b/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestMethodType.java.template @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,26 +24,26 @@ /* * @test * @bug 8156486 - * @run testng/othervm VarHandleTestMethodType$Type$ - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=true -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodType$Type$ - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=false VarHandleTestMethodType$Type$ - * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodType$Type$ + * @run junit/othervm VarHandleTestMethodType$Type$ + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=true -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodType$Type$ + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=false VarHandleTestMethodType$Type$ + * @run junit/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true VarHandleTestMethodType$Type$ */ -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static org.testng.Assert.*; - import static java.lang.invoke.MethodType.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VarHandleTestMethodType$Type$ extends VarHandleBaseTest { static final $type$ static_final_v = $value1$; @@ -63,7 +63,7 @@ public class VarHandleTestMethodType$Type$ extends VarHandleBaseTest { VarHandle vhArray; - @BeforeClass + @BeforeAll public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestMethodType$Type$.class, "final_v", $type$.class); @@ -80,7 +80,6 @@ public class VarHandleTestMethodType$Type$ extends VarHandleBaseTest { vhArray = MethodHandles.arrayElementVarHandle($type$[].class); } - @DataProvider public Object[][] accessTestCaseProvider() throws Exception { List> cases = new ArrayList<>(); @@ -115,7 +114,8 @@ public class VarHandleTestMethodType$Type$ extends VarHandleBaseTest { return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); } - @Test(dataProvider = "accessTestCaseProvider") + @ParameterizedTest + @MethodSource("accessTestCaseProvider") public void testAccess(String desc, AccessTestCase atc) throws Throwable { T t = atc.get(); int iters = atc.requiresLoop() ? ITERS : 1; @@ -124,7 +124,6 @@ public class VarHandleTestMethodType$Type$ extends VarHandleBaseTest { } } - static void testInstanceFieldWrongMethodType(VarHandleTestMethodType$Type$ recv, VarHandle vh) throws Throwable { // Get // Incorrect argument types diff --git a/test/jdk/java/lang/invoke/VarHandles/accessibility/TestFieldLookupAccessibility.java b/test/jdk/java/lang/invoke/VarHandles/accessibility/TestFieldLookupAccessibility.java index 343b15a1caf..11cd6ec233c 100644 --- a/test/jdk/java/lang/invoke/VarHandles/accessibility/TestFieldLookupAccessibility.java +++ b/test/jdk/java/lang/invoke/VarHandles/accessibility/TestFieldLookupAccessibility.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,14 +27,11 @@ * @compile TestFieldLookupAccessibility.java * pkg/A.java pkg/B_extends_A.java pkg/C.java * pkg/subpkg/B_extends_A.java pkg/subpkg/C.java - * @run testng/othervm --enable-final-field-mutation=ALL-UNNAMED -DwriteAccess=true TestFieldLookupAccessibility - * @run testng/othervm --illegal-final-field-mutation=deny -DwriteAccess=false TestFieldLookupAccessibility + * @run junit/othervm --enable-final-field-mutation=ALL-UNNAMED -DwriteAccess=true TestFieldLookupAccessibility + * @run junit/othervm --illegal-final-field-mutation=deny -DwriteAccess=false TestFieldLookupAccessibility */ -import static org.testng.Assert.*; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; +import static org.junit.jupiter.api.Assertions.*; import pkg.B_extends_A; import java.lang.invoke.MethodHandles; @@ -48,11 +45,14 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; public class TestFieldLookupAccessibility { static boolean writeAccess; - @BeforeClass + @BeforeAll static void setup() { String s = System.getProperty("writeAccess"); assertNotNull(s); @@ -188,8 +188,7 @@ public class TestFieldLookupAccessibility { } } - @DataProvider - public Object[][] lookupProvider() throws Exception { + public static Object[][] lookupProvider() throws Exception { Stream> baseCases = Stream.of( // Look up from same package List.of(pkg.A.class, pkg.A.lookup(), pkg.A.inaccessibleFields()), @@ -215,7 +214,8 @@ public class TestFieldLookupAccessibility { return pl.toArray(); } - @Test(dataProvider = "lookupProvider") + @ParameterizedTest + @MethodSource("lookupProvider") public void test(FieldLookup fl, Class src, MethodHandles.Lookup l, Set inaccessibleFields) { // Add to the expected failures all inaccessible fields due to accessibility modifiers Set expected = fl.inaccessibleFields(inaccessibleFields); @@ -240,10 +240,10 @@ public class TestFieldLookupAccessibility { collect(Collectors.toSet()); if (!actualFieldNames.equals(expected)) { if (actualFieldNames.isEmpty()) { - assertEquals(actualFieldNames, expected, "No accessibility failures:"); + assertEquals(expected, actualFieldNames, "No accessibility failures:"); } else { - assertEquals(actualFieldNames, expected, "Accessibility failures differ:"); + assertEquals(expected, actualFieldNames, "Accessibility failures differ:"); } } else { diff --git a/test/jdk/java/lang/invoke/WrongMethodTypeTest.java b/test/jdk/java/lang/invoke/WrongMethodTypeTest.java index be0c59e0d77..32cbfc545ce 100644 --- a/test/jdk/java/lang/invoke/WrongMethodTypeTest.java +++ b/test/jdk/java/lang/invoke/WrongMethodTypeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,8 +21,9 @@ * questions. */ -/* @test 8299183 - * @run testng WrongMethodTypeTest +/* @test + * @bug 8299183 + * @run junit WrongMethodTypeTest */ import java.lang.invoke.MethodHandle; @@ -33,9 +34,10 @@ import java.lang.invoke.WrongMethodTypeException; import static java.lang.invoke.MethodType.methodType; -import static org.testng.AssertJUnit.*; +import org.junit.jupiter.api.Test; -import org.testng.annotations.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; public class WrongMethodTypeTest { static final Lookup LOOKUP = MethodHandles.lookup(); @@ -43,13 +45,11 @@ public class WrongMethodTypeTest { @Test public void checkExactType() throws Throwable { String expectedMessage = "handle's method type (int)int but found ()boolean"; - try { - MethodHandle mh = LOOKUP.findStatic(WrongMethodTypeTest.class, "m", methodType(int.class, int.class)); + MethodHandle mh = LOOKUP.findStatic(WrongMethodTypeTest.class, "m", methodType(int.class, int.class)); + var ex = assertThrows(WrongMethodTypeException.class, () -> { boolean b = (boolean)mh.invokeExact(); - fail("Expected WrongMethodTypeException"); - } catch (WrongMethodTypeException ex) { - assertEquals(expectedMessage, ex.getMessage()); - } + }); + assertEquals(expectedMessage, ex.getMessage()); } @Test @@ -57,11 +57,10 @@ public class WrongMethodTypeTest { String expectedMessage = "handle's method type ()int but found ()Void"; VarHandle vh = LOOKUP.findStaticVarHandle(WrongMethodTypeTest.class, "x", int.class) .withInvokeExactBehavior(); - try { + var ex = assertThrows(WrongMethodTypeException.class, () -> { Void o = (Void) vh.get(); - } catch (WrongMethodTypeException ex) { - assertEquals(expectedMessage, ex.getMessage()); - } + }); + assertEquals(expectedMessage, ex.getMessage()); } @Test @@ -69,11 +68,10 @@ public class WrongMethodTypeTest { String expectedMessage = "handle's method type (WrongMethodTypeTest)boolean but found (WrongMethodTypeTest)int"; VarHandle vh = LOOKUP.findVarHandle(WrongMethodTypeTest.class, "y", boolean.class) .withInvokeExactBehavior(); - try { + var ex = assertThrows(WrongMethodTypeException.class, () -> { int o = (int) vh.get(new WrongMethodTypeTest()); - } catch (WrongMethodTypeException ex) { - assertEquals(expectedMessage, ex.getMessage()); - } + }); + assertEquals(expectedMessage, ex.getMessage()); } static int m(int x) { diff --git a/test/jdk/java/lang/invoke/accessClassAndFindClass/TestAccessClass.java b/test/jdk/java/lang/invoke/accessClassAndFindClass/TestAccessClass.java index 083a357a430..23893655c0a 100644 --- a/test/jdk/java/lang/invoke/accessClassAndFindClass/TestAccessClass.java +++ b/test/jdk/java/lang/invoke/accessClassAndFindClass/TestAccessClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /* @test * @bug 8150782 8207027 8266269 * @compile TestAccessClass.java TestCls.java p/Foo.java q/Bar.java - * @run testng/othervm -ea -esa test.java.lang.invoke.TestAccessClass + * @run junit/othervm -ea -esa test.java.lang.invoke.TestAccessClass */ package test.java.lang.invoke; @@ -36,9 +36,11 @@ import q.Bar; import static java.lang.invoke.MethodHandles.*; -import static org.testng.AssertJUnit.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; -import org.testng.annotations.*; +import static org.junit.jupiter.api.Assertions.*; public class TestAccessClass { @@ -68,17 +70,19 @@ public class TestAccessClass { assertEquals(Class1[].class, aClass); } - @DataProvider - Object[][] illegalAccessAccess() { + static Object[][] illegalAccessAccess() { return new Object[][] { {publicLookup(), Class1.class}, {publicLookup(), TestCls.getPrivateSIC()} }; } - @Test(dataProvider = "illegalAccessAccess", expectedExceptions = {IllegalAccessException.class}) + @ParameterizedTest + @MethodSource("illegalAccessAccess") public void illegalAccessExceptionTest(Lookup lookup, Class klass) throws IllegalAccessException { - lookup.accessClass(klass); + assertThrows(IllegalAccessException.class, () -> { + lookup.accessClass(klass); + }); } @Test @@ -98,8 +102,8 @@ public class TestAccessClass { mh.invoke(null); } - @Test(expectedExceptions = {NullPointerException.class}) + @Test public void illegalArgument() throws IllegalAccessException { - lookup().accessClass(null); + assertThrows(NullPointerException.class, () -> lookup().accessClass(null)); } } diff --git a/test/jdk/java/lang/invoke/accessClassAndFindClass/TestFindClass.java b/test/jdk/java/lang/invoke/accessClassAndFindClass/TestFindClass.java index 54674729fe3..94ec3c54b4f 100644 --- a/test/jdk/java/lang/invoke/accessClassAndFindClass/TestFindClass.java +++ b/test/jdk/java/lang/invoke/accessClassAndFindClass/TestFindClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /* @test * @bug 8150782 8207027 8266269 * @compile TestFindClass.java TestCls.java p/Foo.java q/Bar.java - * @run testng/othervm -ea -esa test.java.lang.invoke.TestFindClass + * @run junit/othervm -ea -esa test.java.lang.invoke.TestFindClass */ package test.java.lang.invoke; @@ -34,9 +34,11 @@ import q.Bar; import static java.lang.invoke.MethodHandles.*; -import static org.testng.AssertJUnit.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; -import org.testng.annotations.*; +import static org.junit.jupiter.api.Assertions.*; public class TestFindClass { @@ -68,13 +70,12 @@ public class TestFindClass { assertEquals(Class1[].class, aClass); } - @Test(expectedExceptions = {ClassNotFoundException.class}) + @Test public void classNotFoundExceptionTest() throws IllegalAccessException, ClassNotFoundException { - lookup().findClass(PACKAGE_PREFIX + "TestFindClass$NonExistent"); + assertThrows(ClassNotFoundException.class, () -> lookup().findClass(PACKAGE_PREFIX + "TestFindClass$NonExistent")); } - @DataProvider - Object[][] illegalAccessFind() { + static Object[][] illegalAccessFind() { return new Object[][] { {publicLookup(), PACKAGE_PREFIX + "TestFindClass$Class1"}, {publicLookup(), PACKAGE_PREFIX + "TestCls$PrivateSIC"} @@ -84,9 +85,10 @@ public class TestFindClass { /** * Assertion: @throws IllegalAccessException if the class is not accessible, using the allowed access modes. */ - @Test(dataProvider = "illegalAccessFind", expectedExceptions = {ClassNotFoundException.class}) + @ParameterizedTest + @MethodSource("illegalAccessFind") public void illegalAccessExceptionTest(Lookup lookup, String className) throws IllegalAccessException, ClassNotFoundException { - lookup.findClass(className); + assertThrows(ClassNotFoundException.class, () -> lookup.findClass(className)); } @Test @@ -104,8 +106,8 @@ public class TestFindClass { lookup().findClass("[Lp.Foo$T;"); } - @Test(expectedExceptions = {NullPointerException.class}) + @Test public void illegalArgument() throws IllegalAccessException, ClassNotFoundException { - lookup().findClass(null); + assertThrows(NullPointerException.class, () -> lookup().findClass(null)); } } diff --git a/test/jdk/java/lang/invoke/accessClassAndFindClass/TestLookup.java b/test/jdk/java/lang/invoke/accessClassAndFindClass/TestLookup.java index 555213bedcc..b0f2e00adbc 100644 --- a/test/jdk/java/lang/invoke/accessClassAndFindClass/TestLookup.java +++ b/test/jdk/java/lang/invoke/accessClassAndFindClass/TestLookup.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,15 +23,15 @@ /* @test * @compile TestLookup.java TestCls.java - * @run testng/othervm -ea -esa test.java.lang.invoke.TestLookup + * @run junit/othervm -ea -esa test.java.lang.invoke.TestLookup */ package test.java.lang.invoke; -import org.testng.annotations.Test; - import static java.lang.invoke.MethodHandles.*; -import static org.testng.AssertJUnit.*; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; public class TestLookup { @@ -43,10 +43,10 @@ public class TestLookup { assertNull(lookup2.lookupClass().getClassLoader()); } - @Test(expectedExceptions = {ClassNotFoundException.class}) + @Test public void testPublicCannotLoadUserClass() throws IllegalAccessException, ClassNotFoundException { Lookup lookup = publicLookup(); - lookup.findClass("test.java.lang.invoke.TestCls"); + assertThrows(ClassNotFoundException.class, () -> lookup.findClass("test.java.lang.invoke.TestCls")); } @Test diff --git a/test/jdk/java/lang/invoke/callerSensitive/CallerSensitiveAccess.java b/test/jdk/java/lang/invoke/callerSensitive/CallerSensitiveAccess.java index a6359162629..67aa90ba99c 100644 --- a/test/jdk/java/lang/invoke/callerSensitive/CallerSensitiveAccess.java +++ b/test/jdk/java/lang/invoke/callerSensitive/CallerSensitiveAccess.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /* @test * @bug 8196830 8235351 8257874 * @modules java.base/jdk.internal.reflect - * @run testng/othervm CallerSensitiveAccess + * @run junit/othervm CallerSensitiveAccess * @summary Check Lookup findVirtual, findStatic and unreflect behavior with * caller sensitive methods with focus on AccessibleObject.setAccessible */ @@ -50,17 +50,16 @@ import java.util.stream.Stream; import jdk.internal.reflect.CallerSensitive; -import org.testng.annotations.DataProvider; -import org.testng.annotations.NoInjection; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; public class CallerSensitiveAccess { /** * Caller sensitive methods in APIs exported by java.base. */ - @DataProvider(name = "callerSensitiveMethods") static Object[][] callerSensitiveMethods() { try (Stream stream = callerSensitiveMethods(Object.class.getModule())) { return stream.map(m -> new Object[]{m, shortDescription(m)}) @@ -72,34 +71,35 @@ public class CallerSensitiveAccess { * Using publicLookup, attempt to use findVirtual or findStatic to obtain a * method handle to a caller sensitive method. */ - @Test(dataProvider = "callerSensitiveMethods", - expectedExceptions = IllegalAccessException.class) - public void testPublicLookupFind(@NoInjection Method method, String desc) throws Exception { + @ParameterizedTest + @MethodSource("callerSensitiveMethods") + public void testPublicLookupFind(Method method, String desc) throws Exception { Lookup lookup = MethodHandles.publicLookup(); Class refc = method.getDeclaringClass(); String name = method.getName(); MethodType mt = MethodType.methodType(method.getReturnType(), method.getParameterTypes()); - if (Modifier.isStatic(method.getModifiers())) { - lookup.findStatic(refc, name, mt); - } else { - lookup.findVirtual(refc, name, mt); - } + assertThrows(IllegalAccessException.class, () -> { + if (Modifier.isStatic(method.getModifiers())) { + lookup.findStatic(refc, name, mt); + } else { + lookup.findVirtual(refc, name, mt); + } + }); } /** * Using publicLookup, attempt to use unreflect to obtain a method handle to a * caller sensitive method. */ - @Test(dataProvider = "callerSensitiveMethods", - expectedExceptions = IllegalAccessException.class) - public void testPublicLookupUnreflect(@NoInjection Method method, String desc) throws Exception { - MethodHandles.publicLookup().unreflect(method); + @ParameterizedTest + @MethodSource("callerSensitiveMethods") + public void testPublicLookupUnreflect(Method method, String desc) throws Exception { + assertThrows(IllegalAccessException.class, () -> MethodHandles.publicLookup().unreflect(method)); } /** * public accessible caller sensitive methods in APIs exported by java.base. */ - @DataProvider(name = "accessibleCallerSensitiveMethods") static Object[][] accessibleCallerSensitiveMethods() { try (Stream stream = callerSensitiveMethods(Object.class.getModule())) { return stream @@ -114,41 +114,43 @@ public class CallerSensitiveAccess { * Using publicLookup, attempt to use unreflect to obtain a method handle to a * caller sensitive method. */ - @Test(dataProvider = "accessibleCallerSensitiveMethods", - expectedExceptions = IllegalAccessException.class) - public void testLookupUnreflect(@NoInjection Method method, String desc) throws Exception { - MethodHandles.publicLookup().unreflect(method); + @ParameterizedTest + @MethodSource("accessibleCallerSensitiveMethods") + public void testLookupUnreflect(Method method, String desc) throws Exception { + assertThrows(IllegalAccessException.class, () -> MethodHandles.publicLookup().unreflect(method)); } /** * Using a Lookup with no original access that can't lookup caller-sensitive * method */ - @Test(dataProvider = "callerSensitiveMethods", - expectedExceptions = IllegalAccessException.class) - public void testLookupNoOriginalAccessFind(@NoInjection Method method, String desc) throws Exception { + @ParameterizedTest + @MethodSource("callerSensitiveMethods") + public void testLookupNoOriginalAccessFind(Method method, String desc) throws Exception { Lookup lookup = MethodHandles.lookup().dropLookupMode(Lookup.ORIGINAL); assertTrue(lookup.hasFullPrivilegeAccess()); Class refc = method.getDeclaringClass(); String name = method.getName(); MethodType mt = MethodType.methodType(method.getReturnType(), method.getParameterTypes()); - if (Modifier.isStatic(method.getModifiers())) { - lookup.findStatic(refc, name, mt); - } else { - lookup.findVirtual(refc, name, mt); - } + assertThrows(IllegalAccessException.class, () -> { + if (Modifier.isStatic(method.getModifiers())) { + lookup.findStatic(refc, name, mt); + } else { + lookup.findVirtual(refc, name, mt); + } + }); } /** * Using a Lookup with no original access that can't unreflect caller-sensitive * method */ - @Test(dataProvider = "callerSensitiveMethods", - expectedExceptions = IllegalAccessException.class) - public void testLookupNoOriginalAccessUnreflect(@NoInjection Method method, String desc) throws Exception { + @ParameterizedTest + @MethodSource("callerSensitiveMethods") + public void testLookupNoOriginalAccessUnreflect(Method method, String desc) throws Exception { Lookup lookup = MethodHandles.lookup().dropLookupMode(Lookup.ORIGINAL); assertTrue(lookup.hasFullPrivilegeAccess()); - lookup.unreflect(method); + assertThrows(IllegalAccessException.class, () -> lookup.unreflect(method)); } // -- Test method handles to setAccessible -- @@ -156,21 +158,12 @@ public class CallerSensitiveAccess { private int aField; Field accessibleField() { - try { - return getClass().getDeclaredField("aField"); - } catch (NoSuchFieldException e) { - fail(); - return null; - } + var clazz = getClass(); + return assertDoesNotThrow(() -> clazz.getDeclaredField("aField")); } Field inaccessibleField() { - try { - return String.class.getDeclaredField("hash"); - } catch (NoSuchFieldException e) { - fail(); - return null; - } + return assertDoesNotThrow(() -> String.class.getDeclaredField("hash")); } void findAndInvokeSetAccessible(Class refc, Field f) throws Throwable { @@ -215,23 +208,23 @@ public class CallerSensitiveAccess { * Create a method handle to setAccessible and attempt to use it to suppress * access to an inaccessible member. */ - @Test(expectedExceptions = InaccessibleObjectException.class) + @Test public void testSetAccessible5() throws Throwable { - findAndInvokeSetAccessible(AccessibleObject.class, inaccessibleField()); + assertThrows(InaccessibleObjectException.class, () -> findAndInvokeSetAccessible(AccessibleObject.class, inaccessibleField())); } - @Test(expectedExceptions = InaccessibleObjectException.class) + @Test public void testSetAccessible6() throws Throwable { - findAndInvokeSetAccessible(Field.class, inaccessibleField()); + assertThrows(InaccessibleObjectException.class, () -> findAndInvokeSetAccessible(Field.class, inaccessibleField())); } - @Test(expectedExceptions = InaccessibleObjectException.class) + @Test public void testSetAccessible7() throws Throwable { Method m = AccessibleObject.class.getMethod("setAccessible", boolean.class); - unreflectAndInvokeSetAccessible(m, inaccessibleField()); + assertThrows(InaccessibleObjectException.class, () -> unreflectAndInvokeSetAccessible(m, inaccessibleField())); } - @Test(expectedExceptions = InaccessibleObjectException.class) + @Test public void testSetAccessible8() throws Throwable { Method m = Field.class.getMethod("setAccessible", boolean.class); - unreflectAndInvokeSetAccessible(m, inaccessibleField()); + assertThrows(InaccessibleObjectException.class, () -> unreflectAndInvokeSetAccessible(m, inaccessibleField())); } @@ -241,7 +234,6 @@ public class CallerSensitiveAccess { * Custom AccessibleObject objects. One class overrides setAccessible, the other * does not override this method. */ - @DataProvider(name = "customAccessibleObjects") static Object[][] customAccessibleObjectClasses() { return new Object[][] { { new S1() }, { new S2() } }; } @@ -271,20 +263,20 @@ public class CallerSensitiveAccess { * Using publicLookup, create a method handle to setAccessible and invoke it * on a custom AccessibleObject object. */ - @Test(expectedExceptions = IllegalAccessException.class) + @Test public void testPublicLookupSubclass1() throws Throwable { // S1 does not override setAccessible - findAndInvokeSetAccessible(MethodHandles.publicLookup(), new S1()); + assertThrows(IllegalAccessException.class, () -> findAndInvokeSetAccessible(MethodHandles.publicLookup(), new S1())); } @Test public void testPublicLookupSubclass2() throws Throwable { // S2 overrides setAccessible findAndInvokeSetAccessible(MethodHandles.publicLookup(), new S2()); } - @Test(expectedExceptions = IllegalAccessException.class) + @Test public void testPublicLookupSubclass3() throws Throwable { // S1 does not override setAccessible - unreflectAndInvokeSetAccessible(MethodHandles.publicLookup(), new S1()); + assertThrows(IllegalAccessException.class, () -> unreflectAndInvokeSetAccessible(MethodHandles.publicLookup(), new S1())); } @Test public void testPublicLookupSubclass4() throws Throwable { @@ -296,11 +288,13 @@ public class CallerSensitiveAccess { * Using a full power lookup, create a method handle to setAccessible and * invoke it on a custom AccessibleObject object. */ - @Test(dataProvider = "customAccessibleObjects") + @ParameterizedTest + @MethodSource("customAccessibleObjectClasses") public void testLookupSubclass1(AccessibleObject obj) throws Throwable { findAndInvokeSetAccessible(MethodHandles.lookup(), obj); } - @Test(dataProvider = "customAccessibleObjects") + @ParameterizedTest + @MethodSource("customAccessibleObjectClasses") public void testLookupSubclass2(AccessibleObject obj) throws Throwable { unreflectAndInvokeSetAccessible(MethodHandles.lookup(), obj); } @@ -309,13 +303,13 @@ public class CallerSensitiveAccess { * Using a full power lookup, create a method handle to setAccessible on a * sub-class of AccessibleObject and then attempt to invoke it on a Field object. */ - @Test(dataProvider = "customAccessibleObjects", - expectedExceptions = ClassCastException.class) + @ParameterizedTest + @MethodSource("customAccessibleObjectClasses") public void testLookupSubclass3(AccessibleObject obj) throws Throwable { MethodType mt = MethodType.methodType(void.class, boolean.class); Lookup lookup = MethodHandles.lookup(); MethodHandle mh = lookup.findVirtual(obj.getClass(), "setAccessible", mt); - mh.invoke(accessibleField(), true); // should throw ClassCastException + assertThrows(ClassCastException.class, () -> mh.invoke(accessibleField(), true)); } /** @@ -333,29 +327,29 @@ public class CallerSensitiveAccess { mh.invoke(f, true); assertTrue(f.isAccessible()); } - @Test(expectedExceptions = InaccessibleObjectException.class) + @Test public void testLookupSubclass5() throws Throwable { // S1 does not override setAccessible Method m = S1.class.getMethod("setAccessible", boolean.class); assertTrue(m.getDeclaringClass() == AccessibleObject.class); MethodHandle mh = MethodHandles.lookup().unreflect(m); - mh.invoke(inaccessibleField(), true); // should throw InaccessibleObjectException + assertThrows(InaccessibleObjectException.class, () -> mh.invoke(inaccessibleField(), true)); } - @Test(expectedExceptions = ClassCastException.class) + @Test public void testLookupSubclass6() throws Throwable { // S2 overrides setAccessible Method m = S2.class.getMethod("setAccessible", boolean.class); assertTrue(m.getDeclaringClass() == S2.class); MethodHandle mh = MethodHandles.lookup().unreflect(m); - mh.invoke(accessibleField(), true); // should throw ClassCastException + assertThrows(ClassCastException.class, () -> mh.invoke(accessibleField(), true)); } - @Test(expectedExceptions = ClassCastException.class) + @Test public void testLookupSubclass7() throws Throwable { // S2 overrides setAccessible Method m = S2.class.getMethod("setAccessible", boolean.class); assertTrue(m.getDeclaringClass() == S2.class); MethodHandle mh = MethodHandles.lookup().unreflect(m); - mh.invoke(inaccessibleField(), true); // should throw ClassCastException + assertThrows(ClassCastException.class, () -> mh.invoke(inaccessibleField(), true)); } /** @@ -373,7 +367,7 @@ public class CallerSensitiveAccess { // Field::getInt mh = MethodHandles.lookup().findVirtual(Field.class, "getInt", MethodType.methodType(int.class, Object.class)); int value = (int)mh.invokeExact(f, (Object)null); - assertTrue(value == 5); + assertEquals(5, value); } private static class Inner { @@ -400,7 +394,7 @@ public class CallerSensitiveAccess { * exported by a named module. */ static Stream callerSensitiveMethods(Module module) { - assert module.isNamed(); + assertTrue(module.isNamed()); ModuleReference mref = module.getLayer().configuration() .findModule(module.getName()) .orElseThrow(() -> new RuntimeException()) diff --git a/test/jdk/java/lang/invoke/condy/BootstrapMethodJumboArgsTest.java b/test/jdk/java/lang/invoke/condy/BootstrapMethodJumboArgsTest.java index 0357afce668..4a2ad3f3091 100644 --- a/test/jdk/java/lang/invoke/condy/BootstrapMethodJumboArgsTest.java +++ b/test/jdk/java/lang/invoke/condy/BootstrapMethodJumboArgsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,12 +27,10 @@ * @summary Test bootstrap methods throwing an exception * @library /java/lang/invoke/common * @build test.java.lang.invoke.lib.InstructionHelper - * @run testng BootstrapMethodJumboArgsTest - * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 BootstrapMethodJumboArgsTest + * @run junit BootstrapMethodJumboArgsTest + * @run junit/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 BootstrapMethodJumboArgsTest */ -import org.testng.Assert; -import org.testng.annotations.Test; import test.java.lang.invoke.lib.InstructionHelper; import java.lang.invoke.ConstantCallSite; @@ -43,6 +41,10 @@ import java.util.stream.IntStream; import static java.lang.invoke.MethodType.methodType; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + public class BootstrapMethodJumboArgsTest { static final MethodHandles.Lookup L = MethodHandles.lookup(); @@ -93,7 +95,7 @@ public class BootstrapMethodJumboArgsTest { Object.class, Object[].class), expected); Object[] actual = (Object[]) mh.invoke(); - Assert.assertEquals(actual, expected); + assertArrayEquals(expected, actual); } { @@ -103,7 +105,7 @@ public class BootstrapMethodJumboArgsTest { Object.class, Object.class, Object[].class), expected); Object[] actual = (Object[]) mh.invoke(); - Assert.assertEquals(actual, expected); + assertArrayEquals(expected, actual); } { @@ -113,7 +115,7 @@ public class BootstrapMethodJumboArgsTest { Object.class, Object.class, Object.class, Object[].class), expected); Object[] actual = (Object[]) mh.invoke(); - Assert.assertEquals(actual, expected); + assertArrayEquals(expected, actual); } } @@ -128,7 +130,7 @@ public class BootstrapMethodJumboArgsTest { Object.class, Object[].class), expected); Object[] actual = (Object[]) mh.invoke(); - Assert.assertEquals(actual, expected); + assertArrayEquals(expected, actual); } { @@ -138,7 +140,7 @@ public class BootstrapMethodJumboArgsTest { Object.class, Object.class, Object[].class), expected); Object[] actual = (Object[]) mh.invoke(); - Assert.assertEquals(actual, expected); + assertArrayEquals(expected, actual); } { @@ -148,7 +150,7 @@ public class BootstrapMethodJumboArgsTest { Object.class, Object.class, Object.class, Object[].class), expected); Object[] actual = (Object[]) mh.invoke(); - Assert.assertEquals(actual, expected); + assertArrayEquals(expected, actual); } } } diff --git a/test/jdk/java/lang/invoke/condy/CondyBSMException.java b/test/jdk/java/lang/invoke/condy/CondyBSMException.java index 7aa25c5cd95..1c9f867bc8b 100644 --- a/test/jdk/java/lang/invoke/condy/CondyBSMException.java +++ b/test/jdk/java/lang/invoke/condy/CondyBSMException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,12 +27,10 @@ * @summary Test bootstrap methods throwing an exception * @library /java/lang/invoke/common * @build test.java.lang.invoke.lib.InstructionHelper - * @run testng CondyBSMException - * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyBSMException + * @run junit CondyBSMException + * @run junit/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyBSMException */ -import org.testng.Assert; -import org.testng.annotations.Test; import test.java.lang.invoke.lib.InstructionHelper; import java.lang.invoke.MethodHandle; @@ -41,6 +39,10 @@ import java.lang.reflect.Constructor; import static java.lang.invoke.MethodType.methodType; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + public class CondyBSMException { @Test @@ -70,26 +72,17 @@ public class CondyBSMException { static void test(String message, Class... ts) { MethodHandle mh = thrower(message, ts[ts.length - 1]); - Throwable caught = null; - try { - mh.invoke(); - } catch (Throwable t) { - caught = t; - } - - if (caught == null) { - Assert.fail("Throwable expected"); - } + Throwable caught = assertThrows(Throwable.class, mh::invoke); String actualMessage = null; for (int i = 0; i < ts.length; i++) { + int level = i; + assertInstanceOf(ts[i], caught, () -> "Level %d".formatted(level)); actualMessage = caught.getMessage(); - Assert.assertNotNull(caught); - Assert.assertTrue(ts[i].isAssignableFrom(caught.getClass())); caught = caught.getCause(); } - Assert.assertEquals(actualMessage, message); + assertEquals(message, actualMessage); } static Throwable throwingBsm(MethodHandles.Lookup l, String name, Class type) throws Throwable { diff --git a/test/jdk/java/lang/invoke/condy/CondyBSMInvocation.java b/test/jdk/java/lang/invoke/condy/CondyBSMInvocation.java index e9050126a79..897ee40b444 100644 --- a/test/jdk/java/lang/invoke/condy/CondyBSMInvocation.java +++ b/test/jdk/java/lang/invoke/condy/CondyBSMInvocation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * 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,13 +27,10 @@ * @summary Test basic invocation of bootstrap methods * @library /java/lang/invoke/common * @build test.java.lang.invoke.lib.InstructionHelper - * @run testng CondyBSMInvocation - * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyBSMInvocation + * @run junit CondyBSMInvocation + * @run junit/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyBSMInvocation */ - -import org.testng.Assert; -import org.testng.annotations.Test; import test.java.lang.invoke.lib.InstructionHelper; import java.lang.constant.ConstantDesc; @@ -48,6 +45,10 @@ import java.util.stream.Stream; import static java.lang.invoke.MethodType.methodType; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + public class CondyBSMInvocation { static final MethodHandles.Lookup L = MethodHandles.lookup(); @@ -59,11 +60,7 @@ public class CondyBSMInvocation { "bsm", methodType(Object.class) ); - try { - mh.invoke(); - Assert.fail("NoSuchMethodError expected to be thrown"); - } catch (NoSuchMethodError e) { - } + assertThrows(NoSuchMethodError.class, mh::invoke); } static MethodHandle[] bsms(String bsmName) { @@ -114,11 +111,7 @@ public class CondyBSMInvocation { "shape_bsm", bsm.type() ); - try { - Object r = mh.invoke(); - Assert.fail("BootstrapMethodError expected to be thrown for " + bsm); - } catch (BootstrapMethodError e) { - } + assertThrows(BootstrapMethodError.class, mh::invoke); } } @@ -139,11 +132,7 @@ public class CondyBSMInvocation { "sig_bsm", bsm.type() ); - try { - Object r = mh.invoke(); - Assert.fail("BootstrapMethodError expected to be thrown for " + bsm); - } catch (BootstrapMethodError e) { - } + assertThrows(BootstrapMethodError.class, mh::invoke); } } @@ -202,7 +191,7 @@ public class CondyBSMInvocation { static void assertAll(Object... as) { for (int i = 0; i < as.length; i++) { - Assert.assertEquals(as[i], i); + assertEquals(i, as[i]); } } @@ -219,7 +208,7 @@ public class CondyBSMInvocation { ); Object r = mh.invoke(); - Assert.assertEquals(r, Integer.toString(n)); + assertEquals(Integer.toString(n), r); } { @@ -231,7 +220,7 @@ public class CondyBSMInvocation { ); Object r = mh.invoke(); - Assert.assertEquals(r, Integer.toString(9)); + assertEquals(Integer.toString(9), r); } } @@ -248,13 +237,8 @@ public class CondyBSMInvocation { IntStream.range(0, n - 1).boxed().toArray(ConstantDesc[]::new) ); - try { - Object r = mh.invoke(); - Assert.fail("BootstrapMethodError expected to be thrown for arrity " + n); - } catch (BootstrapMethodError e) { - Throwable t = e.getCause(); - Assert.assertTrue(WrongMethodTypeException.class.isAssignableFrom(t.getClass())); - } + var e = assertThrows(BootstrapMethodError.class, mh::invoke); + assertInstanceOf(WrongMethodTypeException.class, e.getCause()); } } } diff --git a/test/jdk/java/lang/invoke/condy/CondyBSMValidationTest.java b/test/jdk/java/lang/invoke/condy/CondyBSMValidationTest.java index d255202866f..e6c2aacea63 100644 --- a/test/jdk/java/lang/invoke/condy/CondyBSMValidationTest.java +++ b/test/jdk/java/lang/invoke/condy/CondyBSMValidationTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * 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,28 +27,29 @@ * @summary Test invalid name in name and type * @library /java/lang/invoke/common * @build test.java.lang.invoke.lib.InstructionHelper - * @run testng CondyBSMValidationTest - * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyBSMValidationTest + * @run junit CondyBSMValidationTest + * @run junit/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyBSMValidationTest */ -import org.testng.Assert; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import test.java.lang.invoke.lib.InstructionHelper; -import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.util.stream.Stream; import static java.lang.invoke.MethodType.methodType; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class CondyBSMValidationTest { static final MethodHandles.Lookup L = MethodHandles.lookup(); static final String BSM_TYPE = methodType(Object.class, MethodHandles.Lookup.class, String.class, Object.class) .toMethodDescriptorString(); - @DataProvider - public Object[][] invalidSignaturesProvider() throws Exception { + public static Object[][] invalidSignaturesProvider() throws Exception { return Stream.of(BSM_TYPE.replace("(", ""), BSM_TYPE.replace(")", ""), BSM_TYPE.replace("(", "").replace(")", ""), @@ -57,15 +58,13 @@ public class CondyBSMValidationTest { .map(e -> new Object[]{e}).toArray(Object[][]::new); } - @Test(dataProvider = "invalidSignaturesProvider") + @ParameterizedTest + @MethodSource("invalidSignaturesProvider") public void testInvalidBSMSignature(String sig) throws Exception { - try { - MethodHandle mh = InstructionHelper.ldcDynamicConstant( - L, "name", "Ljava/lang/Object;", - "bsm", sig - ); - } catch (IllegalArgumentException e) { - Assert.assertTrue(e.getMessage().contains("Bad method descriptor")); - } + var e = assertThrows(IllegalArgumentException.class, () -> InstructionHelper.ldcDynamicConstant( + L, "name", "Ljava/lang/Object;", + "bsm", sig + )); + assertTrue(e.getMessage().contains("Bad method descriptor")); } } diff --git a/test/jdk/java/lang/invoke/condy/CondyInterfaceWithOverpassMethods.java b/test/jdk/java/lang/invoke/condy/CondyInterfaceWithOverpassMethods.java index 9fd35ed21f0..fe477d87657 100644 --- a/test/jdk/java/lang/invoke/condy/CondyInterfaceWithOverpassMethods.java +++ b/test/jdk/java/lang/invoke/condy/CondyInterfaceWithOverpassMethods.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,20 +27,20 @@ * @summary Test for an interface using condy with default overpass methods * @library /java/lang/invoke/common * @build test.java.lang.invoke.lib.InstructionHelper - * @run testng CondyInterfaceWithOverpassMethods - * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyInterfaceWithOverpassMethods + * @run junit CondyInterfaceWithOverpassMethods + * @run junit/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyInterfaceWithOverpassMethods */ import java.lang.classfile.ClassFile; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; import test.java.lang.invoke.lib.InstructionHelper; import java.lang.constant.*; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; -@Test +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + public class CondyInterfaceWithOverpassMethods { interface A { int a(); @@ -52,14 +52,14 @@ public class CondyInterfaceWithOverpassMethods { // Generated class with methods containing condy ldc - Class gc; + static Class gc; public static Object bsm(MethodHandles.Lookup l, String name, Class type) { return name; } - @BeforeClass - public void generateClass() throws Exception { + @BeforeAll + public static void generateClass() throws Exception { // interface B extends A { // // Overpass for method A.a // diff --git a/test/jdk/java/lang/invoke/condy/CondyNameValidationTest.java b/test/jdk/java/lang/invoke/condy/CondyNameValidationTest.java index 6178b85236b..b380c28dc94 100644 --- a/test/jdk/java/lang/invoke/condy/CondyNameValidationTest.java +++ b/test/jdk/java/lang/invoke/condy/CondyNameValidationTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * 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,13 +27,10 @@ * @summary Test invalid name in name and type * @library /java/lang/invoke/common * @build test.java.lang.invoke.lib.InstructionHelper - * @run testng CondyNameValidationTest - * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyNameValidationTest + * @run junit CondyNameValidationTest + * @run junit/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyNameValidationTest */ -import org.testng.Assert; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import test.java.lang.invoke.lib.InstructionHelper; import java.lang.invoke.MethodHandle; @@ -43,12 +40,17 @@ import java.util.stream.Stream; import static java.lang.invoke.MethodType.methodType; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class CondyNameValidationTest { static final MethodHandles.Lookup L = MethodHandles.lookup(); static final MethodType BSM_TYPE = methodType(Object.class, MethodHandles.Lookup.class, String.class, Object.class); - @DataProvider - public Object[][] invalidNamesProvider() { + public static Object[][] invalidNamesProvider() { return Stream.of( new Object[]{"", "zero-length member name"}, new Object[]{".", "Invalid member name"}, @@ -59,26 +61,24 @@ public class CondyNameValidationTest { .toArray(Object[][]::new); } - @Test(dataProvider = "invalidNamesProvider") + @ParameterizedTest + @MethodSource("invalidNamesProvider") public void testInvalidNames(String name, String errMessContent) throws Exception { - try { - MethodHandle mh = InstructionHelper.ldcDynamicConstant( - L, name, Object.class, - "bsm", BSM_TYPE - ); - } catch (IllegalArgumentException e) { - Assert.assertTrue(e.getMessage().contains(errMessContent)); - } + var e = assertThrows(IllegalArgumentException.class, () -> InstructionHelper.ldcDynamicConstant( + L, name, Object.class, + "bsm", BSM_TYPE + )); + assertTrue(e.getMessage().contains(errMessContent)); } - @DataProvider - public Object[][] validNamesProvider() throws Exception { + public static Object[][] validNamesProvider() throws Exception { return Stream.of("", "") .map(e -> new Object[]{e}).toArray(Object[][]::new); } - @Test(dataProvider = "validNamesProvider") + @ParameterizedTest + @MethodSource("validNamesProvider") public void testValidNames(String name) throws Exception { MethodHandle mh = InstructionHelper.ldcDynamicConstant( L, name, Object.class, diff --git a/test/jdk/java/lang/invoke/condy/CondyNestedTest.java b/test/jdk/java/lang/invoke/condy/CondyNestedTest.java index 8eb71ec93a3..192bbeaa46f 100644 --- a/test/jdk/java/lang/invoke/condy/CondyNestedTest.java +++ b/test/jdk/java/lang/invoke/condy/CondyNestedTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * 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,24 +26,25 @@ * @bug 8186046 * @summary Test nested dynamic constant declarations that are recursive * @compile CondyNestedTest_Code.jcod - * @run testng CondyNestedTest - * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyNestedTest + * @run junit CondyNestedTest + * @run junit/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyNestedTest */ -import org.testng.Assert; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandles; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + public class CondyNestedTest { static final Class[] THROWABLES = {InvocationTargetException.class, StackOverflowError.class}; private static final MethodHandles.Lookup L = MethodHandles.lookup(); - Class c; + static Class c; // static final MethodHandles.Lookup L = MethodHandles.lookup(); // @@ -243,28 +244,17 @@ public class CondyNestedTest { // } static void test(Method m, Class... ts) { - Throwable caught = null; - try { - m.invoke(null); - } catch (Throwable t) { - caught = t; - } + Throwable caught = assertThrows(Throwable.class, () -> m.invoke(null)); - if (caught == null) { - Assert.fail("Throwable expected"); - } - - String actualMessage = null; for (int i = 0; i < ts.length; i++) { - actualMessage = caught.getMessage(); - Assert.assertNotNull(caught); - Assert.assertTrue(ts[i].isAssignableFrom(caught.getClass())); + int level = i; + assertInstanceOf(ts[i], caught, () -> "Level %d".formatted(level)); caught = caught.getCause(); } } - @BeforeClass - public void findClass() throws Exception { + @BeforeAll + public static void findClass() throws Exception { c = Class.forName("CondyNestedTest_Code"); } diff --git a/test/jdk/java/lang/invoke/condy/CondyRepeatFailedResolution.java b/test/jdk/java/lang/invoke/condy/CondyRepeatFailedResolution.java index 7ef5c610150..b7ccb4944fb 100644 --- a/test/jdk/java/lang/invoke/condy/CondyRepeatFailedResolution.java +++ b/test/jdk/java/lang/invoke/condy/CondyRepeatFailedResolution.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * 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,28 +26,28 @@ * @bug 8186211 * @summary Test basic invocation of multiple ldc's of the same dynamic constant that fail resolution * @library /java/lang/invoke/common - * @run testng CondyRepeatFailedResolution - * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyRepeatFailedResolution + * @run junit CondyRepeatFailedResolution + * @run junit/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyRepeatFailedResolution */ import java.lang.classfile.ClassFile; -import org.testng.Assert; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - import java.lang.constant.*; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -@Test +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + public class CondyRepeatFailedResolution { // Counter used to determine if a given BSM is invoked more than once static int bsm_called = 0; // Generated class with methods containing condy ldc - Class gc; + static Class gc; // Bootstrap method used to represent primitive values // that cannot be represented directly in the constant pool, @@ -90,8 +90,8 @@ public class CondyRepeatFailedResolution { } } - @BeforeClass - public void generateClass() throws Exception { + @BeforeAll + public static void generateClass() throws Exception { String genClassName = CondyRepeatFailedResolution.class.getSimpleName() + "$Code"; String bsmClassDesc = CondyRepeatFailedResolution.class.descriptorString(); String bsmMethodName = "intConversion"; @@ -319,29 +319,21 @@ public class CondyRepeatFailedResolution { Method m = gc.getDeclaredMethod(name); bsm_called = 0; - try { + InvocationTargetException e1 = assertThrows(InvocationTargetException.class, () -> { Object r1 = m.invoke(null); - Assert.fail("InvocationTargetException expected to be thrown after first invocation"); - } catch (InvocationTargetException e1) { - // bsm_called should have been incremented prior to the exception - Assert.assertEquals(bsm_called, 1); - Assert.assertTrue(e1.getCause() instanceof BootstrapMethodError); - // Try invoking method again to ensure that the bootstrap - // method is not invoked twice and a resolution failure - // results. - try { - Object r2 = m.invoke(null); - Assert.fail("InvocationTargetException expected to be thrown after second invocation"); - } catch (InvocationTargetException e2) { - // bsm_called should remain at 1 since the bootstrap - // method should not have been invoked. - Assert.assertEquals(bsm_called, 1); - Assert.assertTrue(e2.getCause() instanceof BootstrapMethodError); - } catch (Throwable t2) { - Assert.fail("InvocationTargetException expected to be thrown"); - } - } catch (Throwable t1) { - Assert.fail("InvocationTargetException expected to be thrown"); - } + }); + // bsm_called should have been incremented prior to the exception + assertEquals(1, bsm_called); + assertInstanceOf(BootstrapMethodError.class, e1.getCause()); + // Try invoking method again to ensure that the bootstrap + // method is not invoked twice and a resolution failure + // results. + InvocationTargetException e2 = assertThrows(InvocationTargetException.class, () -> { + Object r2 = m.invoke(null); + }); + // bsm_called should remain at 1 since the bootstrap + // method should not have been invoked. + assertEquals(1, bsm_called); + assertInstanceOf(BootstrapMethodError.class, e2.getCause()); } } diff --git a/test/jdk/java/lang/invoke/condy/CondyReturnPrimitiveTest.java b/test/jdk/java/lang/invoke/condy/CondyReturnPrimitiveTest.java index d6c0748c97c..4c0dd42a1a2 100644 --- a/test/jdk/java/lang/invoke/condy/CondyReturnPrimitiveTest.java +++ b/test/jdk/java/lang/invoke/condy/CondyReturnPrimitiveTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,22 +25,23 @@ * @test * @bug 8186046 * @summary Test for condy BSMs returning primitive values or null - * @run testng CondyReturnPrimitiveTest - * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyReturnPrimitiveTest + * @run junit CondyReturnPrimitiveTest + * @run junit/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyReturnPrimitiveTest */ import java.lang.classfile.ClassFile; -import org.testng.Assert; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - import java.lang.constant.*; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.lang.reflect.Method; import java.util.concurrent.atomic.AtomicInteger; -@Test +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; + public class CondyReturnPrimitiveTest { // Counter for number of BSM calls // Use of an AtomicInteger is not strictly necessary in this test @@ -49,7 +50,7 @@ public class CondyReturnPrimitiveTest { // constant so care should be taken if a BSM operates on shared state static final AtomicInteger callCount = new AtomicInteger(); // Generated class with methods containing condy ldc - Class gc; + static Class gc; // Bootstrap method used to represent primitive values // that cannot be represented directly in the constant pool, @@ -90,8 +91,8 @@ public class CondyReturnPrimitiveTest { } } - @BeforeClass - public void generateClass() throws Exception { + @BeforeAll + public static void generateClass() throws Exception { String genClassName = CondyReturnPrimitiveTest.class.getSimpleName() + "$Code"; String bsmClassDesc = CondyReturnPrimitiveTest.class.descriptorString(); String bsmMethodName = "intConversion"; @@ -293,7 +294,7 @@ public class CondyReturnPrimitiveTest { // Ensure when run a second time that the bootstrap method is not // invoked and the constants are cached testConstants(); - Assert.assertEquals(callCount.get(), expectedCallCount); + assertEquals(expectedCallCount, callCount.get()); } @Test @@ -318,11 +319,16 @@ public class CondyReturnPrimitiveTest { testConstant("S", Short.MAX_VALUE); testConstant("Z_F", false); testConstant("Z_T", true); - testConstant("null", null); + testConstant("null", (Object) null); } void testConstant(String name, Object expected) throws Exception { Method m = gc.getDeclaredMethod(name); - Assert.assertEquals(m.invoke(null), expected); + assertEquals(expected, m.invoke(null)); + } + + void testConstant(String name, Object[] expected) throws Exception { + Method m = gc.getDeclaredMethod(name); + assertArrayEquals(expected, (Object[]) m.invoke(null)); } } diff --git a/test/jdk/java/lang/invoke/condy/CondyStaticArgumentsTest.java b/test/jdk/java/lang/invoke/condy/CondyStaticArgumentsTest.java index ba3d0e81488..075eaf4e844 100644 --- a/test/jdk/java/lang/invoke/condy/CondyStaticArgumentsTest.java +++ b/test/jdk/java/lang/invoke/condy/CondyStaticArgumentsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,12 +27,10 @@ * @summary Test bootstrap arguments for condy * @library /java/lang/invoke/common * @build test.java.lang.invoke.lib.InstructionHelper - * @run testng CondyStaticArgumentsTest - * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyStaticArgumentsTest + * @run junit CondyStaticArgumentsTest + * @run junit/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyStaticArgumentsTest */ -import org.testng.Assert; -import org.testng.annotations.Test; import test.java.lang.invoke.lib.InstructionHelper; import java.lang.constant.*; @@ -44,6 +42,9 @@ import java.util.StringJoiner; import java.util.stream.Stream; import static java.lang.invoke.MethodType.methodType; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; public class CondyStaticArgumentsTest { static final MethodHandles.Lookup L = MethodHandles.lookup(); @@ -109,7 +110,7 @@ public class CondyStaticArgumentsTest { mhi.getName(), MethodTypeDesc.ofDescriptor(mhi.getMethodType().descriptorString())) ); - Assert.assertEquals(mh.invoke(), "constant-name-String-1-2-3.0-4.0-Number-something-(int,long,float,double)void-11"); + assertEquals("constant-name-String-1-2-3.0-4.0-Number-something-(int,long,float,double)void-11", mh.invoke()); } static MathContext mathContext(MethodHandles.Lookup l, String value, Class type) { @@ -161,7 +162,7 @@ public class CondyStaticArgumentsTest { ) ) ); - Assert.assertEquals(mh.invoke(), "big-decimal-math-context-String-3.141593-7"); + assertEquals("big-decimal-math-context-String-3.141593-7", mh.invoke()); } @@ -194,7 +195,7 @@ public class CondyStaticArgumentsTest { InstructionHelper.classDesc(MathContext.class) ) )); - Assert.assertEquals(mh.invoke(), "big-decimal-math-context-()Ljava/lang/String;-3.141593-7"); + assertEquals("big-decimal-math-context-()Ljava/lang/String;-3.141593-7", mh.invoke()); } private static DirectMethodHandleDesc directMhDesc(String methodName) { diff --git a/test/jdk/java/lang/invoke/condy/CondyTypeValidationTest.java b/test/jdk/java/lang/invoke/condy/CondyTypeValidationTest.java index c44179ce13c..4429468bd34 100644 --- a/test/jdk/java/lang/invoke/condy/CondyTypeValidationTest.java +++ b/test/jdk/java/lang/invoke/condy/CondyTypeValidationTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,12 +27,9 @@ * @summary Test invalid name in name and type * @library /java/lang/invoke/common * @build test.java.lang.invoke.lib.InstructionHelper - * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyTypeValidationTest + * @run junit/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyTypeValidationTest */ -import org.testng.Assert; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import test.java.lang.invoke.lib.InstructionHelper; import java.lang.invoke.MethodHandle; @@ -43,14 +40,18 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import static java.lang.invoke.MethodType.methodType; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; public class CondyTypeValidationTest { static final MethodHandles.Lookup L = MethodHandles.lookup(); static final String BSM_TYPE = methodType(Object.class, MethodHandles.Lookup.class, String.class, Object.class) .toMethodDescriptorString(); - @DataProvider - public Object[][] invalidTypesProvider() { + public static Object[][] invalidTypesProvider() { return Stream.of( // ByteCode API checks for the following invalid types // "", @@ -66,20 +67,19 @@ public class CondyTypeValidationTest { ).toArray(Object[][]::new); } - @Test(dataProvider = "invalidTypesProvider") + @ParameterizedTest + @MethodSource("invalidTypesProvider") public void testInvalidTypes(String type, String errMessContent) throws Exception { - try { + var e = assertThrows(IllegalArgumentException.class, () -> { MethodHandle mh = InstructionHelper.ldcDynamicConstant( L, "name", type, "bsm", BSM_TYPE ); - } catch (IllegalArgumentException e) { - Assert.assertTrue(e.getMessage().contains(errMessContent)); - } + }); + assertTrue(e.getMessage().contains(errMessContent)); } - @DataProvider - public Object[][] validTypesProvider() { + public static Object[][] validTypesProvider() { List t = new ArrayList<>(List.of("B", "C", "D", "F", "I", "J", "Ljava/lang/Object;", "S", "Z")); int l = t.size(); for (int i = 0; i < l; i++) { @@ -90,7 +90,8 @@ public class CondyTypeValidationTest { .map(e -> new Object[]{e}).toArray(Object[][]::new); } - @Test(dataProvider = "validTypesProvider") + @ParameterizedTest + @MethodSource("validTypesProvider") public void testValidTypes(String type) throws Exception { MethodHandle mh = InstructionHelper.ldcDynamicConstant( L, "name", type, diff --git a/test/jdk/java/lang/invoke/condy/CondyWithGarbageTest.java b/test/jdk/java/lang/invoke/condy/CondyWithGarbageTest.java index 5e301a193dd..a00f93b69b7 100644 --- a/test/jdk/java/lang/invoke/condy/CondyWithGarbageTest.java +++ b/test/jdk/java/lang/invoke/condy/CondyWithGarbageTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * 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,21 +27,20 @@ * @summary Stress test ldc to ensure HotSpot correctly manages oop maps * @library /java/lang/invoke/common * @build test.java.lang.invoke.lib.InstructionHelper - * @run testng CondyWithGarbageTest - * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyWithGarbageTest + * @run junit CondyWithGarbageTest + * @run junit/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyWithGarbageTest */ - import java.lang.classfile.ClassFile; import java.lang.classfile.CodeBuilder; -import org.testng.Assert; -import org.testng.annotations.Test; - import java.lang.constant.*; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import static java.lang.invoke.MethodType.methodType; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertTrue; import static test.java.lang.invoke.lib.InstructionHelper.classDesc; public class CondyWithGarbageTest { @@ -54,7 +53,7 @@ public class CondyWithGarbageTest { for (int i = 0; i < 100000; i++) { l += +((String) mh.invoke()).length(); } - Assert.assertTrue(l > 0); + assertTrue(l > 0); } public static Object bsmString(MethodHandles.Lookup l, @@ -133,7 +132,7 @@ public class CondyWithGarbageTest { for (int i = 0; i < 100000; i++) { l += +((String) mh.invoke()).length(); } - Assert.assertTrue(l > 0); + assertTrue(l > 0); } public static Object bsmStringArray(MethodHandles.Lookup l, diff --git a/test/jdk/java/lang/invoke/condy/CondyWrongType.java b/test/jdk/java/lang/invoke/condy/CondyWrongType.java index 42c69e8ab7d..1c00da922fe 100644 --- a/test/jdk/java/lang/invoke/condy/CondyWrongType.java +++ b/test/jdk/java/lang/invoke/condy/CondyWrongType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * 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,13 +27,10 @@ * @summary Test bootstrap methods returning the wrong type * @library /java/lang/invoke/common * @build test.java.lang.invoke.lib.InstructionHelper - * @run testng CondyWrongType - * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyWrongType + * @run junit CondyWrongType + * @run junit/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyWrongType */ -import org.testng.Assert; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import test.java.lang.invoke.lib.InstructionHelper; import java.lang.invoke.MethodHandle; @@ -46,11 +43,15 @@ import java.util.List; import java.util.Map; import static java.lang.invoke.MethodType.methodType; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.junit.jupiter.api.Assertions.*; public class CondyWrongType { - @DataProvider - public Object[][] primitivesProvider() throws Exception { + public static Object[][] primitivesProvider() throws Exception { Map> typeMap = Map.of( "B", byte.class, "C", char.class, @@ -81,7 +82,8 @@ public class CondyWrongType { return cases.stream().toArray(Object[][]::new); } - @Test(dataProvider = "primitivesProvider") + @ParameterizedTest + @MethodSource("primitivesProvider") public void testPrimitives(String name, String type, boolean pass) { test(name, type, pass); } @@ -106,27 +108,12 @@ public class CondyWrongType { static void test(String name, String type, boolean pass) { MethodHandle mh = caster(name, type); - Throwable caught = null; - try { - mh.invoke(); - } catch (Throwable t) { - caught = t; + if (pass) { + assertDoesNotThrow(() -> mh.invoke()); + } else { + Throwable caught = assertThrows(BootstrapMethodError.class, () -> mh.invoke()); + assertInstanceOf(ClassCastException.class, caught.getCause()); } - - if (caught == null) { - if (pass) { - return; - } else { - Assert.fail("Throwable expected"); - } - } else if (pass) { - Assert.fail("Throwable not expected"); - } - - Assert.assertTrue(BootstrapMethodError.class.isAssignableFrom(caught.getClass())); - caught = caught.getCause(); - Assert.assertNotNull(caught); - Assert.assertTrue(ClassCastException.class.isAssignableFrom(caught.getClass())); } static Object bsm(MethodHandles.Lookup l, String name, Class type) { diff --git a/test/jdk/java/lang/invoke/condy/ConstantBootstrapsTest.java b/test/jdk/java/lang/invoke/condy/ConstantBootstrapsTest.java index 829f26704f9..cef5a17eda1 100644 --- a/test/jdk/java/lang/invoke/condy/ConstantBootstrapsTest.java +++ b/test/jdk/java/lang/invoke/condy/ConstantBootstrapsTest.java @@ -27,27 +27,31 @@ * @summary Test dynamic constant bootstraps * @library /java/lang/invoke/common * @build test.java.lang.invoke.lib.InstructionHelper - * @run testng ConstantBootstrapsTest - * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 ConstantBootstrapsTest + * @run junit ConstantBootstrapsTest + * @run junit/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 ConstantBootstrapsTest */ -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; -import test.java.lang.invoke.lib.InstructionHelper; - import java.lang.constant.ConstantDescs; import java.lang.constant.DirectMethodHandleDesc; import java.lang.constant.MethodHandleDesc; -import java.lang.invoke.*; +import java.lang.invoke.ConstantBootstraps; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.invoke.VarHandle; +import java.lang.invoke.WrongMethodTypeException; import java.math.BigInteger; import java.util.Collection; import java.util.List; import java.util.Map; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertNull; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import test.java.lang.invoke.lib.InstructionHelper; + +import static org.junit.jupiter.api.Assertions.*; -@Test public class ConstantBootstrapsTest { static final MethodHandles.Lookup L = MethodHandles.lookup(); @@ -56,6 +60,7 @@ public class ConstantBootstrapsTest { appendParameterTypes(params); } + @Test public void testNullConstant() throws Throwable { var handle = InstructionHelper.ldcDynamicConstant(L, "_", Object.class, ConstantBootstraps.class, "nullConstant", lookupMT(Object.class)); @@ -66,12 +71,13 @@ public class ConstantBootstrapsTest { assertNull(handle.invoke()); } - @Test(expectedExceptions = IllegalArgumentException.class) + @Test public void testNullConstantPrimitiveClass() { - ConstantBootstraps.nullConstant(MethodHandles.lookup(), null, int.class); + assertThrows(IllegalArgumentException.class, () -> ConstantBootstraps.nullConstant(MethodHandles.lookup(), null, int.class)); } + @Test public void testPrimitiveClass() throws Throwable { var pm = Map.of( "I", int.class, @@ -88,69 +94,73 @@ public class ConstantBootstrapsTest { for (var desc : pm.keySet()) { var handle = InstructionHelper.ldcDynamicConstant(L, desc, Class.class, ConstantBootstraps.class, "primitiveClass", lookupMT(Class.class)); - assertEquals(handle.invoke(), pm.get(desc)); + assertEquals(pm.get(desc), handle.invoke()); } } - @Test(expectedExceptions = NullPointerException.class) + @Test public void testPrimitiveClassNullName() { - ConstantBootstraps.primitiveClass(MethodHandles.lookup(), null, Class.class); + assertThrows(NullPointerException.class, () -> ConstantBootstraps.primitiveClass(MethodHandles.lookup(), null, Class.class)); } - @Test(expectedExceptions = NullPointerException.class) + @Test public void testPrimitiveClassNullType() { - ConstantBootstraps.primitiveClass(MethodHandles.lookup(), "I", null); + assertThrows(NullPointerException.class, () -> ConstantBootstraps.primitiveClass(MethodHandles.lookup(), "I", null)); } - @Test(expectedExceptions = IllegalArgumentException.class) + @Test public void testPrimitiveClassEmptyName() { - ConstantBootstraps.primitiveClass(MethodHandles.lookup(), "", Class.class); + assertThrows(IllegalArgumentException.class, () -> ConstantBootstraps.primitiveClass(MethodHandles.lookup(), "", Class.class)); } - @Test(expectedExceptions = IllegalArgumentException.class) + @Test public void testPrimitiveClassWrongNameChar() { - ConstantBootstraps.primitiveClass(MethodHandles.lookup(), "L", Class.class); + assertThrows(IllegalArgumentException.class, () -> ConstantBootstraps.primitiveClass(MethodHandles.lookup(), "L", Class.class)); } - @Test(expectedExceptions = IllegalArgumentException.class) + @Test public void testPrimitiveClassWrongNameString() { - ConstantBootstraps.primitiveClass(MethodHandles.lookup(), "Ljava/lang/Object;", Class.class); + assertThrows(IllegalArgumentException.class, () -> ConstantBootstraps.primitiveClass(MethodHandles.lookup(), "Ljava/lang/Object;", Class.class)); } + @Test public void testEnumConstant() throws Throwable { for (var v : StackWalker.Option.values()) { var handle = InstructionHelper.ldcDynamicConstant(L, v.name(), StackWalker.Option.class, ConstantBootstraps.class, "enumConstant", lookupMT(Enum.class)); - assertEquals(handle.invoke(), v); + assertEquals(v, handle.invoke()); } } - @Test(expectedExceptions = IllegalArgumentException.class) + @Test public void testEnumConstantUnknown() { - ConstantBootstraps.enumConstant(MethodHandles.lookup(), "DOES_NOT_EXIST", StackWalker.Option.class); + assertThrows(IllegalArgumentException.class, () -> ConstantBootstraps.enumConstant(MethodHandles.lookup(), "DOES_NOT_EXIST", StackWalker.Option.class)); } + @Test public void testGetStaticDecl() throws Throwable { var handle = InstructionHelper.ldcDynamicConstant(L, "TYPE", Class.class, ConstantBootstraps.class, "getStaticFinal", lookupMT(Object.class, Class.class), InstructionHelper.classDesc(Integer.class)); - assertEquals(handle.invoke(), int.class); + assertEquals(int.class, handle.invoke()); } + @Test public void testGetStaticSelf() throws Throwable { var handle = InstructionHelper.ldcDynamicConstant(L, "MAX_VALUE", int.class, ConstantBootstraps.class, "getStaticFinal", lookupMT(Object.class)); - assertEquals(handle.invoke(), Integer.MAX_VALUE); + assertEquals(Integer.MAX_VALUE, handle.invoke()); handle = InstructionHelper.ldcDynamicConstant(L, "ZERO", BigInteger.class, ConstantBootstraps.class, "getStaticFinal", lookupMT(Object.class)); - assertEquals(handle.invoke(), BigInteger.ZERO); + assertEquals(BigInteger.ZERO, handle.invoke()); } + @Test public void testInvoke() throws Throwable { var handle = InstructionHelper.ldcDynamicConstant( L, "_", List.class, @@ -159,9 +169,10 @@ public class ConstantBootstrapsTest { MethodType.methodType(List.class, Object[].class).toMethodDescriptorString()), 1, 2, 3, 4 ); - assertEquals(handle.invoke(), List.of(1, 2, 3, 4)); + assertEquals(List.of(1, 2, 3, 4), handle.invoke()); } + @Test public void testInvokeAsType() throws Throwable { var handle = InstructionHelper.ldcDynamicConstant( L, "_", int.class, @@ -170,9 +181,10 @@ public class ConstantBootstrapsTest { MethodType.methodType(Integer.class, String.class).toMethodDescriptorString()), "42" ); - assertEquals(handle.invoke(), 42); + assertEquals(42, handle.invoke()); } + @Test public void testInvokeAsTypeVariableArity() throws Throwable { // The constant type is Collection but the invoke return type is List var handle = InstructionHelper.ldcDynamicConstant( @@ -182,21 +194,21 @@ public class ConstantBootstrapsTest { MethodType.methodType(List.class, Object[].class).toMethodDescriptorString()), 1, 2, 3, 4 ); - assertEquals(handle.invoke(), List.of(1, 2, 3, 4)); + assertEquals(List.of(1, 2, 3, 4), handle.invoke()); } - @Test(expectedExceptions = ClassCastException.class) + @Test public void testInvokeAsTypeClassCast() throws Throwable { - ConstantBootstraps.invoke(MethodHandles.lookup(), "_", String.class, + assertThrows(ClassCastException.class, () -> ConstantBootstraps.invoke(MethodHandles.lookup(), "_", String.class, MethodHandles.lookup().findStatic(Integer.class, "valueOf", MethodType.methodType(Integer.class, String.class)), - "42"); + "42")); } - @Test(expectedExceptions = WrongMethodTypeException.class) + @Test public void testInvokeAsTypeWrongReturnType() throws Throwable { - ConstantBootstraps.invoke(MethodHandles.lookup(), "_", short.class, + assertThrows(WrongMethodTypeException.class, () -> ConstantBootstraps.invoke(MethodHandles.lookup(), "_", short.class, MethodHandles.lookup().findStatic(Integer.class, "parseInt", MethodType.methodType(int.class, String.class)), - "42"); + "42")); } @@ -205,6 +217,7 @@ public class ConstantBootstrapsTest { public static String sf; } + @Test public void testVarHandleField() throws Throwable { var handle = InstructionHelper.ldcDynamicConstant( L, "f", VarHandle.class, @@ -214,10 +227,11 @@ public class ConstantBootstrapsTest { ); var vhandle = (VarHandle) handle.invoke(); - assertEquals(vhandle.varType(), String.class); - assertEquals(vhandle.coordinateTypes(), List.of(X.class)); + assertEquals(String.class, vhandle.varType()); + assertEquals(List.of(X.class), vhandle.coordinateTypes()); } + @Test public void testVarHandleStaticField() throws Throwable { var handle = InstructionHelper.ldcDynamicConstant( L, "sf", VarHandle.class, @@ -227,10 +241,11 @@ public class ConstantBootstrapsTest { ); var vhandle = (VarHandle) handle.invoke(); - assertEquals(vhandle.varType(), String.class); - assertEquals(vhandle.coordinateTypes(), List.of()); + assertEquals(String.class, vhandle.varType()); + assertEquals(List.of(), vhandle.coordinateTypes()); } + @Test public void testVarHandleArray() throws Throwable { var handle = InstructionHelper.ldcDynamicConstant( L, "_", VarHandle.class, @@ -239,11 +254,10 @@ public class ConstantBootstrapsTest { ); var vhandle = (VarHandle) handle.invoke(); - assertEquals(vhandle.varType(), String.class); - assertEquals(vhandle.coordinateTypes(), List.of(String[].class, int.class)); + assertEquals(String.class, vhandle.varType()); + assertEquals(List.of(String[].class, int.class), vhandle.coordinateTypes()); } - @DataProvider public static Object[][] cceCasts() { return new Object[][]{ { void.class, null }, @@ -252,12 +266,12 @@ public class ConstantBootstrapsTest { }; } - @Test(dataProvider = "cceCasts", expectedExceptions = ClassCastException.class) + @ParameterizedTest + @MethodSource("cceCasts") public void testBadCasts(Class dstType, Object value) { - ConstantBootstraps.explicitCast(null, null, dstType, value); + assertThrows(ClassCastException.class, () -> ConstantBootstraps.explicitCast(null, null, dstType, value)); } - @DataProvider public static Object[][] validCasts() { Object o = new Object(); return new Object[][]{ @@ -278,9 +292,10 @@ public class ConstantBootstrapsTest { }; } - @Test(dataProvider = "validCasts") + @ParameterizedTest + @MethodSource("validCasts") public void testSuccessfulCasts(Class dstType, Object value, Object expected) { Object actual = ConstantBootstraps.explicitCast(null, null, dstType, value); - assertEquals(actual, expected); + assertEquals(expected, actual); } } diff --git a/test/jdk/java/lang/invoke/defineHiddenClass/BasicTest.java b/test/jdk/java/lang/invoke/defineHiddenClass/BasicTest.java index 379ae765a6b..097e7c782a5 100644 --- a/test/jdk/java/lang/invoke/defineHiddenClass/BasicTest.java +++ b/test/jdk/java/lang/invoke/defineHiddenClass/BasicTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ * BadClassFileVersion.jcod * @build jdk.test.lib.Utils * jdk.test.lib.compiler.CompilerUtils - * @run testng/othervm BasicTest + * @run junit/othervm BasicTest */ import java.io.File; @@ -52,16 +52,16 @@ import java.util.stream.Stream; import jdk.test.lib.compiler.CompilerUtils; import jdk.test.lib.Utils; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import static java.lang.classfile.ClassFile.*; import static java.lang.constant.ConstantDescs.CD_Enum; import static java.lang.constant.ConstantDescs.CD_Object; import static java.lang.invoke.MethodHandles.lookup; import static java.lang.invoke.MethodHandles.Lookup.ClassOption.*; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; interface HiddenTest { void test(); @@ -75,7 +75,7 @@ public class BasicTest { private static byte[] hiddenClassBytes; - @BeforeTest + @BeforeAll static void setup() throws IOException { compileSources(SRC_DIR, CLASSES_DIR); hiddenClassBytes = Files.readAllBytes(CLASSES_DIR.resolve("HiddenClass.class")); @@ -114,9 +114,9 @@ public class BasicTest { Class[] intfs = c.getInterfaces(); assertTrue(c.isHidden()); assertFalse(c.isPrimitive()); - assertTrue(intfs.length == 1); - assertTrue(intfs[0] == HiddenTest.class); - assertTrue(c.getCanonicalName() == null); + assertEquals(1, intfs.length); + assertSame(HiddenTest.class, intfs[0]); + assertNull(c.getCanonicalName()); String hcName = "HiddenClass"; String hcSuffix = "0x[0-9a-f]+"; @@ -143,7 +143,7 @@ public class BasicTest { Object array = Array.newInstance(type, 2); Class arrayType = array.getClass(); assertTrue(arrayType.isArray()); - assertTrue(Array.getLength(array) == 2); + assertEquals(2, Array.getLength(array)); assertFalse(arrayType.isHidden()); String hcName = "HiddenClass"; @@ -152,11 +152,11 @@ public class BasicTest { assertTrue(arrayType.descriptorString().matches("\\[" + "L" + hcName + "." + hcSuffix + ";")); assertTrue(arrayType.getComponentType().isHidden()); - assertTrue(arrayType.getComponentType() == type); + assertSame(type, arrayType.getComponentType()); Object t = type.newInstance(); Array.set(array, 0, t); Object o = Array.get(array, 0); - assertTrue(o == t); + assertSame(t, o); } private void checkSetAccessible(Class c, String name, Class... ptypes) throws Exception { @@ -170,13 +170,8 @@ public class BasicTest { @Test public void testLambda() throws Throwable { HiddenTest t = (HiddenTest)defineHiddenClass("Lambda").newInstance(); - try { - t.test(); - } catch (Error e) { - if (!e.getMessage().equals("thrown by " + t.getClass().getName())) { - throw e; - } - } + var e = assertThrows(Error.class, t::test); + assertEquals("thrown by " + t.getClass().getName(), e.getMessage()); } // Define a hidden class that uses lambda and contains its implementation @@ -184,13 +179,8 @@ public class BasicTest { @Test public void testHiddenLambda() throws Throwable { HiddenTest t = (HiddenTest)defineHiddenClass("HiddenLambda").newInstance(); - try { - t.test(); - } catch (Error e) { - if (!e.getMessage().equals("thrown by " + t.getClass().getName())) { - throw e; - } - } + var e = assertThrows(Error.class, t::test); + assertEquals("thrown by " + t.getClass().getName(), e.getMessage()); } // Verify the nest host and nest members of a hidden class and hidden nestmate class @@ -206,19 +196,18 @@ public class BasicTest { // test nest membership and reflection API assertTrue(host.isNestmateOf(member)); - assertTrue(host.getNestHost() == host); + assertSame(host, host.getNestHost()); // getNestHost and getNestMembers return the same value when calling // on a nest member and the nest host - assertTrue(member.getNestHost() == host.getNestHost()); - assertTrue(Arrays.equals(member.getNestMembers(), host.getNestMembers())); + assertSame(host.getNestHost(), member.getNestHost()); + assertArrayEquals(member.getNestMembers(), host.getNestMembers()); // getNestMembers includes the nest host that can be a hidden class but // only includes static nest members - assertTrue(host.getNestMembers().length == 1); - assertTrue(host.getNestMembers()[0] == host); + assertEquals(1, host.getNestMembers().length); + assertSame(host, host.getNestMembers()[0]); } - @DataProvider(name = "hiddenClasses") - private Object[][] hiddenClasses() { + private static Object[][] hiddenClasses() { return new Object[][] { new Object[] { "HiddenInterface", false }, new Object[] { "AbstractClass", false }, @@ -240,7 +229,8 @@ public class BasicTest { * is not useful as it cannot be referenced and an outer/inner class * when defined as a hidden effectively becomes a final top-level class. */ - @Test(dataProvider = "hiddenClasses") + @ParameterizedTest + @MethodSource("hiddenClasses") public void defineHiddenClass(String name, boolean nestmate) throws Exception { byte[] bytes = Files.readAllBytes(CLASSES_DIR.resolve(name + ".class")); Class hc; @@ -252,13 +242,12 @@ public class BasicTest { hc = lookup().defineHiddenClass(bytes, false).lookupClass(); host = hc; } - assertTrue(hc.getNestHost() == host); - assertTrue(hc.getNestMembers().length == 1); - assertTrue(hc.getNestMembers()[0] == host); + assertSame(host, hc.getNestHost()); + assertEquals(1, hc.getNestMembers().length); + assertSame(host, hc.getNestMembers()[0]); } - @DataProvider(name = "emptyClasses") - private Object[][] emptyClasses() { + private static Object[][] emptyClasses() { return new Object[][] { new Object[] { "EmptyHiddenSynthetic", ACC_SYNTHETIC }, new Object[] { "EmptyHiddenEnum", ACC_ENUM }, @@ -276,7 +265,8 @@ public class BasicTest { * enum class containing constants of its type should not be a hidden * class. */ - @Test(dataProvider = "emptyClasses") + @ParameterizedTest + @MethodSource("emptyClasses") public void emptyHiddenClass(String name, int accessFlags) throws Exception { byte[] bytes = (accessFlags == ACC_ENUM) ? classBytes(name, CD_Enum, accessFlags) : classBytes(name, accessFlags); @@ -316,7 +306,7 @@ public class BasicTest { throw new IllegalArgumentException("unexpected access flag: " + accessFlags); } assertTrue(hc.isHidden()); - assertTrue(hc.getModifiers() == (ACC_PUBLIC|accessFlags)); + assertEquals(hc.getModifiers(), ACC_PUBLIC | accessFlags); assertFalse(hc.isLocalClass()); assertFalse(hc.isMemberClass()); assertFalse(hc.isAnonymousClass()); @@ -324,8 +314,7 @@ public class BasicTest { } // These class files can't be defined as hidden classes - @DataProvider(name = "cantBeHiddenClasses") - private Object[][] cantBeHiddenClasses() { + private static Object[][] cantBeHiddenClasses() { return new Object[][] { // a hidden class can't be a field's declaring type // enum class with static final HiddenEnum[] $VALUES: @@ -342,10 +331,11 @@ public class BasicTest { /* * These class files */ - @Test(dataProvider = "cantBeHiddenClasses", expectedExceptions = NoClassDefFoundError.class) + @ParameterizedTest + @MethodSource("cantBeHiddenClasses") public void failToDeriveAsHiddenClass(String name) throws Exception { byte[] bytes = Files.readAllBytes(CLASSES_DIR.resolve(name + ".class")); - Class hc = lookup().defineHiddenClass(bytes, false).lookupClass(); + assertThrows(NoClassDefFoundError.class, () -> lookup().defineHiddenClass(bytes, false).lookupClass()); } /* @@ -361,22 +351,17 @@ public class BasicTest { Class c = t.getClass(); Class[] intfs = c.getInterfaces(); - assertTrue(intfs.length == 1); - assertTrue(intfs[0] == HiddenTest.class); + assertEquals(1, intfs.length); + assertSame(HiddenTest.class, intfs[0]); - try { - // this would cause loading of class HiddenCantReflect and NCDFE due - // to error during verification - c.getDeclaredMethods(); - } catch (NoClassDefFoundError e) { - Throwable x = e.getCause(); - if (x == null || !(x instanceof ClassNotFoundException && x.getMessage().contains("HiddenCantReflect"))) { - throw e; - } + var e = assertThrows(NoClassDefFoundError.class, c::getDeclaredMethods); + Throwable x = e.getCause(); + if (x == null || !(x instanceof ClassNotFoundException && x.getMessage().contains("HiddenCantReflect"))) { + throw e; } } - @Test(expectedExceptions = { IllegalArgumentException.class }) + @Test public void cantDefineModule() throws Throwable { Path src = Paths.get("module-info.java"); Path dir = CLASSES_DIR.resolve("m"); @@ -384,35 +369,34 @@ public class BasicTest { compileSources(src, dir); byte[] bytes = Files.readAllBytes(dir.resolve("module-info.class")); - lookup().defineHiddenClass(bytes, false); + assertThrows(IllegalArgumentException.class, () -> lookup().defineHiddenClass(bytes, false)); } - @Test(expectedExceptions = { IllegalArgumentException.class }) + @Test public void cantDefineClassInAnotherPackage() throws Throwable { Path src = Paths.get("ClassInAnotherPackage.java"); Files.write(src, List.of("package p;", "public class ClassInAnotherPackage {}"), StandardCharsets.UTF_8); compileSources(src, CLASSES_DIR); byte[] bytes = Files.readAllBytes(CLASSES_DIR.resolve("p").resolve("ClassInAnotherPackage.class")); - lookup().defineHiddenClass(bytes, false); + assertThrows(IllegalArgumentException.class, () -> lookup().defineHiddenClass(bytes, false)); } - @Test(expectedExceptions = { IllegalAccessException.class }) + @Test public void lessPrivilegedLookup() throws Throwable { Lookup lookup = lookup().dropLookupMode(Lookup.PRIVATE); - lookup.defineHiddenClass(hiddenClassBytes, false); + assertThrows(IllegalAccessException.class, () -> lookup.defineHiddenClass(hiddenClassBytes, false)); } - @Test(expectedExceptions = { UnsupportedClassVersionError.class }) + @Test public void badClassFileVersion() throws Throwable { Path dir = Paths.get(System.getProperty("test.classes", ".")); byte[] bytes = Files.readAllBytes(dir.resolve("BadClassFileVersion.class")); - lookup().defineHiddenClass(bytes, false); + assertThrows(UnsupportedClassVersionError.class, () -> lookup().defineHiddenClass(bytes, false)); } // malformed class files - @DataProvider(name = "malformedClassFiles") - private Object[][] malformedClassFiles() throws IOException { + private static Object[][] malformedClassFiles() throws IOException { Path dir = Paths.get(System.getProperty("test.classes", ".")); return new Object[][] { // `this_class` has invalid CP entry @@ -424,13 +408,13 @@ public class BasicTest { }; } - @Test(dataProvider = "malformedClassFiles", expectedExceptions = ClassFormatError.class) + @ParameterizedTest + @MethodSource("malformedClassFiles") public void badClassFile(byte[] bytes) throws Throwable { - lookup().defineHiddenClass(bytes, false); + assertThrows(ClassFormatError.class, () -> lookup().defineHiddenClass(bytes, false)); } - @DataProvider(name = "nestedTypesOrAnonymousClass") - private Object[][] nestedTypesOrAnonymousClass() { + private static Object[][] nestedTypesOrAnonymousClass() { return new Object[][] { // class file with bad InnerClasses or EnclosingMethod attribute new Object[] { "Outer", null }, @@ -440,7 +424,8 @@ public class BasicTest { }; } - @Test(dataProvider = "nestedTypesOrAnonymousClass") + @ParameterizedTest + @MethodSource("nestedTypesOrAnonymousClass") public void hasInnerClassesOrEnclosingMethodAttribute(String className, String badDeclaringClassName) throws Throwable { byte[] bytes = Files.readAllBytes(CLASSES_10_DIR.resolve(className + ".class")); Class hc = lookup().defineHiddenClass(bytes, false).lookupClass(); @@ -460,21 +445,22 @@ public class BasicTest { byte[] bytes = Files.readAllBytes(CLASSES_DIR.resolve("Outer.class")); Class hc = lookup().defineHiddenClass(bytes, false).lookupClass(); assertHiddenClass(hc); - assertTrue(hc.getNestHost() == hc); + assertSame(hc, hc.getNestHost()); Class[] members = hc.getNestMembers(); - assertTrue(members.length == 1 && members[0] == hc); + assertEquals(1, members.length); + assertSame(hc, members[0]); } // a hidden class with bad InnerClasses or EnclosingMethod attribute private void hiddenClassWithBadAttribute(Class hc, String badDeclaringClassName) { assertTrue(hc.isHidden()); - assertTrue(hc.getCanonicalName() == null); + assertNull(hc.getCanonicalName()); assertTrue(hc.getName().contains("/")); if (badDeclaringClassName == null) { // the following reflection API assumes a good name in InnerClasses // or EnclosingMethod attribute can successfully be resolved. - assertTrue(hc.getSimpleName().length() > 0); + assertFalse(hc.getSimpleName().isEmpty()); assertFalse(hc.isAnonymousClass()); assertFalse(hc.isLocalClass()); assertFalse(hc.isMemberClass()); @@ -483,43 +469,34 @@ public class BasicTest { } // validation of nest membership - assertTrue(hc.getNestHost() == hc); + assertSame(hc, hc.getNestHost()); // validate the static nest membership Class[] members = hc.getNestMembers(); - assertTrue(members.length == 1 && members[0] == hc); + assertEquals(1, members.length); + assertSame(hc, members[0]); } // Class::getSimpleName, Class::isMemberClass private void declaringClassNotFound(Class c, String cn) { - try { - // fail to find declaring/enclosing class - c.isMemberClass(); - assertTrue(false); - } catch (NoClassDefFoundError e) { - if (!e.getMessage().equals(cn)) { - throw e; - } + var e = assertThrows(NoClassDefFoundError.class, c::isMemberClass); + if (!e.getMessage().equals(cn)) { + throw e; } - try { - // fail to find declaring/enclosing class - c.getSimpleName(); - assertTrue(false); - } catch (NoClassDefFoundError e) { - if (!e.getMessage().equals(cn)) { - throw e; - } + e = assertThrows(NoClassDefFoundError.class, c::getSimpleName); + if (!e.getMessage().equals(cn)) { + throw e; } } private static void singletonNest(Class hc) { - assertTrue(hc.getNestHost() == hc); - assertTrue(hc.getNestMembers().length == 1); - assertTrue(hc.getNestMembers()[0] == hc); + assertSame(hc, hc.getNestHost()); + assertEquals(1, hc.getNestMembers().length); + assertSame(hc, hc.getNestMembers()[0]); } private static void assertHiddenClass(Class hc) { assertTrue(hc.isHidden()); - assertTrue(hc.getCanonicalName() == null); + assertNull(hc.getCanonicalName()); assertTrue(hc.getName().contains("/")); assertFalse(hc.isAnonymousClass()); assertFalse(hc.isLocalClass()); diff --git a/test/jdk/java/lang/invoke/defineHiddenClass/HiddenNestmateTest.java b/test/jdk/java/lang/invoke/defineHiddenClass/HiddenNestmateTest.java index e026a7a1387..a71029dd229 100644 --- a/test/jdk/java/lang/invoke/defineHiddenClass/HiddenNestmateTest.java +++ b/test/jdk/java/lang/invoke/defineHiddenClass/HiddenNestmateTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ * @test * @library /test/lib * @build HiddenNestmateTest - * @run testng/othervm HiddenNestmateTest + * @run junit/othervm HiddenNestmateTest */ import java.lang.classfile.ClassFile; @@ -37,9 +37,6 @@ import java.lang.reflect.AccessFlag; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.stream.Stream; -import java.util.Arrays; - -import org.testng.annotations.Test; import static java.lang.constant.ConstantDescs.CD_Object; import static java.lang.constant.ConstantDescs.CD_int; @@ -48,7 +45,8 @@ import static java.lang.constant.ConstantDescs.MTD_void; import static java.lang.invoke.MethodHandles.Lookup.ClassOption.*; import static java.lang.invoke.MethodHandles.Lookup.*; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; public class HiddenNestmateTest { private static final ClassDesc CD_HiddenNestmateTest = HiddenNestmateTest.class.describeConstable().orElseThrow(); @@ -61,12 +59,12 @@ public class HiddenNestmateTest { Class hiddenClass = lookup.lookupClass(); Class nestHost = hiddenClass.getNestHost(); assertTrue(hiddenClass.isHidden()); - assertTrue(nestHost == MethodHandles.lookup().lookupClass()); + assertSame(MethodHandles.lookup().lookupClass(), nestHost); // hidden nestmate is not listed in the return array of getNestMembers assertTrue(Stream.of(nestHost.getNestMembers()).noneMatch(k -> k == hiddenClass)); assertTrue(hiddenClass.isNestmateOf(lookup.lookupClass())); - assertTrue(Arrays.equals(hiddenClass.getNestMembers(), nestHost.getNestMembers())); + assertArrayEquals(nestHost.getNestMembers(), hiddenClass.getNestMembers()); } /* @@ -78,23 +76,19 @@ public class HiddenNestmateTest { Lookup lookup = MethodHandles.lookup().defineHiddenClass(bytes, false); Class c = lookup.lookupClass(); assertTrue(lookup.hasFullPrivilegeAccess()); - assertTrue((lookup.lookupModes() & ORIGINAL) == ORIGINAL); - assertTrue(c.getNestHost() == c); // host of its own nest + assertEquals(ORIGINAL, lookup.lookupModes() & ORIGINAL); + assertSame(c, c.getNestHost()); // host of its own nest assertTrue(c.isHidden()); // invoke int test(HiddenNestmateTest o) via MethodHandle MethodHandle ctor = lookup.findConstructor(c, MethodType.methodType(void.class)); MethodHandle mh = lookup.findVirtual(c, "test", MethodType.methodType(int.class, HiddenNestmateTest.class)); - try { + assertThrows(IllegalAccessError.class, () -> { int x = (int) mh.bindTo(ctor.invoke()).invokeExact(this); - throw new RuntimeException("should fail when accessing HiddenNestmateTest.privMethod()"); - } catch (IllegalAccessError e) {} + }); // invoke int test(HiddenNestmateTest o) - try { - int x1 = testInjectedClass(c); - throw new RuntimeException("should fail when accessing HiddenNestmateTest.privMethod()"); - } catch (IllegalAccessError e) {} + assertThrows(IllegalAccessError.class, () -> testInjectedClass(c)); } /* @@ -111,11 +105,11 @@ public class HiddenNestmateTest { MethodHandle ctor = lookup.findConstructor(c, MethodType.methodType(void.class)); MethodHandle mh = lookup.findVirtual(c, "test", MethodType.methodType(int.class, HiddenNestmateTest.class)); int x = (int)mh.bindTo(ctor.invoke()).invokeExact( this); - assertTrue(x == privMethod()); + assertEquals(privMethod(), x); // invoke int test(HiddenNestmateTest o) int x1 = testInjectedClass(c); - assertTrue(x1 == privMethod()); + assertEquals(privMethod(), x1); } /* @@ -131,10 +125,10 @@ public class HiddenNestmateTest { /* * Fail to create a hidden class if dropping PRIVATE lookup mode */ - @Test(expectedExceptions = IllegalAccessException.class) + @Test public void noPrivateLookupAccess() throws Throwable { Lookup lookup = MethodHandles.lookup().dropLookupMode(Lookup.PRIVATE); - lookup.defineHiddenClass(bytes, false, NESTMATE); + assertThrows(IllegalAccessException.class, () -> lookup.defineHiddenClass(bytes, false, NESTMATE)); } public void teleportToNestmate() throws Throwable { @@ -143,8 +137,8 @@ public class HiddenNestmateTest { // Teleport to a hidden nestmate Lookup lc = MethodHandles.lookup().in(lookup.lookupClass()); - assertTrue((lc.lookupModes() & PRIVATE) != 0); - assertTrue((lc.lookupModes() & ORIGINAL) == 0); + assertNotEquals(0, lc.lookupModes() & PRIVATE); + assertEquals(0, lc.lookupModes() & ORIGINAL); Lookup lc2 = lc.defineHiddenClass(bytes, false, NESTMATE); assertNestmate(lc2); @@ -153,9 +147,9 @@ public class HiddenNestmateTest { /* * Fail to create a hidden class in a different package from the lookup class' package */ - @Test(expectedExceptions = IllegalArgumentException.class) + @Test public void notSamePackage() throws Throwable { - MethodHandles.lookup().defineHiddenClass(classBytes("p/HiddenInjected"), false, NESTMATE); + assertThrows(IllegalArgumentException.class, () -> MethodHandles.lookup().defineHiddenClass(classBytes("p/HiddenInjected"), false, NESTMATE)); } /* diff --git a/test/jdk/java/lang/invoke/defineHiddenClass/LambdaNestedInnerTest.java b/test/jdk/java/lang/invoke/defineHiddenClass/LambdaNestedInnerTest.java index 9e3c8a8b318..7524e67bf9e 100644 --- a/test/jdk/java/lang/invoke/defineHiddenClass/LambdaNestedInnerTest.java +++ b/test/jdk/java/lang/invoke/defineHiddenClass/LambdaNestedInnerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ * @test * @summary define a lambda proxy class whose target class has an invalid * nest membership - * @run testng/othervm p.LambdaNestedInnerTest + * @run junit/othervm p.LambdaNestedInnerTest */ package p; @@ -41,11 +41,10 @@ import java.util.Arrays; import java.util.Set; import java.util.stream.Collectors; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; - import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; public class LambdaNestedInnerTest { private static final String INNER_CLASSNAME = "p.LambdaNestedInnerTest$Inner"; @@ -68,7 +67,7 @@ public class LambdaNestedInnerTest { lambda1.run(); } - // testng may not be visible to this class + // junit may not be visible to this class private static void assertTrue(boolean x) { if (!x) { throw new AssertionError("expected true but found false"); @@ -79,8 +78,8 @@ public class LambdaNestedInnerTest { } } - @BeforeTest - public void setup() throws IOException { + @BeforeAll + public static void setup() throws IOException { String filename = INNER_CLASSNAME.replace('.', File.separatorChar) + ".class"; Path src = Paths.get(System.getProperty("test.classes"), filename); Path dest = Paths.get(DIR, filename); @@ -93,9 +92,9 @@ public class LambdaNestedInnerTest { Class inner = Class.forName(INNER_CLASSNAME); // inner class is a nest member of LambdaNestedInnerTest Class nestHost = inner.getNestHost(); - assertTrue(nestHost == LambdaNestedInnerTest.class); + assertSame(LambdaNestedInnerTest.class, nestHost); Set> members = Arrays.stream(nestHost.getNestMembers()).collect(Collectors.toSet()); - assertEquals(members, Set.of(nestHost, inner, TestLoader.class)); + assertEquals(Set.of(nestHost, inner, TestLoader.class), members); // spin lambda proxy hidden class Runnable runnable = (Runnable) inner.newInstance(); @@ -107,8 +106,8 @@ public class LambdaNestedInnerTest { URL[] urls = new URL[] { Paths.get(DIR).toUri().toURL() }; URLClassLoader loader = new URLClassLoader(urls, null); Class inner = loader.loadClass(INNER_CLASSNAME); - assertTrue(inner.getClassLoader() == loader); - assertTrue(inner.getNestHost() == inner); // linkage error ignored + assertSame(loader, inner.getClassLoader()); + assertSame(inner, inner.getNestHost()); // linkage error ignored Runnable runnable = (Runnable) inner.newInstance(); // this validates the lambda proxy class @@ -125,8 +124,8 @@ public class LambdaNestedInnerTest { TestLoader loader = new TestLoader(urls); Class inner = loader.loadClass(INNER_CLASSNAME); - assertTrue(inner.getClassLoader() == loader); - assertTrue(inner.getNestHost() == inner); // linkage error ignored. + assertSame(loader, inner.getClassLoader()); + assertSame(inner, inner.getNestHost()); // linkage error ignored. Runnable runnable = (Runnable) inner.newInstance(); // this validates the lambda proxy class diff --git a/test/jdk/java/lang/invoke/defineHiddenClass/PreviewHiddenClass.java b/test/jdk/java/lang/invoke/defineHiddenClass/PreviewHiddenClass.java index fddbb348517..bd6c87808fe 100644 --- a/test/jdk/java/lang/invoke/defineHiddenClass/PreviewHiddenClass.java +++ b/test/jdk/java/lang/invoke/defineHiddenClass/PreviewHiddenClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 @@ * @requires !java.enablePreview * @build jdk.test.lib.Utils * jdk.test.lib.compiler.CompilerUtils - * @run testng PreviewHiddenClass + * @run junit PreviewHiddenClass * @summary verify UnsupportedClassVersionError thrown when defining a hidden class * with preview minor version but --enable-preview is not set * @comment This test itself cannot enablePreview, or hidden class definition @@ -46,15 +46,15 @@ import java.nio.file.Paths; import jdk.test.lib.compiler.CompilerUtils; import jdk.test.lib.Utils; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; public class PreviewHiddenClass { private static final Path SRC_DIR = Paths.get(Utils.TEST_SRC, "src"); private static final Path CLASSES_DIR = Paths.get("classes"); - @Test(expectedExceptions = { UnsupportedClassVersionError.class }) + @Test public void previewNotEnabled() throws Exception { // compile a class with --enable-preview Path sourceFile = SRC_DIR.resolve("HiddenInterface.java"); @@ -67,7 +67,7 @@ public class PreviewHiddenClass { byte[] bytes = Files.readAllBytes(CLASSES_DIR.resolve("HiddenInterface.class")); var dis = new DataInputStream(new ByteArrayInputStream(bytes)); dis.skipBytes(4); // 0xCAFEBABE - assertEquals(dis.readUnsignedShort(), 65535); // Minor version - MethodHandles.lookup().defineHiddenClass(bytes, false); + assertEquals(65535, dis.readUnsignedShort()); // Minor version + assertThrows(UnsupportedClassVersionError.class, () -> MethodHandles.lookup().defineHiddenClass(bytes, false)); } } diff --git a/test/jdk/java/lang/invoke/defineHiddenClass/StaticInvocableTest.java b/test/jdk/java/lang/invoke/defineHiddenClass/StaticInvocableTest.java index 1c95caa97d3..ac0a29c247d 100644 --- a/test/jdk/java/lang/invoke/defineHiddenClass/StaticInvocableTest.java +++ b/test/jdk/java/lang/invoke/defineHiddenClass/StaticInvocableTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ * @summary hidden class members can't be statically invocable * @modules java.base/jdk.internal.misc * @build java.base/* - * @run testng StaticInvocableTest + * @run junit StaticInvocableTest */ import java.lang.classfile.ClassFile; @@ -38,7 +38,6 @@ import java.lang.invoke.MethodHandles.Lookup; import java.lang.invoke.MethodType; import java.lang.invoke.LookupHelper; import java.lang.reflect.AccessFlag; -import org.testng.annotations.Test; import static java.lang.classfile.ClassFile.ACC_PUBLIC; import static java.lang.classfile.ClassFile.ACC_STATIC; @@ -46,6 +45,7 @@ import static java.lang.constant.ConstantDescs.CD_Object; import static java.lang.constant.ConstantDescs.CD_int; import static java.lang.constant.ConstantDescs.INIT_NAME; import static java.lang.constant.ConstantDescs.MTD_void; +import org.junit.jupiter.api.Test; public class StaticInvocableTest { public static void main(String[] args) throws Throwable { diff --git a/test/jdk/java/lang/invoke/defineHiddenClass/TypeDescriptorTest.java b/test/jdk/java/lang/invoke/defineHiddenClass/TypeDescriptorTest.java index e60cb8a5782..575eac1ccd1 100644 --- a/test/jdk/java/lang/invoke/defineHiddenClass/TypeDescriptorTest.java +++ b/test/jdk/java/lang/invoke/defineHiddenClass/TypeDescriptorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,10 +21,10 @@ * questions. */ -/** +/* * @test * @bug 8242013 - * @run testng/othervm test.TypeDescriptorTest + * @run junit/othervm test.TypeDescriptorTest * @summary Test TypeDescriptor::descriptorString for hidden classes which * cannot be used to produce ConstantDesc via ClassDesc or * MethodTypeDesc factory methods @@ -42,9 +42,10 @@ import java.nio.file.Files; import java.nio.file.Paths; import static java.lang.invoke.MethodType.*; -import org.testng.annotations.Test; -import org.testng.annotations.DataProvider; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; public class TypeDescriptorTest { private static final Lookup HC_LOOKUP = defineHiddenClass(); @@ -61,8 +62,7 @@ public class TypeDescriptorTest { } } - @DataProvider(name = "constables") - private Object[][] constables() throws Exception { + private static Object[][] constables() throws Exception { Class hcArray = Array.newInstance(HC, 1).getClass(); return new Object[][] { new Object[] { HC }, @@ -79,7 +79,8 @@ public class TypeDescriptorTest { * Hidden classes have no nominal descriptor. * Constable::describeConstable returns empty optional. */ - @Test(dataProvider = "constables") + @ParameterizedTest + @MethodSource("constables") public void noNominalDescriptor(Constable constable) { assertTrue(constable.describeConstable().isEmpty()); } @@ -90,27 +91,13 @@ public class TypeDescriptorTest { */ @Test public void testClassDesc() { - try { - ClassDesc.ofDescriptor(HC.descriptorString()); - assertFalse(true); - } catch (IllegalArgumentException e) {} - - try { - ClassDesc.ofDescriptor(HC.getName()); - assertFalse(true); - } catch (IllegalArgumentException e) {} - try { - ClassDesc.of(HC.getPackageName(), HC.getSimpleName()); - assertFalse(true); - } catch (IllegalArgumentException e) {} - try { - ClassDesc.of(HC.getName()); - assertFalse(true); - } catch (IllegalArgumentException e) {} + assertThrows(IllegalArgumentException.class, () -> ClassDesc.ofDescriptor(HC.descriptorString())); + assertThrows(IllegalArgumentException.class, () -> ClassDesc.ofDescriptor(HC.getName())); + assertThrows(IllegalArgumentException.class, () -> ClassDesc.of(HC.getPackageName(), HC.getSimpleName())); + assertThrows(IllegalArgumentException.class, () -> ClassDesc.of(HC.getName())); } - @DataProvider(name = "typeDescriptors") - private Object[][] typeDescriptors() throws Exception { + private static Object[][] typeDescriptors() throws Exception { Class hcArray = Array.newInstance(HC, 1, 1).getClass(); return new Object[][] { new Object[] { HC, "Ltest/HiddenClass.0x[0-9a-f]+;"}, @@ -124,26 +111,20 @@ public class TypeDescriptorTest { /* * Hidden classes have no nominal type descriptor */ - @Test(dataProvider = "typeDescriptors") + @ParameterizedTest + @MethodSource("typeDescriptors") public void testTypeDescriptor(TypeDescriptor td, String regex) throws Exception { String desc = td.descriptorString(); assertTrue(desc.matches(regex)); if (td instanceof Class) { - try { - ClassDesc.ofDescriptor(desc); - assertFalse(true); - } catch (IllegalArgumentException e) {} + assertThrows(IllegalArgumentException.class, () -> ClassDesc.ofDescriptor(desc)); } else if (td instanceof MethodType) { - try { - MethodTypeDesc.ofDescriptor(desc); - assertFalse(true); - } catch (IllegalArgumentException e) {} + assertThrows(IllegalArgumentException.class, () -> MethodTypeDesc.ofDescriptor(desc)); } } - @DataProvider(name = "methodTypes") - private Object[][] methodTypes() throws Exception { + private static Object[][] methodTypes() throws Exception { Class hcArray = Array.newInstance(HC, 1, 1).getClass(); return new Object[][] { new Object[] { methodType(HC), "\\(\\)Ltest/HiddenClass.0x[0-9a-f]+;" }, @@ -155,15 +136,13 @@ public class TypeDescriptorTest { /* * Test MethodType::toMethodDescriptorString with MethodType referencing to hidden class */ - @Test(dataProvider = "methodTypes") + @ParameterizedTest + @MethodSource("methodTypes") public void testToMethodDescriptorString(MethodType mtype, String regex) throws Exception { String desc = mtype.toMethodDescriptorString(); assertTrue(desc.matches(regex)); - try { - MethodType.fromMethodDescriptorString(desc, TypeDescriptorTest.class.getClassLoader()); - assertFalse(true); - } catch (IllegalArgumentException e) {} + assertThrows(IllegalArgumentException.class, () -> MethodType.fromMethodDescriptorString(desc, TypeDescriptorTest.class.getClassLoader())); } } diff --git a/test/jdk/java/lang/invoke/defineHiddenClass/UnloadingTest.java b/test/jdk/java/lang/invoke/defineHiddenClass/UnloadingTest.java index b016b2f6899..45728f2ed79 100644 --- a/test/jdk/java/lang/invoke/defineHiddenClass/UnloadingTest.java +++ b/test/jdk/java/lang/invoke/defineHiddenClass/UnloadingTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ * @modules jdk.compiler * @library /test/lib/ * @build jdk.test.lib.util.ForceGC - * @run testng/othervm UnloadingTest + * @run junit/othervm UnloadingTest */ import java.io.IOException; @@ -48,18 +48,16 @@ import jdk.test.lib.util.ForceGC; import jdk.test.lib.compiler.CompilerUtils; import jdk.test.lib.Utils; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; - -import static java.lang.invoke.MethodHandles.lookup; import static java.lang.invoke.MethodHandles.Lookup.ClassOption.*; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; public class UnloadingTest { private static final Path CLASSES_DIR = Paths.get("classes"); private static byte[] hiddenClassBytes; - @BeforeTest + @BeforeAll static void setup() throws IOException { Path src = Paths.get(Utils.TEST_SRC, "src", "LookupHelper.java"); if (!CompilerUtils.compile(src, CLASSES_DIR)) { @@ -116,7 +114,7 @@ public class UnloadingTest { // keep a strong reference to the nest member class Class member = unloaders[1].weakRef.get(); - assertTrue(member != null); + assertNotNull(member); // nest host and member will not be unloaded assertFalse(unloaders[0].tryUnload()); assertFalse(unloaders[1].tryUnload()); @@ -180,7 +178,7 @@ public class UnloadingTest { } else { hc = lookup.defineHiddenClass(hiddenClassBytes, false).lookupClass(); } - assertTrue(hc.getClassLoader() == lookup.lookupClass().getClassLoader()); + assertSame(lookup.lookupClass().getClassLoader(), hc.getClassLoader()); return new HiddenClassUnloader(hc); } @@ -202,7 +200,7 @@ public class UnloadingTest { } else { member = hostLookup.defineHiddenClass(hiddenClassBytes, false, NESTMATE).lookupClass(); } - assertTrue(member.getNestHost() == host); + assertSame(host, member.getNestHost()); return new HiddenClassUnloader[] { new HiddenClassUnloader(host), new HiddenClassUnloader(member) }; } diff --git a/test/jdk/java/lang/invoke/findSpecial/FindSpecialTest.java b/test/jdk/java/lang/invoke/findSpecial/FindSpecialTest.java index 9b6622a7e9c..5bb7f67c000 100644 --- a/test/jdk/java/lang/invoke/findSpecial/FindSpecialTest.java +++ b/test/jdk/java/lang/invoke/findSpecial/FindSpecialTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,12 +21,12 @@ * questions. */ -/** +/* * @test * @bug 8209005 8209078 * @library /test/lib * @build m1/* FindSpecialTest - * @run testng/othervm FindSpecialTest + * @run junit/othervm FindSpecialTest * @summary Test findSpecial and unreflectSpecial of the declaring class * of the method and the special caller are not in the same module * as the lookup class. @@ -39,7 +39,7 @@ import java.nio.file.Paths; import static jdk.test.lib.process.ProcessTools.*; -import org.testng.annotations.Test; +import org.junit.jupiter.api.Test; public class FindSpecialTest { static final String TEST_CLASSES = System.getProperty("test.classes", "."); @@ -51,7 +51,7 @@ public class FindSpecialTest { * Run test.FindSpecial in unnamed module */ @Test - public static void callerInUnnamedModule() throws Throwable { + public void callerInUnnamedModule() throws Throwable { Path m1 = Paths.get(TEST_CLASSES, "modules", TEST_MODULE); if (Files.notExists(m1)) { throw new Error(m1 + " not exist"); @@ -66,7 +66,7 @@ public class FindSpecialTest { * Run test.FindSpecial in a named module */ @Test - public static void callerInNamedModule() throws Throwable { + public void callerInNamedModule() throws Throwable { Path modules = Paths.get(TEST_CLASSES, "modules"); if (Files.notExists(modules)) { throw new Error(modules + " not exist"); diff --git a/test/jdk/java/lang/invoke/lambda/LambdaFileEncodingSerialization.java b/test/jdk/java/lang/invoke/lambda/LambdaFileEncodingSerialization.java index 1f950ffce7e..6c505ddf471 100644 --- a/test/jdk/java/lang/invoke/lambda/LambdaFileEncodingSerialization.java +++ b/test/jdk/java/lang/invoke/lambda/LambdaFileEncodingSerialization.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,36 +21,33 @@ * questions. */ -/** +/* * @test * @bug 8248231 * @summary Test to verify lambda serialization uses the correct UTF-8 encoding * @library /test/lib * @build jdk.test.lib.JDKToolFinder * jdk.test.lib.process.ProcessTools - * @run testng LambdaFileEncodingSerialization + * @run junit LambdaFileEncodingSerialization */ import java.io.File; -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.io.IOException; import java.util.List; import java.util.Map; import java.util.Arrays; import java.util.ArrayList; -import org.testng.annotations.Test; -import static org.testng.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertTrue; import jdk.test.lib.JDKToolFinder; import jdk.test.lib.process.ProcessTools; +import org.junit.jupiter.api.Test; public class LambdaFileEncodingSerialization { private static final String TEST_NAME = "TestLambdaFileEncodingSerialization"; @Test - public static void testDeserializeLambdaEncoding() throws Throwable { + public void testDeserializeLambdaEncoding() throws Throwable { String javac = JDKToolFinder.getTestJDKTool("javac"); String java = JDKToolFinder.getTestJDKTool("java"); diff --git a/test/jdk/java/lang/invoke/lambda/LambdaHiddenCaller.java b/test/jdk/java/lang/invoke/lambda/LambdaHiddenCaller.java index aed19e6ca17..0dbdff79230 100644 --- a/test/jdk/java/lang/invoke/lambda/LambdaHiddenCaller.java +++ b/test/jdk/java/lang/invoke/lambda/LambdaHiddenCaller.java @@ -29,8 +29,7 @@ import java.util.function.IntSupplier; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; /* * @test @@ -62,7 +61,7 @@ public class LambdaHiddenCaller { void testSerializableLambda() { var is = hiddenCaller.callSerializableLambda(); assertEquals(42, is.getAsInt()); - assertTrue(Serializable.class.isAssignableFrom(is.getClass())); + assertInstanceOf(Serializable.class, is); // We do not guarantee serialization functionalities yet } } diff --git a/test/jdk/java/lang/invoke/lambda/LogGeneratedClassesTest.java b/test/jdk/java/lang/invoke/lambda/LogGeneratedClassesTest.java index 60c85753d72..eb013bf01f3 100644 --- a/test/jdk/java/lang/invoke/lambda/LogGeneratedClassesTest.java +++ b/test/jdk/java/lang/invoke/lambda/LogGeneratedClassesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ * @library /java/nio/file * @modules jdk.compiler * jdk.zipfs - * @run testng LogGeneratedClassesTest + * @run junit LogGeneratedClassesTest * @summary tests logging generated classes for lambda */ import java.io.IOException; @@ -45,24 +45,24 @@ import java.nio.file.attribute.PosixFileAttributeView; import jdk.test.lib.compiler.CompilerUtils; import jdk.test.lib.process.OutputAnalyzer; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; -import org.testng.SkipException; import static java.nio.file.attribute.PosixFilePermissions.*; import static jdk.test.lib.process.ProcessTools.*; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertTrue; +import org.junit.jupiter.api.AfterAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; public class LogGeneratedClassesTest { static final Path DUMP_LAMBDA_PROXY_CLASS_FILES = Path.of("DUMP_LAMBDA_PROXY_CLASS_FILES"); static final Path CLASSES = Path.of("classes").toAbsolutePath(); - String longFQCN; + static String longFQCN; - @BeforeClass - public void setup() throws IOException { + @BeforeAll + public static void setup() throws IOException { final List scratch = new ArrayList<>(); scratch.clear(); scratch.add("package com.example;"); @@ -102,8 +102,8 @@ public class LogGeneratedClassesTest { CompilerUtils.compile(Path.of("."), CLASSES); } - @AfterClass - public void cleanup() throws IOException { + @AfterAll + public static void cleanup() throws IOException { Files.delete(Paths.get("TestLambda.java")); Files.delete(Paths.get("LongPackageName.java")); TestUtil.removeAll(DUMP_LAMBDA_PROXY_CLASS_FILES); @@ -132,12 +132,11 @@ public class LogGeneratedClassesTest { executeProcess(pb).shouldHaveExitValue(0); // 2 our own class files. We don't care about the others - assertEquals(Files.find( - dumpDir, - 99, - (p, a) -> p.startsWith(dumpDir.resolve("com/example")) - && a.isRegularFile()).count(), - 2, "Two lambda captured"); + assertEquals(2, Files.find( + dumpDir, + 99, + (p, a) -> p.startsWith(dumpDir.resolve("com/example")) + && a.isRegularFile()).count(), "Two lambda captured"); } @Test @@ -155,12 +154,11 @@ public class LogGeneratedClassesTest { executeProcess(pb).shouldHaveExitValue(0); // The dump directory will be created if not exist - assertEquals(Files.find( - dumpDir, - 99, - (p, a) -> p.startsWith(dumpDir.resolve("com/example")) - && a.isRegularFile()).count(), - 2, "Two lambda captured"); + assertEquals(2, Files.find( + dumpDir, + 99, + (p, a) -> p.startsWith(dumpDir.resolve("com/example")) + && a.isRegularFile()).count(), "Two lambda captured"); } @Test @@ -208,12 +206,10 @@ public class LogGeneratedClassesTest { try { fs = Files.getFileStore(Paths.get(".")); } catch (IOException e) { - throw new SkipException("WARNING: IOException occurred: " + e + ", Skipping testDumpDirNotWritable test."); - } - if (!fs.supportsFileAttributeView(PosixFileAttributeView.class)) { - // No easy way to setup readonly directory without POSIX - throw new SkipException("WARNING: POSIX is not supported. Skipping testDumpDirNotWritable test."); + Assumptions.assumeTrue(false, "WARNING: IOException occurred: " + e + ", Skipping testDumpDirNotWritable test."); + return; } + Assumptions.assumeFalse(!fs.supportsFileAttributeView(PosixFileAttributeView.class), "WARNING: POSIX is not supported. Skipping testDumpDirNotWritable test."); // No easy way to setup readonly directory without POSIX Path testDir = Path.of("readOnly"); Path dumpDir = testDir.resolve(DUMP_LAMBDA_PROXY_CLASS_FILES); @@ -221,11 +217,8 @@ public class LogGeneratedClassesTest { Files.createDirectory(dumpDir, asFileAttribute(fromString("r-xr-xr-x"))); try { - if (isWriteableDirectory(dumpDir)) { - // Skipping the test: it's allowed to write into read-only directory - // (e.g. current user is super user). - throw new SkipException("WARNING: The dump directory is writeable. Skipping testDumpDirNotWritable test."); - } + Assumptions.assumeFalse(isWriteableDirectory(dumpDir), "WARNING: The dump directory is writeable. Skipping testDumpDirNotWritable test."); // Skipping the test: it's allowed to write into read-only directory + // (e.g. current user is super user). ProcessBuilder pb = createLimitedTestJavaProcessBuilder( "-cp", CLASSES.toString(), @@ -251,10 +244,9 @@ public class LogGeneratedClassesTest { longFQCN).directory(testDir.toFile()); OutputAnalyzer outputAnalyzer = executeProcess(pb); outputAnalyzer.shouldHaveExitValue(0); - assertEquals(outputAnalyzer.asLines().stream() - .filter(s -> s.startsWith("WARNING: Exception")) - .count(), - 2, "show error each capture"); + assertEquals(2, outputAnalyzer.asLines().stream() + .filter(s -> s.startsWith("WARNING: Exception")) + .count(), "show error each capture"); // dumpLong/DUMP_LAMBDA_PROXY_CLASS_FILES/com/example/nonsense/nonsense Path dumpPath = dumpDir.resolve("com/example/nonsense"); Predicate filter = p -> p.getParent() == null || dumpPath.startsWith(p) || p.startsWith(dumpPath); @@ -269,8 +261,8 @@ public class LogGeneratedClassesTest { } }); } - assertEquals(Files.walk(dumpDir) + assertEquals(5, Files.walk(dumpDir) .filter(filter) - .count(), 5, "Two lambda captured failed to log"); + .count(), "Two lambda captured failed to log"); } } diff --git a/test/jdk/java/lang/invoke/lambda/invokeSpecial/InvokeSpecialMethodTest.java b/test/jdk/java/lang/invoke/lambda/invokeSpecial/InvokeSpecialMethodTest.java index bf1db0f822e..4b74d05f270 100644 --- a/test/jdk/java/lang/invoke/lambda/invokeSpecial/InvokeSpecialMethodTest.java +++ b/test/jdk/java/lang/invoke/lambda/invokeSpecial/InvokeSpecialMethodTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,22 +24,22 @@ /* * @test * @bug 8274848 - * @run testng InvokeSpecialMethodTest + * @run junit InvokeSpecialMethodTest * @summary ensure REF_invokeSpecial on a non-private implementation method * behaves as if `super::m` is invoked regardless of its access flag */ -import org.testng.Assert; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.CallSite; import java.lang.invoke.LambdaMetafactory; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles.Lookup; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + import static java.lang.invoke.MethodType.methodType; +import static org.junit.jupiter.api.Assertions.assertEquals; public class InvokeSpecialMethodTest { static class MethodTest { @@ -95,8 +95,7 @@ public class InvokeSpecialMethodTest { String get(); } - @DataProvider - public Object[][] methodProvider() { + public static Object[][] methodProvider() { return new Object[][]{ {MethodTest.M_PUBLIC, "test_public"}, {MethodTest.M_PROTECTED, "test_protected"}, @@ -104,7 +103,8 @@ public class InvokeSpecialMethodTest { }; } - @Test(dataProvider = "methodProvider") + @ParameterizedTest + @MethodSource("methodProvider") void test(MethodHandle implMethod, String expected) throws Throwable { testMetafactory(implMethod, expected); testAltMetafactory(implMethod, expected); @@ -117,7 +117,7 @@ public class InvokeSpecialMethodTest { MethodTest o = new MethodTest.SubClass(); StringFactory factory = (StringFactory) cs.dynamicInvoker().invokeExact(o); String actual = factory.get(); - Assert.assertEquals(actual, expected); + assertEquals(expected, actual); } static void testAltMetafactory(MethodHandle implMethod, String expected) throws Throwable { @@ -128,6 +128,6 @@ public class InvokeSpecialMethodTest { MethodTest o = new MethodTest.SubClass(); StringFactory factory = (StringFactory) cs.dynamicInvoker().invokeExact(o); String actual = factory.get(); - Assert.assertEquals(actual, expected); + assertEquals(expected, actual); } } diff --git a/test/jdk/java/lang/invoke/lambda/superProtectedMethod/InheritedProtectedMethod.java b/test/jdk/java/lang/invoke/lambda/superProtectedMethod/InheritedProtectedMethod.java index a5cf6f68c50..fc730d790ac 100644 --- a/test/jdk/java/lang/invoke/lambda/superProtectedMethod/InheritedProtectedMethod.java +++ b/test/jdk/java/lang/invoke/lambda/superProtectedMethod/InheritedProtectedMethod.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ * @library /test/lib * @build jdk.test.lib.Utils * jdk.test.lib.compiler.CompilerUtils - * @run testng/othervm InheritedProtectedMethod + * @run junit/othervm InheritedProtectedMethod * @summary Test method reference to a method inherited from its * superclass in a different package. Such method's modifier * is changed from public to protected. @@ -37,10 +37,6 @@ import jdk.test.lib.compiler.CompilerUtils; import jdk.test.lib.Utils; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.io.IOException; import java.lang.reflect.Method; import java.net.URL; @@ -48,13 +44,15 @@ import java.net.URLClassLoader; import java.nio.file.Path; import java.nio.file.Paths; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; public class InheritedProtectedMethod { private static final Path SRC_DIR = Paths.get(Utils.TEST_SRC, "src"); private static final Path CLASSES_DIR = Paths.get("classes"); - @BeforeTest + @BeforeAll static void setup() throws IOException { assertTrue(CompilerUtils.compile(SRC_DIR, CLASSES_DIR)); @@ -64,13 +62,13 @@ public class InheritedProtectedMethod { } @Test - public static void run() throws Exception { + public void run() throws Exception { URLClassLoader loader = new URLClassLoader("loader", new URL[]{ CLASSES_DIR.toUri().toURL()}, ClassLoader.getPlatformClassLoader()); Class methodInvokeClass = Class.forName("MethodInvoker", false, loader); Method invokeMethod = methodInvokeClass.getMethod("invoke"); String result = (String)invokeMethod.invoke(null); - assertEquals(result, "protected inherited method"); + assertEquals("protected inherited method", result); } } diff --git a/test/jdk/java/lang/invoke/lambda/superProtectedMethod/ProtectedMethodInOtherPackage.java b/test/jdk/java/lang/invoke/lambda/superProtectedMethod/ProtectedMethodInOtherPackage.java index 666ba5c254b..980114149a8 100644 --- a/test/jdk/java/lang/invoke/lambda/superProtectedMethod/ProtectedMethodInOtherPackage.java +++ b/test/jdk/java/lang/invoke/lambda/superProtectedMethod/ProtectedMethodInOtherPackage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /* * @test * @bug 8227415 8254975 8270056 - * @run testng/othervm p.ProtectedMethodInOtherPackage + * @run junit/othervm p.ProtectedMethodInOtherPackage * @summary method reference to a protected method inherited from its * superclass in a different runtime package where * lambda proxy class has no access to it. @@ -47,12 +47,12 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.function.Function; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; public class ProtectedMethodInOtherPackage { @Test - public static void remotePackageSameLoader() { + public void remotePackageSameLoader() { Sub_I sub = new Sub_I(); sub.test(Paths.get("test")); } @@ -76,14 +76,14 @@ public class ProtectedMethodInOtherPackage { } @Test - public static void splitPackage() throws Throwable { + public void splitPackage() throws Throwable { ClassLoader parent = new Loader("loader-A", null, A.class); ClassLoader loader = new Loader("loader-B", parent, B.class); Class aClass = Class.forName(A.class.getName(), false, loader); Class bClass = Class.forName(B.class.getName(), false, loader); - assertTrue(aClass.getClassLoader() == parent); - assertTrue(bClass.getClassLoader() == loader); - assertEquals(aClass.getPackageName(), bClass.getPackageName()); + assertSame(parent, aClass.getClassLoader()); + assertSame(loader, bClass.getClassLoader()); + assertEquals(bClass.getPackageName(), aClass.getPackageName()); Object b = bClass.getDeclaredConstructor().newInstance(); @@ -102,14 +102,14 @@ public class ProtectedMethodInOtherPackage { } @Test - public static void protectedStaticMethodInSplitPackage() throws Throwable { + public void protectedStaticMethodInSplitPackage() throws Throwable { ClassLoader parent = new Loader("loader-A1", null, A1.class); ClassLoader loader = new Loader("loader-B1", parent, B1.class); Class aClass1 = Class.forName(A1.class.getName(), false, loader); Class bClass1 = Class.forName(B1.class.getName(), false, loader); - assertTrue(aClass1.getClassLoader() == parent); - assertTrue(bClass1.getClassLoader() == loader); - assertEquals(aClass1.getPackageName(), bClass1.getPackageName()); + assertSame(parent, aClass1.getClassLoader()); + assertSame(loader, bClass1.getClassLoader()); + assertEquals(bClass1.getPackageName(), aClass1.getPackageName()); // verify subclass can access a static protected method inherited from // its superclass in a split package diff --git a/test/jdk/java/lang/invoke/lookup/ChainedLookupTest.java b/test/jdk/java/lang/invoke/lookup/ChainedLookupTest.java index 0e81c6a9eec..15a46e6ca2c 100644 --- a/test/jdk/java/lang/invoke/lookup/ChainedLookupTest.java +++ b/test/jdk/java/lang/invoke/lookup/ChainedLookupTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /* * @test * @bug 8013527 - * @run testng/othervm ChainedLookupTest + * @run junit/othervm ChainedLookupTest * @summary Test MethodHandles.lookup method to produce the Lookup object with * proper lookup class if invoked through reflection and method handle. */ @@ -33,11 +33,11 @@ import java.lang.invoke.*; import java.lang.invoke.MethodHandles.Lookup; import java.lang.reflect.Method; -import org.testng.annotations.Test; import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; public class ChainedLookupTest { /** @@ -121,7 +121,7 @@ public class ChainedLookupTest { } void test(Lookup lookup, String msg) throws Throwable { - assertTrue(lookup.lookupClass() == ChainedLookupTest.class); + assertSame(ChainedLookupTest.class, lookup.lookupClass()); assertTrue(lookup.hasFullPrivilegeAccess()); MethodHandle mh = lookup.findStatic(lookup.lookupClass(), "say", methodType(void.class, String.class)); diff --git a/test/jdk/java/lang/invoke/lookup/LookupClassTest.java b/test/jdk/java/lang/invoke/lookup/LookupClassTest.java index 205bd3d893e..5970d0331dd 100644 --- a/test/jdk/java/lang/invoke/lookup/LookupClassTest.java +++ b/test/jdk/java/lang/invoke/lookup/LookupClassTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2026, Oracle and/or its affiliates. All rights reserved. * 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,44 +25,44 @@ * @test * @bug 8173975 * @summary Lookup::in throws IAE if the target class is a primitive class or array class - * @run testng/othervm LookupClassTest + * @run junit/othervm LookupClassTest */ import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles.Lookup; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; public class LookupClassTest { private static final LookupClassTest[] ARRAY = new LookupClassTest[0]; - @BeforeTest - public void test() { + @BeforeAll + public static void test() { assertTrue(ARRAY.getClass().isArray()); assertSamePackage(MethodHandles.lookup(), ARRAY.getClass()); assertSamePackage(MethodHandles.publicLookup(), int.class); } - private void assertSamePackage(Lookup lookup, Class targetClass) { - assertEquals(lookup.lookupClass().getPackageName(), targetClass.getPackageName()); + private static void assertSamePackage(Lookup lookup, Class targetClass) { + assertEquals(targetClass.getPackageName(), lookup.lookupClass().getPackageName()); } - @Test(expectedExceptions = IllegalArgumentException.class) + @Test public void arrayLookupClass() { Lookup lookup = MethodHandles.lookup(); - lookup.in(ARRAY.getClass()); + assertThrows(IllegalArgumentException.class, () -> lookup.in(ARRAY.getClass())); } - @Test(expectedExceptions = IllegalArgumentException.class) + @Test public void primitiveLookupClass() { Lookup lookup = MethodHandles.publicLookup(); - lookup.in(int.class); + assertThrows(IllegalArgumentException.class, () -> lookup.in(int.class)); } - @Test(expectedExceptions = IllegalArgumentException.class) + @Test public void voidLookupClass() { Lookup lookup = MethodHandles.publicLookup(); - lookup.in(void.class); + assertThrows(IllegalArgumentException.class, () -> lookup.in(void.class)); } } diff --git a/test/jdk/java/lang/invoke/lookup/SpecialStatic.java b/test/jdk/java/lang/invoke/lookup/SpecialStatic.java index 31ded727d66..3ff99b9dfda 100644 --- a/test/jdk/java/lang/invoke/lookup/SpecialStatic.java +++ b/test/jdk/java/lang/invoke/lookup/SpecialStatic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ * @bug 8032400 * @summary JSR292: invokeSpecial: InternalError attempting to lookup a method * @compile -XDignore.symbol.file SpecialStatic.java - * @run testng test.java.lang.invoke.lookup.SpecialStatic + * @run junit test.java.lang.invoke.lookup.SpecialStatic */ package test.java.lang.invoke.lookup; @@ -38,13 +38,13 @@ import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.lang.reflect.AccessFlag; -import org.testng.annotations.*; import static java.lang.classfile.ClassFile.ACC_PUBLIC; import static java.lang.classfile.ClassFile.ACC_STATIC; import static java.lang.constant.ConstantDescs.*; import static java.lang.constant.DirectMethodHandleDesc.Kind.SPECIAL; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; /** * Test case: @@ -105,7 +105,7 @@ public class SpecialStatic { public void testConstant() throws Throwable { MethodHandle mh = (MethodHandle)t3.getDeclaredMethod("getMethodHandle").invoke(null); int result = (int)mh.invoke(t3.newInstance()); - assertEquals(result, 1); // T1.m should be invoked. + assertEquals(1, result); // T1.m should be invoked. } @Test @@ -113,7 +113,7 @@ public class SpecialStatic { MethodHandles.Lookup lookup = (MethodHandles.Lookup)t3.getDeclaredMethod("getLookup").invoke(null); MethodHandle mh = lookup.findSpecial(t1, "m", MethodType.methodType(int.class), t3); int result = (int)mh.invoke(t3.newInstance()); - assertEquals(result, 1); // T1.m should be invoked. + assertEquals(1, result); // T1.m should be invoked. } public static byte[] dumpT1() { diff --git a/test/jdk/java/lang/invoke/modules/Driver.java b/test/jdk/java/lang/invoke/modules/Driver.java index 5c00de3ad47..11c44280309 100644 --- a/test/jdk/java/lang/invoke/modules/Driver.java +++ b/test/jdk/java/lang/invoke/modules/Driver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,9 +21,9 @@ * questions. */ -/** +/* * @test * @build m1/* m2/* Unnamed - * @run testng/othervm m1/p1.Main + * @run junit/othervm m1/p1.Main * @summary Basic test case for module access checks and Lookup.in. */ diff --git a/test/jdk/java/lang/invoke/modules/Driver1.java b/test/jdk/java/lang/invoke/modules/Driver1.java index 654ee04c9e0..4ef7130ff94 100644 --- a/test/jdk/java/lang/invoke/modules/Driver1.java +++ b/test/jdk/java/lang/invoke/modules/Driver1.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,11 +21,11 @@ * questions. */ -/** +/* * @test * @bug 8173978 * @build m3/* m4/* m5/* Unnamed Unnamed1 - * @run testng/othervm m3/jdk.test.ModuleAccessTest + * @run junit/othervm m3/jdk.test.ModuleAccessTest * @summary Basic test case for module access checks and Lookup.in and * MethodHandles.privateLookupIn */ diff --git a/test/jdk/java/lang/invoke/modules/m1/module-info.java b/test/jdk/java/lang/invoke/modules/m1/module-info.java index db03841b4d0..ecd133ae6a1 100644 --- a/test/jdk/java/lang/invoke/modules/m1/module-info.java +++ b/test/jdk/java/lang/invoke/modules/m1/module-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,6 +22,6 @@ */ module m1 { requires m2; - requires org.testng; + requires org.junit.platform.console.standalone; exports p1; } diff --git a/test/jdk/java/lang/invoke/modules/m1/p1/Main.java b/test/jdk/java/lang/invoke/modules/m1/p1/Main.java index 0a4d2fff1db..5a2a7c91999 100644 --- a/test/jdk/java/lang/invoke/modules/m1/p1/Main.java +++ b/test/jdk/java/lang/invoke/modules/m1/p1/Main.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,26 +30,24 @@ import java.lang.invoke.MethodType; import static java.lang.invoke.MethodHandles.Lookup.*; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; /** * Basic test case for module access checks and Lookup.in. */ - -@Test public class Main { - private Class p1_Type1; // m1, exported - private Class p2_Type2; // m1, not exported - private Class q1_Type1; // m2, exported - private Class q2_Type2; // m2, not exported - private Class signalClass; // java.base, not exported - private Class unnamedClass; // class in unnamed module + private static Class p1_Type1; // m1, exported + private static Class p2_Type2; // m1, not exported + private static Class q1_Type1; // m2, exported + private static Class q2_Type2; // m2, not exported + private static Class signalClass; // java.base, not exported + private static Class unnamedClass; // class in unnamed module - @BeforeTest - public void setup() throws Exception { + @BeforeAll + public static void setup() throws Exception { try { p1_Type1 = Class.forName("p1.Type1"); p2_Type2 = Class.forName("p2.Type2"); @@ -64,15 +62,15 @@ public class Main { // check setup Module m1 = ModuleLayer.boot().findModule("m1").orElse(null); assertNotNull(m1); - assertTrue(p1_Type1.getModule() == m1); - assertTrue(p2_Type2.getModule() == m1); + assertSame(m1, p1_Type1.getModule()); + assertSame(m1, p2_Type2.getModule()); assertTrue(m1.isExported("p1")); assertFalse(m1.isExported("p2")); Module m2 = ModuleLayer.boot().findModule("m2").orElse(null); assertNotNull(m2); - assertTrue(q1_Type1.getModule() == m2); - assertTrue(q2_Type2.getModule() == m2); + assertSame(m2, q1_Type1.getModule()); + assertSame(m2, q2_Type2.getModule()); assertTrue(m2.isExported("q1")); assertFalse(m2.isExported("q2")); @@ -91,9 +89,10 @@ public class Main { * [A2] can access public types in packages exported by modules that m1 reads * [A3] cannot access public types in non-exported modules of modules that m1 reads */ + @Test public void testLookup() throws Exception { Lookup lookup = MethodHandles.lookup(); - assertTrue((lookup.lookupModes() & MODULE) == MODULE); // [A0] + assertEquals(MODULE, lookup.lookupModes() & MODULE); // [A0] // m1 findConstructor(lookup, p1_Type1, void.class); // [A1] @@ -116,9 +115,10 @@ public class Main { * * [A0] module and public access is not lost */ + @Test public void testToSameModule() throws Exception { Lookup lookup = MethodHandles.lookup().in(p2_Type2); - assertTrue(lookup.lookupModes() == (MODULE|PUBLIC)); // [A0] + assertEquals(MODULE | PUBLIC, lookup.lookupModes()); // [A0] // m1 findConstructor(lookup, p1_Type1, void.class); @@ -142,15 +142,16 @@ public class Main { * [A0] has PUBLIC access if accessible; otherwise no access * [A1] old lookup class becomes previous lookup class */ + @Test public void testFromNamedToNamedModule() throws Exception { // m2/q1_Type1 is accessible to m1 whereas m2/q_Type2 is not accessible Lookup lookup = MethodHandles.lookup().in(q1_Type1); - assertTrue(lookup.lookupModes() == PUBLIC); // [A0] - assertTrue(lookup.previousLookupClass() == Main.class); // [A1] + assertEquals(PUBLIC, lookup.lookupModes()); // [A0] + assertSame(Main.class, lookup.previousLookupClass()); // [A1] Lookup lookup2 = MethodHandles.lookup().in(q2_Type2); - assertTrue(lookup2.lookupModes() == 0); // [A0] - assertTrue(lookup2.previousLookupClass() == Main.class); // [A1] + assertEquals(0, lookup2.lookupModes()); // [A0] + assertSame(Main.class, lookup2.previousLookupClass()); // [A1] // m1 findConstructorExpectingIAE(lookup, p1_Type1, void.class); @@ -185,9 +186,10 @@ public class Main { * * [A0] has PUBLIC access */ + @Test public void testFromNamedToUnnamedModule() throws Exception { Lookup lookup = MethodHandles.lookup().in(unnamedClass); - assertTrue(lookup.lookupModes() == PUBLIC); // [A0] + assertEquals(PUBLIC, lookup.lookupModes()); // [A0] // m1 findConstructor(lookup, p1_Type1, void.class); // p1 is exported @@ -210,10 +212,11 @@ public class Main { * * [A0] retains PUBLIC access */ + @Test public void testFromUnnamedToNamedModule() throws Exception { Lookup lookup = MethodHandles.lookup(); lookup = MethodHandles.privateLookupIn(unnamedClass, lookup).in(p1_Type1); - assertTrue(lookup.lookupModes() == PUBLIC); // A0 + assertEquals(PUBLIC, lookup.lookupModes()); // A0 // m1 findConstructor(lookup, p1_Type1, void.class); @@ -236,9 +239,10 @@ public class Main { * * [A0] has UNCONDITIONAL access */ + @Test public void testPublicLookup() throws Exception { Lookup lookup = MethodHandles.publicLookup(); - assertTrue(lookup.lookupModes() == UNCONDITIONAL); // A0 + assertEquals(UNCONDITIONAL, lookup.lookupModes()); // A0 // m1 findConstructor(lookup, p1_Type1, void.class); @@ -261,9 +265,10 @@ public class Main { * * [A0] has UNCONDITIONAL access */ + @Test public void testPublicLookupToBaseModule() throws Exception { Lookup lookup = MethodHandles.publicLookup().in(String.class); - assertTrue(lookup.lookupModes() == UNCONDITIONAL); // A0 + assertEquals(UNCONDITIONAL, lookup.lookupModes()); // A0 // m1 findConstructor(lookup, p1_Type1, void.class); @@ -287,9 +292,10 @@ public class Main { * * [A0] has UNCONDITIONAL access */ + @Test public void testPublicLookupToAccessibleTypeInNamedModule() throws Exception { Lookup lookup = MethodHandles.publicLookup().in(p1_Type1); - assertTrue(lookup.lookupModes() == UNCONDITIONAL); // A0 + assertEquals(UNCONDITIONAL, lookup.lookupModes()); // A0 // m1 findConstructor(lookup, p1_Type1, void.class); @@ -312,9 +318,10 @@ public class Main { * * [A0] has no access */ + @Test public void testPublicLookupToInaccessibleTypeInNamedModule() throws Exception { Lookup lookup = MethodHandles.publicLookup().in(p2_Type2); - assertTrue(lookup.lookupModes() == 0); // A0 + assertEquals(0, lookup.lookupModes()); // A0 // m1 findConstructorExpectingIAE(lookup, p1_Type1, void.class); @@ -337,9 +344,10 @@ public class Main { * * [A0] has UNCONDITIONAL access */ + @Test public void testPublicLookupToUnnamedModule() throws Exception { Lookup lookup = MethodHandles.publicLookup().in(unnamedClass); - assertTrue(lookup.lookupModes() == UNCONDITIONAL); // A0 + assertEquals(UNCONDITIONAL, lookup.lookupModes()); // A0 // m1 findConstructor(lookup, p1_Type1, void.class); @@ -366,10 +374,7 @@ public class Main { Class clazz, Class rtype, Class... ptypes) throws Exception { - try { - findConstructor(lookup, clazz, rtype, ptypes); - assertTrue(false); - } catch (IllegalAccessException expected) { } + assertThrows(IllegalAccessException.class, () -> findConstructor(lookup, clazz, rtype, ptypes)); } /** diff --git a/test/jdk/java/lang/invoke/modules/m3/jdk/test/ModuleAccessTest.java b/test/jdk/java/lang/invoke/modules/m3/jdk/test/ModuleAccessTest.java index 6a1e8efe103..235c712926d 100644 --- a/test/jdk/java/lang/invoke/modules/m3/jdk/test/ModuleAccessTest.java +++ b/test/jdk/java/lang/invoke/modules/m3/jdk/test/ModuleAccessTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,15 +23,12 @@ package jdk.test; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles.Lookup; import java.lang.invoke.MethodType; +import java.lang.management.ThreadMXBean; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; @@ -42,7 +39,11 @@ import java.util.stream.Stream; import e1.CrackM5Access; import static java.lang.invoke.MethodHandles.Lookup.*; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; public class ModuleAccessTest { static ModuleLookup m3; @@ -55,8 +56,8 @@ public class ModuleAccessTest { static Class unnamed; static Class unnamed1; - @BeforeTest - public void setup() throws Exception { + @BeforeAll + public static void setup() throws Exception { m3 = new ModuleLookup("m3", 'C'); m4 = new ModuleLookup("m4", 'D'); m5 = new ModuleLookup("m5", 'E'); @@ -76,8 +77,7 @@ public class ModuleAccessTest { CrackM5Access.addReads(unnamed.getModule()); } - @DataProvider(name = "samePackage") - public Object[][] samePackage() throws Exception { + public static Object[][] samePackage() throws Exception { return new Object[][] { { m3.lookup, m3.type2 }, { privLookupIn, m3.type1 }, @@ -93,7 +93,8 @@ public class ModuleAccessTest { * [A1] no change in previous lookup class * [A2] PROTECTED, PRIVATE and ORIGINAL are dropped */ - @Test(dataProvider = "samePackage") + @ParameterizedTest + @MethodSource("samePackage") public void testLookupInSamePackage(Lookup lookup, Class targetClass) throws Exception { Class lookupClass = lookup.lookupClass(); Lookup lookup2 = lookup.in(targetClass); @@ -105,8 +106,7 @@ public class ModuleAccessTest { assertTrue(lookup2.lookupModes() == (lookup.lookupModes() & ~(PROTECTED|PRIVATE|ORIGINAL))); // [A2] } - @DataProvider(name = "sameModule") - public Object[][] sameModule() throws Exception { + public static Object[][] sameModule() throws Exception { return new Object[][] { { m3.lookup, m3.type3}, { privLookupIn, m3.type3}, @@ -121,20 +121,20 @@ public class ModuleAccessTest { * [A1] no change in previous lookup class * [A2] PROTECTED, PRIVATE, PACKAGE and ORIGINAL are dropped */ - @Test(dataProvider = "sameModule") + @ParameterizedTest + @MethodSource("sameModule") public void testLookupInSameModule(Lookup lookup, Class targetClass) throws Exception { Class lookupClass = lookup.lookupClass(); Lookup lookup2 = lookup.in(targetClass); - assertTrue(lookupClass.getPackage() != targetClass.getPackage()); - assertTrue(lookupClass.getModule() == targetClass.getModule()); - assertTrue(lookup2.lookupClass() == targetClass); // [A0] - assertTrue(lookup2.previousLookupClass() == lookup.previousLookupClass()); // [A1] - assertTrue(lookup2.lookupModes() == (lookup.lookupModes() & ~(PROTECTED|PRIVATE|PACKAGE|ORIGINAL))); // [A2] + assertNotSame(targetClass.getPackage(), lookupClass.getPackage()); + assertSame(targetClass.getModule(), lookupClass.getModule()); + assertSame(targetClass, lookup2.lookupClass()); // [A0] + assertSame(lookup.previousLookupClass(), lookup2.previousLookupClass()); // [A1] + assertEquals(lookup.lookupModes() & ~(PROTECTED | PRIVATE | PACKAGE | ORIGINAL), lookup2.lookupModes()); // [A2] } - @DataProvider(name = "anotherModule") - public Object[][] anotherModule() throws Exception { + public static Object[][] anotherModule() throws Exception { return new Object[][] { { m3.lookup, m4.type1, m5, m5.accessibleTypesTo(m3.module, m4.module) }, { m4.lookup, m5.type2, m3, m3.accessibleTypesTo(m4.module, m5.module) }, @@ -154,21 +154,22 @@ public class ModuleAccessTest { * [A5] can access public types in m1 exported to m0 * [A6] can access public types in m2 exported to m0 and m1 */ - @Test(dataProvider = "anotherModule") + @ParameterizedTest + @MethodSource("anotherModule") public void testLookupInAnotherModule(Lookup lookup, Class targetClass, ModuleLookup m2, Set> otherTypes) throws Exception { Class lookupClass = lookup.lookupClass(); Module m0 = lookupClass.getModule(); Module m1 = targetClass.getModule(); - assertTrue(m0 != m1); + assertNotSame(m1, m0); assertTrue(m0.canRead(m1)); assertTrue(m1.isExported(targetClass.getPackageName(), m0)); Lookup lookup2 = lookup.in(targetClass); - assertTrue(lookup2.lookupClass() == targetClass); // [A0] - assertTrue(lookup2.previousLookupClass() == lookup.lookupClass()); // [A1] - assertTrue(lookup2.lookupModes() == (lookup.lookupModes() & ~(PROTECTED|PRIVATE|PACKAGE|MODULE|ORIGINAL))); // [A2] + assertSame(targetClass, lookup2.lookupClass()); // [A0] + assertSame(lookup.lookupClass(), lookup2.previousLookupClass()); // [A1] + assertEquals(lookup.lookupModes() & ~(PROTECTED | PRIVATE | PACKAGE | MODULE | ORIGINAL), lookup2.lookupModes()); // [A2] // [A3] no access to module internal type in m0 // [A4] if m1 reads m0, @@ -207,7 +208,7 @@ public class ModuleAccessTest { // [A5] can access public types exported from m2 unconditionally // [A5] can access public types exported from m2 to m0 and m1 for (Class type : otherTypes) { - assertTrue(type.getModule() == m2.module); + assertSame(m2.module, type.getModule()); testAccess(lookup2, type); } @@ -215,10 +216,7 @@ public class ModuleAccessTest { for (Class type : Set.of(m2.type1, m2.type2, m2.type3)) { if (!otherTypes.contains(type)) { // type is accessible to this lookup - try { - lookup2.accessClass(type); - assertTrue(false); - } catch (IllegalAccessException e) {} + assertThrows(IllegalAccessException.class, () -> lookup2.accessClass(type)); findConstructorExpectingIAE(lookup2, type, void.class); } @@ -227,7 +225,7 @@ public class ModuleAccessTest { public void testAccess(Lookup lookup, Class type) throws Exception { // type is accessible to this lookup - assertTrue(lookup.accessClass(type) == type); + assertSame(type, lookup.accessClass(type)); // can find constructor findConstructor(lookup, type, void.class); @@ -237,28 +235,27 @@ public class ModuleAccessTest { Module m2 = type.getModule(); assertTrue(m0 != m1 && m0 != null); - assertTrue((lookup.lookupModes() & MODULE) == 0); + assertEquals(0, lookup.lookupModes() & MODULE); assertTrue(m0 != m2 || m1 != m2); MethodHandles.Lookup lookup2 = lookup.in(type); if (m2 == m1) { // the same module of the lookup class - assertTrue(lookup2.lookupClass() == type); - assertTrue(lookup2.previousLookupClass() == lookup.previousLookupClass()); + assertSame(type, lookup2.lookupClass()); + assertSame(lookup.previousLookupClass(), lookup2.previousLookupClass()); } else if (m2 == m0) { // hop back to the module of the previous lookup class - assertTrue(lookup2.lookupClass() == type); - assertTrue(lookup2.previousLookupClass() == lookup.lookupClass()); + assertSame(type, lookup2.lookupClass()); + assertSame(lookup.lookupClass(), lookup2.previousLookupClass()); } else { // hop to a third module - assertTrue(lookup2.lookupClass() == type); - assertTrue(lookup2.previousLookupClass() == lookup.lookupClass()); - assertTrue(lookup2.lookupModes() == 0); + assertSame(type, lookup2.lookupClass()); + assertSame(lookup.lookupClass(), lookup2.previousLookupClass()); + assertEquals(0, lookup2.lookupModes()); } } - @DataProvider(name = "thirdModule") - public Object[][] thirdModule() throws Exception { + public static Object[][] thirdModule() throws Exception { return new Object[][] { { m3.lookup, m4.type1, m5.type1}, { m3.lookup, m4.type2, m5.type1}, @@ -273,7 +270,8 @@ public class ModuleAccessTest { * [A1] c1 becomes previous lookup class * [A2] all access bits are dropped */ - @Test(dataProvider = "thirdModule") + @ParameterizedTest + @MethodSource("thirdModule") public void testLookupInThirdModule(Lookup lookup, Class c1, Class c2) throws Exception { Class c0 = lookup.lookupClass(); Module m0 = c0.getModule(); @@ -287,18 +285,17 @@ public class ModuleAccessTest { assertTrue(m2.isExported(c2.getPackageName(), m0) && m2.isExported(c2.getPackageName(), m1)); Lookup lookup1 = lookup.in(c1); - assertTrue(lookup1.lookupClass() == c1); - assertTrue(lookup1.previousLookupClass() == c0); - assertTrue(lookup1.lookupModes() == (lookup.lookupModes() & ~(PROTECTED|PRIVATE|PACKAGE|MODULE|ORIGINAL))); + assertSame(c1, lookup1.lookupClass()); + assertSame(c0, lookup1.previousLookupClass()); + assertEquals(lookup.lookupModes() & ~(PROTECTED | PRIVATE | PACKAGE | MODULE | ORIGINAL), lookup1.lookupModes()); Lookup lookup2 = lookup1.in(c2); - assertTrue(lookup2.lookupClass() == c2); // [A0] - assertTrue(lookup2.previousLookupClass() == c1); // [A1] - assertTrue(lookup2.lookupModes() == 0, lookup2.toString()); // [A2] + assertSame(c2, lookup2.lookupClass()); // [A0] + assertSame(c1, lookup2.previousLookupClass()); // [A1] + assertEquals(0, lookup2.lookupModes(), lookup2.toString()); // [A2] } - @DataProvider(name = "privLookupIn") - public Object[][] privLookupIn() throws Exception { + public static Object[][] privLookupIn() throws Exception { return new Object[][] { { m3.lookup, m4.type1 }, { m3.lookup, m5.type1 }, @@ -316,24 +313,22 @@ public class ModuleAccessTest { * [A2] the lookup class becomes previous lookup class * [A3] IAE thrown if lookup has no MODULE access */ - @Test(dataProvider = "privLookupIn") + @ParameterizedTest + @MethodSource("privLookupIn") public void testPrivateLookupIn(Lookup lookup, Class targetClass) throws Exception { Module m0 = lookup.lookupClass().getModule(); Module m1 = targetClass.getModule(); // privateLookupIn from m0 to m1 - assertTrue(m0 != m1); + assertNotSame(m1, m0); assertTrue(m1.isOpen(targetClass.getPackageName(), m0)); Lookup privLookup1 = MethodHandles.privateLookupIn(targetClass, lookup); - assertTrue(privLookup1.lookupModes() == (PROTECTED|PRIVATE|PACKAGE|PUBLIC)); // [A0] - assertTrue(privLookup1.lookupClass() == targetClass); // [A1] - assertTrue(privLookup1.previousLookupClass() == lookup.lookupClass()); // [A2] + assertEquals(PROTECTED | PRIVATE | PACKAGE | PUBLIC, privLookup1.lookupModes()); // [A0] + assertSame(targetClass, privLookup1.lookupClass()); // [A1] + assertSame(lookup.lookupClass(), privLookup1.previousLookupClass()); // [A2] // privLookup1 has no MODULE access; can't do privateLookupIn - try { - Lookup privLookup2 = MethodHandles.privateLookupIn(targetClass, privLookup1); // [A3] - assertFalse(privLookup2 != null); - } catch (IllegalAccessException e) {} + assertThrows(IllegalAccessException.class, () -> MethodHandles.privateLookupIn(targetClass, privLookup1)); // [A3] } /** @@ -343,9 +338,9 @@ public class ModuleAccessTest { public void testPrivateLookupAccess() throws Exception { Class staticsClass = e1.Statics.class; Lookup privLookup1 = MethodHandles.privateLookupIn(staticsClass, m4.lookup); - assertTrue((privLookup1.lookupModes() & MODULE) == 0); - assertTrue(privLookup1.lookupClass() == staticsClass); - assertTrue(privLookup1.previousLookupClass() == m4.lookup.lookupClass()); + assertEquals(0, (privLookup1.lookupModes() & MODULE)); + assertSame(staticsClass, privLookup1.lookupClass()); + assertSame(m4.lookup.lookupClass(), privLookup1.previousLookupClass()); // access private member and default package member in m5 MethodType mtype = MethodType.methodType(void.class); @@ -365,12 +360,9 @@ public class ModuleAccessTest { // lose private access Lookup privLookup2 = MethodHandles.privateLookupIn(m5.type1, m4.lookup); Lookup lookup = privLookup2.in(staticsClass); - assertTrue((lookup.lookupModes() & PRIVATE) == 0); + assertEquals(0, lookup.lookupModes() & PRIVATE); MethodHandle mh3 = lookup.findStatic(staticsClass, "packageMethod", mtype); - try { - lookup.findStatic(staticsClass, "privateMethod", mtype); - assertTrue(false); - } catch (IllegalAccessException e) {} + assertThrows(IllegalAccessException.class, () -> lookup.findStatic(staticsClass, "privateMethod", mtype)); } /** @@ -380,16 +372,16 @@ public class ModuleAccessTest { @Test public void testDropLookupMode() throws Exception { Lookup lookup = MethodHandles.privateLookupIn(m5.type1, m4.lookup); - assertTrue((lookup.lookupModes() & MODULE) == 0); + assertEquals(0, lookup.lookupModes() & MODULE); Lookup lookup1 = lookup.dropLookupMode(PRIVATE); - assertTrue(lookup1.lookupModes() == (lookup.lookupModes() & ~(PROTECTED|PRIVATE))); + assertEquals(lookup1.lookupModes(), lookup.lookupModes() & ~(PROTECTED | PRIVATE)); Lookup lookup2 = lookup.dropLookupMode(PACKAGE); - assertTrue(lookup2.lookupModes() == (lookup.lookupModes() & ~(PROTECTED|PRIVATE|PACKAGE))); + assertEquals(lookup2.lookupModes(), lookup.lookupModes() & ~(PROTECTED | PRIVATE | PACKAGE)); Lookup lookup3 = lookup.dropLookupMode(MODULE); - assertTrue(lookup3.lookupModes() == (lookup.lookupModes() & ~(PROTECTED|PRIVATE|PACKAGE))); + assertEquals(lookup3.lookupModes(), lookup.lookupModes() & ~(PROTECTED | PRIVATE | PACKAGE)); Lookup lookup4 = lookup.dropLookupMode(PUBLIC); - assertTrue(lookup4.lookupModes() == 0); + assertEquals(0, lookup4.lookupModes()); } @@ -406,11 +398,8 @@ public class ModuleAccessTest { // drop MODULE access i.e. only PUBLIC access Lookup lookup = privLookup.dropLookupMode(MODULE); - assertTrue(lookup.lookupModes() == PUBLIC); - try { - MethodHandle mh2 = lookup.findStatic(nonPUblicType, "publicStatic", mtype); - assertFalse(mh2 != null); - } catch (IllegalAccessException e) {} + assertEquals(PUBLIC, lookup.lookupModes()); + assertThrows(IllegalAccessException.class, () -> lookup.findStatic(nonPUblicType, "publicStatic", mtype)); } @Test @@ -421,21 +410,18 @@ public class ModuleAccessTest { Lookup pub3 = pub2.in(java.lang.management.ThreadMXBean.class); Lookup pub4 = pub3.dropLookupMode(UNCONDITIONAL); - assertTrue(publicLookup.lookupClass() == Object.class); - assertTrue(publicLookup.lookupModes() == UNCONDITIONAL); - assertTrue(pub1.lookupClass() == m3.type1); - assertTrue(pub1.lookupModes() == UNCONDITIONAL); - assertTrue(pub2.lookupClass() == String.class); - assertTrue(pub2.lookupModes() == UNCONDITIONAL); - assertTrue(pub3.lookupClass() == java.lang.management.ThreadMXBean.class); - assertTrue(pub3.lookupModes() == UNCONDITIONAL); - assertTrue(pub4.lookupModes() == 0); + assertSame(Object.class, publicLookup.lookupClass()); + assertEquals(UNCONDITIONAL, publicLookup.lookupModes()); + assertSame(m3.type1, pub1.lookupClass()); + assertEquals(UNCONDITIONAL, pub1.lookupModes()); + assertSame(String.class, pub2.lookupClass()); + assertEquals(UNCONDITIONAL, pub2.lookupModes()); + assertSame(ThreadMXBean.class, pub3.lookupClass()); + assertEquals(UNCONDITIONAL, pub3.lookupModes()); + assertEquals(0, pub4.lookupModes()); // publicLookup has no MODULE access; can't do privateLookupIn - try { - Lookup pub5 = MethodHandles.privateLookupIn(m4.type1, pub1); - assertFalse(pub5 != null); - } catch (IllegalAccessException e) {} + assertThrows(IllegalAccessException.class, () -> MethodHandles.privateLookupIn(m4.type1, pub1)); } static class ModuleLookup { @@ -548,10 +534,7 @@ public class ModuleAccessTest { Class clazz, Class rtype, Class... ptypes) throws Exception { - try { - MethodHandle mh = findConstructor(lookup, clazz, rtype, ptypes); - assertTrue(false); - } catch (IllegalAccessException expected) { } + assertThrows(IllegalAccessException.class, () -> findConstructor(lookup, clazz, rtype, ptypes)); } /** diff --git a/test/jdk/java/lang/invoke/modules/m3/module-info.java b/test/jdk/java/lang/invoke/modules/m3/module-info.java index 1f47c42c196..c9d8fab20a5 100644 --- a/test/jdk/java/lang/invoke/modules/m3/module-info.java +++ b/test/jdk/java/lang/invoke/modules/m3/module-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ module m3 { requires m4; requires m5; - requires org.testng; + requires org.junit.platform.console.standalone; requires java.management; exports c1; opens c2 to m5; diff --git a/test/jdk/java/lang/module/ModuleReader/ModuleReaderTest.java b/test/jdk/java/lang/module/ModuleReader/ModuleReaderTest.java index 61e5914798e..6217a4a8954 100644 --- a/test/jdk/java/lang/module/ModuleReader/ModuleReaderTest.java +++ b/test/jdk/java/lang/module/ModuleReader/ModuleReaderTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ * @build ModuleReaderTest * jdk.test.lib.compiler.CompilerUtils * jdk.test.lib.util.JarUtils - * @run testng ModuleReaderTest + * @run junit ModuleReaderTest * @summary Basic tests for java.lang.module.ModuleReader */ @@ -48,22 +48,24 @@ import java.nio.ByteBuffer; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Optional; import java.util.Set; -import java.util.stream.Collectors; import java.util.spi.ToolProvider; import java.util.stream.Stream; import jdk.internal.module.ModulePath; import jdk.test.lib.compiler.CompilerUtils; import jdk.test.lib.util.JarUtils; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; public class ModuleReaderTest { private static final String TEST_SRC = System.getProperty("test.src"); @@ -150,8 +152,8 @@ public class ModuleReaderTest { "p\\Main.class" }; - @BeforeTest - public void compileTestModule() throws Exception { + @BeforeAll + public static void compileTestModule() throws Exception { // javac -d mods/$TESTMODULE src/$TESTMODULE/** boolean compiled = CompilerUtils.compile(SRC_DIR.resolve(TEST_MODULE), MODS_DIR.resolve(TEST_MODULE)); @@ -187,51 +189,29 @@ public class ModuleReaderTest { Optional ouri = reader.find(name); ouri.ifPresent(uri -> { if (name.endsWith("/")) - assertTrue(uri.toString().endsWith("/")); + assertTrue(uri.toString().endsWith("/"), + "mismatched directory URI for '" + name + "': " + uri); }); } // test "not found" in java.base module for (String name : NOT_BASE_RESOURCES) { - assertFalse(reader.find(name).isPresent()); - assertFalse(reader.open(name).isPresent()); - assertFalse(reader.read(name).isPresent()); + assertFalse(reader.find(name).isPresent(), "Unexpected resource found: " + name); + assertFalse(reader.open(name).isPresent(), "Unexpected resource opened: " + name); + assertFalse(reader.read(name).isPresent(), "Unexpected resource read: " + name); } // test nulls - try { - reader.find(null); - assertTrue(false); - } catch (NullPointerException expected) { } - - try { - reader.open(null); - assertTrue(false); - } catch (NullPointerException expected) { } - - try { - reader.read(null); - assertTrue(false); - } catch (NullPointerException expected) { } - - try { - reader.release(null); - assertTrue(false); - } catch (NullPointerException expected) { } - + assertThrows(NullPointerException.class, () -> reader.find(null)); + assertThrows(NullPointerException.class, () -> reader.open(null)); + assertThrows(NullPointerException.class, () -> reader.read(null)); + assertThrows(NullPointerException.class, () -> reader.release(null)); } // test closed ModuleReader - try { - reader.open(BASE_RESOURCES[0]); - assertTrue(false); - } catch (IOException expected) { } - - - try { - reader.read(BASE_RESOURCES[0]); - assertTrue(false); - } catch (IOException expected) { } + assertThrows(IOException.class, () -> reader.open(BASE_RESOURCES[0])); + assertThrows(IOException.class, () -> reader.read(BASE_RESOURCES[0])); + assertThrows(IOException.class, reader::list); } /** @@ -268,10 +248,10 @@ public class ModuleReaderTest { String jmod = dir.resolve("m.jmod").toString(); String[] args = { "create", "--class-path", cp, jmod }; ToolProvider jmodTool = ToolProvider.findFirst("jmod") - .orElseThrow(() -> - new RuntimeException("jmod tool not found") - ); - assertEquals(jmodTool.run(System.out, System.out, args), 0); + .orElseThrow(() -> + new RuntimeException("jmod tool not found") + ); + assertEquals(0, jmodTool.run(System.out, System.out, args), "jmod tool failed"); test(dir); } @@ -307,57 +287,30 @@ public class ModuleReaderTest { Optional ouri = reader.find(name); ouri.ifPresent(uri -> { if (name.endsWith("/")) - assertTrue(uri.toString().endsWith("/")); + assertTrue(uri.toString().endsWith("/"), + "mismatched directory URI for '" + name + "': " + uri); }); } // test "not found" in test module for (String name : NOT_TEST_RESOURCES) { System.out.println("resource: " + name); - assertFalse(reader.find(name).isPresent()); - assertFalse(reader.open(name).isPresent()); - assertFalse(reader.read(name).isPresent()); + assertFalse(reader.find(name).isPresent(), "Unexpected resource found: " + name); + assertFalse(reader.open(name).isPresent(), "Unexpected resource open: " + name); + assertFalse(reader.read(name).isPresent(), "Unexpected resource read: " + name); } // test nulls - try { - reader.find(null); - assertTrue(false); - } catch (NullPointerException expected) { } - - try { - reader.open(null); - assertTrue(false); - } catch (NullPointerException expected) { } - - try { - reader.read(null); - assertTrue(false); - } catch (NullPointerException expected) { } - - try { - reader.release(null); - throw new RuntimeException(); - } catch (NullPointerException expected) { } - + assertThrows(NullPointerException.class, () -> reader.find(null)); + assertThrows(NullPointerException.class, () -> reader.open(null)); + assertThrows(NullPointerException.class, () -> reader.read(null)); + assertThrows(NullPointerException.class, () -> reader.release(null)); } // test closed ModuleReader - try { - reader.open(TEST_RESOURCES[0]); - assertTrue(false); - } catch (IOException expected) { } - - - try { - reader.read(TEST_RESOURCES[0]); - assertTrue(false); - } catch (IOException expected) { } - - try { - reader.list(); - assertTrue(false); - } catch (IOException expected) { } + assertThrows(IOException.class, () -> reader.open(BASE_RESOURCES[0])); + assertThrows(IOException.class, () -> reader.read(BASE_RESOURCES[0])); + assertThrows(IOException.class, reader::list); } /** @@ -367,7 +320,7 @@ public class ModuleReaderTest { throws IOException { Optional ouri = reader.find(name); - assertTrue(ouri.isPresent()); + assertTrue(ouri.isPresent(), "missing URI for: " + name); URL url = ouri.get().toURL(); if (!url.getProtocol().equalsIgnoreCase("jmod")) { @@ -375,7 +328,7 @@ public class ModuleReaderTest { uc.setUseCaches(false); try (InputStream in = uc.getInputStream()) { byte[] bytes = in.readAllBytes(); - assertTrue(Arrays.equals(bytes, expectedBytes)); + assertArrayEquals(expectedBytes, bytes, "resource bytes differ for: " + name); } } } @@ -387,12 +340,10 @@ public class ModuleReaderTest { throws IOException { Optional oin = reader.open(name); - assertTrue(oin.isPresent()); - - InputStream in = oin.get(); - try (in) { + assertTrue(oin.isPresent(), "missing input stream for: " + name); + try (InputStream in = oin.get()) { byte[] bytes = in.readAllBytes(); - assertTrue(Arrays.equals(bytes, expectedBytes)); + assertArrayEquals(expectedBytes, bytes, "resource bytes differ for: " + name); } } @@ -408,10 +359,10 @@ public class ModuleReaderTest { ByteBuffer bb = obb.get(); try { int rem = bb.remaining(); - assertTrue(rem == expectedBytes.length); + assertEquals(expectedBytes.length, rem, "resource lengths differ: " + name); byte[] bytes = new byte[rem]; bb.get(bytes); - assertTrue(Arrays.equals(bytes, expectedBytes)); + assertArrayEquals(expectedBytes, bytes, "resource bytes differ: " + name); } finally { reader.release(bb); } @@ -426,14 +377,14 @@ public class ModuleReaderTest { list = stream.toList(); } Set names = new HashSet<>(list); - assertTrue(names.size() == list.size()); // no duplicates + assertEquals(names.size(), list.size(), "resource list contains duplicates: " + list); - assertTrue(names.contains("module-info.class")); - assertTrue(names.contains(name)); + assertTrue(names.contains("module-info.class"), "resource list did not contain 'module-info.class': " + list); + assertTrue(names.contains(name), "resource list did not contain '" + name + "'" + list); // all resources should be locatable via find for (String e : names) { - assertTrue(reader.find(e).isPresent()); + assertTrue(reader.find(e).isPresent(), "resource not found: " + name); } } diff --git a/test/jdk/java/lang/reflect/AccessibleObject/CanAccessTest.java b/test/jdk/java/lang/reflect/AccessibleObject/CanAccessTest.java index 45e2502b601..ac7a1bad31b 100644 --- a/test/jdk/java/lang/reflect/AccessibleObject/CanAccessTest.java +++ b/test/jdk/java/lang/reflect/AccessibleObject/CanAccessTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,11 +21,11 @@ * questions. */ -/** +/* * @test * @build CanAccessTest * @modules java.base/jdk.internal.misc:+open - * @run testng/othervm CanAccessTest + * @run junit/othervm CanAccessTest * @summary Test AccessibleObject::canAccess method */ @@ -34,31 +34,29 @@ import java.lang.reflect.Method; import java.security.SecureClassLoader; import jdk.internal.misc.Unsafe; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; -@Test public class CanAccessTest { private static Unsafe INSTANCE = Unsafe.getUnsafe(); /** * null object parameter for Constructor */ + @Test public void testConstructor() throws Exception { Constructor ctor = Unsafe.class.getDeclaredConstructor(); assertFalse(ctor.canAccess(null)); assertTrue(ctor.trySetAccessible()); - try { - // non-null object parameter - ctor.canAccess(INSTANCE); - assertTrue(false); - } catch (IllegalArgumentException expected) {} + // non-null object parameter + assertThrows(IllegalArgumentException.class, () -> ctor.canAccess(INSTANCE)); } /** * Test protected constructors */ + @Test public void testProtectedConstructor() throws Exception { TestLoader.testProtectedConstructorNonOpenedPackage(); @@ -69,21 +67,20 @@ public class CanAccessTest { /** * null object parameter for static members */ + @Test public void testStaticMember() throws Exception { Method m = Unsafe.class.getDeclaredMethod("throwIllegalAccessError"); assertFalse(m.canAccess(null)); assertTrue(m.trySetAccessible()); - try { - // non-null object parameter - m.canAccess(INSTANCE); - assertTrue(false); - } catch (IllegalArgumentException expected) { } + // non-null object parameter + assertThrows(IllegalArgumentException.class, () -> m.canAccess(INSTANCE)); } /** * Test protected static */ + @Test public void testProtectedStatic() throws Exception { Method m = TestLoader.testProtectedStatic(); assertFalse(m.canAccess(null)); @@ -93,28 +90,24 @@ public class CanAccessTest { * the specified object must be an instance of the declaring class * for instance members */ + @Test public void testInstanceMethod() throws Exception { Method m = Unsafe.class.getDeclaredMethod("allocateMemory0", long.class); assertFalse(m.canAccess(INSTANCE)); - try { - m.canAccess(null); - assertTrue(false); - } catch (IllegalArgumentException expected) { } + assertThrows(IllegalArgumentException.class, () -> m.canAccess(null)); } /** * the specified object must be an instance of the declaring class * for instance members */ + @Test public void testInvalidInstanceObject() throws Exception { Class clazz = Class.forName("sun.security.x509.X500Name"); Method m = clazz.getDeclaredMethod("size"); - try { - m.canAccess(INSTANCE); - assertTrue(false); - } catch (IllegalArgumentException expected) { } + assertThrows(IllegalArgumentException.class, () -> m.canAccess(INSTANCE)); } diff --git a/test/jdk/java/lang/reflect/AccessibleObject/ModuleSetAccessibleTest.java b/test/jdk/java/lang/reflect/AccessibleObject/ModuleSetAccessibleTest.java index 45cebdb552b..7d79a1ac49b 100644 --- a/test/jdk/java/lang/reflect/AccessibleObject/ModuleSetAccessibleTest.java +++ b/test/jdk/java/lang/reflect/AccessibleObject/ModuleSetAccessibleTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,12 +21,12 @@ * questions. */ -/** +/* * @test * @build ModuleSetAccessibleTest * @modules java.base/java.lang:open * java.base/jdk.internal.misc:+open - * @run testng/othervm ModuleSetAccessibleTest + * @run junit/othervm ModuleSetAccessibleTest * @summary Test java.lang.reflect.AccessibleObject with modules */ @@ -40,22 +40,19 @@ import java.security.ProtectionDomain; import jdk.internal.misc.Unsafe; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; -@Test public class ModuleSetAccessibleTest { /** * Invoke a private constructor on a public class in an exported package */ + @Test public void testPrivateConstructorInExportedPackage() throws Exception { Constructor ctor = Unsafe.class.getDeclaredConstructor(); - try { - ctor.newInstance(); - assertTrue(false); - } catch (IllegalAccessException expected) { } + assertThrows(IllegalAccessException.class, () -> ctor.newInstance()); ctor.setAccessible(true); Unsafe unsafe = (Unsafe) ctor.newInstance(); @@ -65,34 +62,26 @@ public class ModuleSetAccessibleTest { /** * Invoke a private method on a public class in an exported package */ + @Test public void testPrivateMethodInExportedPackage() throws Exception { Method m = Unsafe.class.getDeclaredMethod("throwIllegalAccessError"); - try { - m.invoke(null); - assertTrue(false); - } catch (IllegalAccessException expected) { } + assertThrows(IllegalAccessException.class, () -> m.invoke(null)); m.setAccessible(true); - try { - m.invoke(null); - assertTrue(false); - } catch (InvocationTargetException e) { - // thrown by throwIllegalAccessError - assertTrue(e.getCause() instanceof IllegalAccessError); - } + InvocationTargetException e = assertThrows(InvocationTargetException.class, () -> + m.invoke(null)); + // thrown by throwIllegalAccessError + assertInstanceOf(IllegalAccessError.class, e.getCause()); } /** * Access a private field in a public class that is an exported package */ + @Test public void testPrivateFieldInExportedPackage() throws Exception { Field f = Unsafe.class.getDeclaredField("theUnsafe"); - - try { - f.get(null); - assertTrue(false); - } catch (IllegalAccessException expected) { } + assertThrows(IllegalAccessException.class, () -> f.get(null)); f.setAccessible(true); Unsafe unsafe = (Unsafe) f.get(null); @@ -102,19 +91,14 @@ public class ModuleSetAccessibleTest { /** * Invoke a public constructor on a public class in a non-exported package */ + @Test public void testPublicConstructorInNonExportedPackage() throws Exception { Class clazz = Class.forName("sun.security.x509.X500Name"); Constructor ctor = clazz.getConstructor(String.class); - try { - ctor.newInstance("cn=duke"); - assertTrue(false); - } catch (IllegalAccessException expected) { } + assertThrows(IllegalAccessException.class, () -> ctor.newInstance("cn=duke")); - try { - ctor.setAccessible(true); - assertTrue(false); - } catch (InaccessibleObjectException expected) { } + assertThrows(InaccessibleObjectException.class, () -> ctor.setAccessible(true)); ctor.setAccessible(false); // should succeed } @@ -123,19 +107,14 @@ public class ModuleSetAccessibleTest { /** * Access a public field in a public class that in a non-exported package */ + @Test public void testPublicFieldInNonExportedPackage() throws Exception { Class clazz = Class.forName("sun.security.x509.X500Name"); Field f = clazz.getField("SERIALNUMBER_OID"); - try { - f.get(null); - assertTrue(false); - } catch (IllegalAccessException expected) { } + assertThrows(IllegalAccessException.class, () -> f.get(null)); - try { - f.setAccessible(true); - assertTrue(false); - } catch (InaccessibleObjectException expected) { } + assertThrows(InaccessibleObjectException.class, () -> f.setAccessible(true)); f.setAccessible(false); // should succeed } @@ -144,6 +123,7 @@ public class ModuleSetAccessibleTest { /** * Test that the Class constructor cannot be make accessible. */ + @Test public void testJavaLangClass() throws Exception { // non-public constructor @@ -152,15 +132,8 @@ public class ModuleSetAccessibleTest { ProtectionDomain.class, boolean.class, char.class); AccessibleObject[] ctors = { ctor }; - try { - ctor.setAccessible(true); - assertTrue(false); - } catch (SecurityException expected) { } - - try { - AccessibleObject.setAccessible(ctors, true); - assertTrue(false); - } catch (SecurityException expected) { } + assertThrows(SecurityException.class, () -> ctor.setAccessible(true)); + assertThrows(SecurityException.class, () -> AccessibleObject.setAccessible(ctors, true)); // should succeed ctor.setAccessible(false); diff --git a/test/jdk/java/lang/reflect/AccessibleObject/TrySetAccessibleTest.java b/test/jdk/java/lang/reflect/AccessibleObject/TrySetAccessibleTest.java index 774ee4d1dad..bd4d0fab23f 100644 --- a/test/jdk/java/lang/reflect/AccessibleObject/TrySetAccessibleTest.java +++ b/test/jdk/java/lang/reflect/AccessibleObject/TrySetAccessibleTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,14 +21,14 @@ * questions. */ -/** +/* * @test * @build TrySetAccessibleTest * @modules java.base/java.lang:open * java.base/jdk.internal.module * java.base/jdk.internal.perf * java.base/jdk.internal.misc:+open - * @run testng/othervm TrySetAccessibleTest + * @run junit/othervm TrySetAccessibleTest * @summary Test AccessibleObject::trySetAccessible method */ @@ -43,21 +43,18 @@ import jdk.internal.module.ModulePath; import jdk.internal.perf.Perf; import java.security.ProtectionDomain; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; -@Test public class TrySetAccessibleTest { /** * Invoke a private constructor on a public class in an exported package */ + @Test public void testPrivateConstructorInExportedPackage() throws Exception { Constructor ctor = Perf.class.getDeclaredConstructor(); - try { - ctor.newInstance(); - assertTrue(false); - } catch (IllegalAccessException expected) { } + assertThrows(IllegalAccessException.class, () -> ctor.newInstance()); assertFalse(ctor.trySetAccessible()); assertFalse(ctor.canAccess(null)); @@ -66,13 +63,11 @@ public class TrySetAccessibleTest { /** * Invoke a private constructor on a public class in an open package */ + @Test public void testPrivateConstructorInOpenedPackage() throws Exception { Constructor ctor = Unsafe.class.getDeclaredConstructor(); - try { - ctor.newInstance(); - assertTrue(false); - } catch (IllegalAccessException expected) { } + assertThrows(IllegalAccessException.class, () -> ctor.newInstance()); assertTrue(ctor.trySetAccessible()); assertTrue(ctor.canAccess(null)); @@ -82,12 +77,10 @@ public class TrySetAccessibleTest { /** * Invoke a private method on a public class in an exported package */ + @Test public void testPrivateMethodInExportedPackage() throws Exception { Method m = ModulePath.class.getDeclaredMethod("packageName", String.class); - try { - m.invoke(null); - assertTrue(false); - } catch (IllegalAccessException expected) { } + assertThrows(IllegalAccessException.class, () -> m.invoke(null)); assertFalse(m.trySetAccessible()); assertFalse(m.canAccess(null)); @@ -97,54 +90,42 @@ public class TrySetAccessibleTest { /** * Invoke a private method on a public class in an open package */ + @Test public void testPrivateMethodInOpenedPackage() throws Exception { Method m = Unsafe.class.getDeclaredMethod("throwIllegalAccessError"); assertFalse(m.canAccess(null)); - try { - m.invoke(null); - assertTrue(false); - } catch (IllegalAccessException expected) { } + assertThrows(IllegalAccessException.class, () -> m.invoke(null)); assertTrue(m.trySetAccessible()); assertTrue(m.canAccess(null)); - try { - m.invoke(null); - assertTrue(false); - } catch (InvocationTargetException e) { - // thrown by throwIllegalAccessError - assertTrue(e.getCause() instanceof IllegalAccessError); - } + + InvocationTargetException e = assertThrows(InvocationTargetException.class, () -> + m.invoke(null)); + assertInstanceOf(IllegalAccessError.class, e.getCause()); } /** * Invoke a private method on a public class in an exported package */ + @Test public void testPrivateFieldInExportedPackage() throws Exception { Field f = Perf.class.getDeclaredField("instance"); - try { - f.get(null); - assertTrue(false); - } catch (IllegalAccessException expected) { } + assertThrows(IllegalAccessException.class, () -> f.get(null)); assertFalse(f.trySetAccessible()); assertFalse(f.canAccess(null)); - try { - f.get(null); - assertTrue(false); - } catch (IllegalAccessException expected) {} + assertThrows(IllegalAccessException.class, () -> f.get(null)); } /** * Access a private field in a public class that is an exported package */ + @Test public void testPrivateFieldInOpenedPackage() throws Exception { Field f = Unsafe.class.getDeclaredField("theUnsafe"); - try { - f.get(null); - assertTrue(false); - } catch (IllegalAccessException expected) { } + assertThrows(IllegalAccessException.class, () -> f.get(null)); assertTrue(f.trySetAccessible()); assertTrue(f.canAccess(null)); @@ -155,32 +136,29 @@ public class TrySetAccessibleTest { /** * Invoke a public constructor on a public class in a non-exported package */ + @Test public void testPublicConstructorInNonExportedPackage() throws Exception { Class clazz = Class.forName("sun.security.x509.X500Name"); Constructor ctor = clazz.getConstructor(String.class); - try { - ctor.newInstance("cn=duke"); - assertTrue(false); - } catch (IllegalAccessException expected) { } + assertThrows(IllegalAccessException.class, () -> ctor.newInstance("cn=duke")); assertFalse(ctor.trySetAccessible()); assertFalse(ctor.canAccess(null)); - assertTrue(ctor.trySetAccessible() == ctor.isAccessible()); + assertFalse(ctor.trySetAccessible()); + assertFalse(ctor.isAccessible()); // should match trySetAccessible } /** * Access a public field in a public class that in a non-exported package */ + @Test public void testPublicFieldInNonExportedPackage() throws Exception { Class clazz = Class.forName("sun.security.x509.X500Name"); Field f = clazz.getField("SERIALNUMBER_OID"); - try { - f.get(null); - assertTrue(false); - } catch (IllegalAccessException expected) { } + assertThrows(IllegalAccessException.class, () -> f.get(null)); assertFalse(f.trySetAccessible()); assertFalse(f.canAccess(null)); @@ -190,6 +168,7 @@ public class TrySetAccessibleTest { /** * Test that the Class constructor cannot be make accessible. */ + @Test public void testJavaLangClass() throws Exception { // non-public constructor diff --git a/test/jdk/java/lang/reflect/ChainedReflection.java b/test/jdk/java/lang/reflect/ChainedReflection.java index 212a70345cd..bd76cd13fc8 100644 --- a/test/jdk/java/lang/reflect/ChainedReflection.java +++ b/test/jdk/java/lang/reflect/ChainedReflection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,9 +23,11 @@ /* * @test - * @run testng/othervm ChainedReflection + * @run junit/othervm ChainedReflection * @summary Test Method::invoke and Constructor::newInstance chained calls that * should wrap NPE in InvocationTargetException properly + * @comment This test is not using assertThrows given lambdas may affect the + * exception stack trace and therefore test anticipations */ import java.lang.reflect.Constructor; @@ -33,24 +35,28 @@ import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; import java.util.Optional; -import org.testng.annotations.Test; +import org.junit.jupiter.api.Test; public class ChainedReflection { - public ChainedReflection() {} - ChainedReflection(Void dummy) throws ReflectiveOperationException { - Method m = ChainedReflection.class.getMethod("throwNPE"); - try { - m.invoke(null); - } catch (InvocationTargetException e) { - Throwable t = e.getTargetException(); - if (t instanceof NullPointerException npe) { - throw npe; - } else { - throw new RuntimeException("Test failed (InvocationTargetException didn't wrap NullPointerException)"); + // This inner class is declared with a constructor that ctorCallMethodInvoke + // reflects on. Such a constructor cannot be declared in ChainedReflection + // because JUnit does not allow a test class to declare multiple constructors. + class Inner { + Inner() throws ReflectiveOperationException { + Method m = ChainedReflection.class.getMethod("throwNPE"); + try { + m.invoke(null); + } catch (InvocationTargetException e) { + Throwable t = e.getTargetException(); + if (t instanceof NullPointerException npe) { + throw npe; + } else { + throw new RuntimeException("Test failed (InvocationTargetException didn't wrap NullPointerException)"); + } + } catch (Throwable t) { + throw new RuntimeException("Test failed (Unexpected exception)", t); } - } catch (Throwable t) { - throw new RuntimeException("Test failed (Unexpected exception)", t); } } @@ -105,9 +111,9 @@ public class ChainedReflection { */ @Test public void ctorCallMethodInvoke() throws ReflectiveOperationException { - Constructor ctor = ChainedReflection.class.getDeclaredConstructor(Void.class); + Constructor ctor = ChainedReflection.Inner.class.getDeclaredConstructor(ChainedReflection.class); try { - ctor.newInstance((Void)null); + ctor.newInstance(this); } catch (InvocationTargetException e) { Throwable t = e.getTargetException(); if (!(t instanceof NullPointerException)) { diff --git a/test/jdk/java/lang/reflect/DefaultMethodMembers/FilterNotMostSpecific.java b/test/jdk/java/lang/reflect/DefaultMethodMembers/FilterNotMostSpecific.java index 1992f31d5de..b8738a383b0 100644 --- a/test/jdk/java/lang/reflect/DefaultMethodMembers/FilterNotMostSpecific.java +++ b/test/jdk/java/lang/reflect/DefaultMethodMembers/FilterNotMostSpecific.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 @@ * @bug 8029674 * @summary Verify that the right interface methods are returned by * Class.getMethod() and Class.getMethods() - * @run testng FilterNotMostSpecific + * @run junit FilterNotMostSpecific */ import java.lang.reflect.*; @@ -39,14 +39,14 @@ import java.util.HashMap; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; public class FilterNotMostSpecific { - @Test(dataProvider="getCases") + @ParameterizedTest + @MethodSource("getCases") public void testGetMethod(Class iface) { boolean match = false; MethodDesc[] expectedMethods = iface.getAnnotationsByType(MethodDesc.class); @@ -67,7 +67,8 @@ public class FilterNotMostSpecific { assert(match); } - @Test(dataProvider="getCases") + @ParameterizedTest + @MethodSource("getCases") public void testGetMethods(Class iface) { List foundMethods = filterObjectMethods(iface.getMethods()); MethodDesc[] expectedMethods = iface.getAnnotationsByType(MethodDesc.class); @@ -84,7 +85,7 @@ public class FilterNotMostSpecific { fail("On: "+ iface +"\nDid not find " + toMethodString(expected) + " among " + foundMethods); } - assertEquals(foundMethods.size(), expectedMethods.length, + assertEquals(expectedMethods.length, foundMethods.size(), "\non: " + iface + "\nexpected: " + toMethodStrings(expectedMethods) + "\nfound: " + foundMethods + "\n"); @@ -565,8 +566,7 @@ public class FilterNotMostSpecific { @MethodDesc(name="m", declaringClass=F.class, isGetMethodReturn=true) abstract class H extends G implements F {} - @DataProvider - public Object[][] getCases() { return CASES; } + public static Object[][] getCases() { return CASES; } public static final Class[][] CASES = { { K1.class }, { K1M.class }, diff --git a/test/jdk/java/lang/reflect/DefaultStaticTest/DefaultStaticInvokeTest.java b/test/jdk/java/lang/reflect/DefaultStaticTest/DefaultStaticInvokeTest.java index 215ee3dd66a..ff7d12502b3 100644 --- a/test/jdk/java/lang/reflect/DefaultStaticTest/DefaultStaticInvokeTest.java +++ b/test/jdk/java/lang/reflect/DefaultStaticTest/DefaultStaticInvokeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 @@ * in interfaces and/or in inheritance * @bug 7184826 * @build helper.Mod helper.Declared DefaultStaticTestData - * @run testng DefaultStaticInvokeTest + * @run junit DefaultStaticInvokeTest * @author Yong Lu */ @@ -40,23 +40,19 @@ import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertTrue; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.fail; -import org.testng.annotations.Test; - import static helper.Mod.*; import static helper.Declared.*; -import helper.Mod; +import static org.junit.jupiter.api.Assertions.*; +import helper.Mod; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; public class DefaultStaticInvokeTest { // getMethods(): Make sure getMethods returns the expected methods. - @Test(dataProvider = "testCasesAll", - dataProviderClass = DefaultStaticTestData.class) + @ParameterizedTest + @MethodSource({"DefaultStaticTestData#testClasses", "DefaultStaticTestData#testInterfaces"}) public void testGetMethods(String testTarget, Object param) throws Exception { testMethods(ALL_METHODS, testTarget, param); @@ -64,8 +60,8 @@ public class DefaultStaticInvokeTest { // getDeclaredMethods(): Make sure getDeclaredMethods returns the expected methods. - @Test(dataProvider = "testCasesAll", - dataProviderClass = DefaultStaticTestData.class) + @ParameterizedTest + @MethodSource({"DefaultStaticTestData#testClasses", "DefaultStaticTestData#testInterfaces"}) public void testGetDeclaredMethods(String testTarget, Object param) throws Exception { testMethods(DECLARED_ONLY, testTarget, param); @@ -73,8 +69,8 @@ public class DefaultStaticInvokeTest { // getMethod(): Make sure that getMethod finds all methods it should find. - @Test(dataProvider = "testCasesAll", - dataProviderClass = DefaultStaticTestData.class) + @ParameterizedTest + @MethodSource({"DefaultStaticTestData#testClasses", "DefaultStaticTestData#testInterfaces"}) public void testGetMethod(String testTarget, Object param) throws Exception { @@ -91,8 +87,8 @@ public class DefaultStaticInvokeTest { // getMethod(): Make sure that getMethod does *not* find certain methods. - @Test(dataProvider = "testCasesAll", - dataProviderClass = DefaultStaticTestData.class) + @ParameterizedTest + @MethodSource({"DefaultStaticTestData#testClasses", "DefaultStaticTestData#testInterfaces"}) public void testGetMethodSuperInterfaces(String testTarget, Object param) throws Exception { @@ -124,8 +120,8 @@ public class DefaultStaticInvokeTest { // Method.invoke(): Make sure Method.invoke returns the expected value. - @Test(dataProvider = "testCasesAll", - dataProviderClass = DefaultStaticTestData.class) + @ParameterizedTest + @MethodSource({"DefaultStaticTestData#testClasses", "DefaultStaticTestData#testInterfaces"}) public void testMethodInvoke(String testTarget, Object param) throws Exception { Class typeUnderTest = Class.forName(testTarget); @@ -141,8 +137,8 @@ public class DefaultStaticInvokeTest { // MethodHandle.invoke(): Make sure MethodHandle.invoke returns the expected value. - @Test(dataProvider = "testCasesAll", - dataProviderClass = DefaultStaticTestData.class) + @ParameterizedTest + @MethodSource({"DefaultStaticTestData#testClasses", "DefaultStaticTestData#testInterfaces"}) public void testMethodHandleInvoke(String testTarget, Object param) throws Throwable { Class typeUnderTest = Class.forName(testTarget); @@ -169,14 +165,14 @@ public class DefaultStaticInvokeTest { : (String) methodHandle.invoke(typeUnderTest.newInstance(), param); } - assertEquals(result, expectedReturn); + assertEquals(expectedReturn, result); } } // Lookup.findStatic / .findVirtual: Make sure IllegalAccessException is thrown as expected. - @Test(dataProvider = "testClasses", - dataProviderClass = DefaultStaticTestData.class) + @ParameterizedTest + @MethodSource("DefaultStaticTestData#testClasses") public void testIAE(String testTarget, Object param) throws ClassNotFoundException { @@ -189,14 +185,8 @@ public class DefaultStaticInvokeTest { if (mod != STATIC && typeUnderTest.isInterface()) { continue; } - Exception caught = null; - try { - getTestMH(typeUnderTest, mName, param, true); - } catch (Exception e) { - caught = e; - } - assertNotNull(caught); - assertEquals(caught.getClass(), IllegalAccessException.class); + assertThrowsExactly(IllegalAccessException.class, () -> + getTestMH(typeUnderTest, mName, param, true)); } } @@ -254,7 +244,7 @@ public class DefaultStaticInvokeTest { } } - assertEquals(myMethods.size(), expectedMethods.length); + assertEquals(expectedMethods.length, myMethods.size()); for (MethodDesc toTest : expectedMethods) { @@ -284,16 +274,15 @@ public class DefaultStaticInvokeTest { assertFalse(method.isDefault()); // Test invoke it - assertEquals(tryInvoke(method, null, param), expectedReturn); + assertEquals(expectedReturn, tryInvoke(method, null, param)); break; case DEFAULT: // if typeUnderTest is a class then instantiate and invoke if (!typeUnderTest.isInterface()) { - assertEquals(tryInvoke( + assertEquals(expectedReturn, tryInvoke( method, typeUnderTest, - param), - expectedReturn); + param)); } //assert candidate is default @@ -302,11 +291,10 @@ public class DefaultStaticInvokeTest { break; case REGULAR: // if typeUnderTest must be a class - assertEquals(tryInvoke( + assertEquals(expectedReturn, tryInvoke( method, typeUnderTest, - param), - expectedReturn); + param)); //assert candidate is neither default nor static assertFalse(Modifier.isStatic(method.getModifiers())); diff --git a/test/jdk/java/lang/reflect/DefaultStaticTest/DefaultStaticTestData.java b/test/jdk/java/lang/reflect/DefaultStaticTest/DefaultStaticTestData.java index 8049712569b..add991e3493 100644 --- a/test/jdk/java/lang/reflect/DefaultStaticTest/DefaultStaticTestData.java +++ b/test/jdk/java/lang/reflect/DefaultStaticTest/DefaultStaticTestData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,12 +27,10 @@ * @author Yong Lu */ +import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import org.testng.annotations.DataProvider; -import org.testng.collections.Lists; - import static helper.Mod.*; import static helper.Declared.*; import helper.Mod; @@ -379,7 +377,6 @@ public class DefaultStaticTestData { * data is the name of the class under test Second data used in test as the * arguments used for the method call. */ - @DataProvider static Object[][] testClasses() { return new Object[][]{ {"TestClass1", null}, @@ -408,7 +405,6 @@ public class DefaultStaticTestData { * data is the name of the interface under test Second data used in test as * the arguments used for the method call. */ - @DataProvider static Object[][] testInterfaces() { return new Object[][]{ {"TestIF1", null}, @@ -438,12 +434,4 @@ public class DefaultStaticTestData { {"TestIF21", null}, }; } - - @DataProvider - static Object[][] testCasesAll() { - List result = Lists.newArrayList(); - result.addAll(Arrays.asList(testClasses())); - result.addAll(Arrays.asList(testInterfaces())); - return result.toArray(new Object[result.size()][]); - } } diff --git a/test/jdk/java/lang/reflect/Field/NegativeTest.java b/test/jdk/java/lang/reflect/Field/NegativeTest.java index fe1f2dd7480..186267f4458 100644 --- a/test/jdk/java/lang/reflect/Field/NegativeTest.java +++ b/test/jdk/java/lang/reflect/Field/NegativeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,20 +21,20 @@ * questions. */ -/** +/* * @test * @bug 8277451 * @summary Test exception thrown due to bad receiver and bad value on * Field with and without setAccessible(true) - * @run testng/othervm --enable-final-field-mutation=ALL-UNNAMED NegativeTest + * @run junit/othervm --enable-final-field-mutation=ALL-UNNAMED NegativeTest */ import java.lang.reflect.Field; import java.lang.reflect.Modifier; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; public class NegativeTest { static class Fields { @@ -167,8 +167,7 @@ public class NegativeTest { } } - @DataProvider(name = "instanceFields") - private Object[][] instanceFields() { + private static Object[][] instanceFields() { return new Object[][]{ new Object[]{i_field}, new Object[]{c_field}, @@ -217,7 +216,8 @@ public class NegativeTest { * IllegalArgumentException is thrown if the receiver is of * a bad type. NullPointerException is thrown if the receiver is null. */ - @Test(dataProvider = "instanceFields") + @ParameterizedTest + @MethodSource("instanceFields") public void testReceiver(Field f) throws ReflectiveOperationException { f.get(INSTANCE); // good receiver @@ -231,15 +231,10 @@ public class NegativeTest { private void testBadReceiver(Field f) throws ReflectiveOperationException { assertFalse(Modifier.isStatic(f.getModifiers())); // instance field Object badObj = new NegativeTest(); - try { - f.get(badObj); - fail("expected IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // expected - } + assertThrows(IllegalArgumentException.class, () -> f.get(badObj)); Class fType = f.getType(); if (fType.isPrimitive()) { - try { + assertThrows(IllegalArgumentException.class, () -> { switch (fType.descriptorString()) { case "B" -> f.getByte(badObj); case "C" -> f.getChar(badObj); @@ -250,10 +245,7 @@ public class NegativeTest { case "S" -> f.getShort(badObj); case "Z" -> f.getBoolean(badObj); } - fail("expected IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // expected - } + }); } } @@ -262,16 +254,11 @@ public class NegativeTest { */ private void testNullReceiver(Field f) throws ReflectiveOperationException { assertFalse(Modifier.isStatic(f.getModifiers())); // instance field - try { - f.get(null); - fail("expected NullPointerException"); - } catch (NullPointerException e) { - // expected - } + assertThrows(NullPointerException.class, () -> f.get(null)); Class fType = f.getType(); if (fType.isPrimitive()) { - try { + assertThrows(NullPointerException.class, () -> { switch (fType.descriptorString()) { case "B" -> f.getByte(null); case "C" -> f.getChar(null); @@ -282,15 +269,11 @@ public class NegativeTest { case "S" -> f.getShort(null); case "Z" -> f.getBoolean(null); } - fail("expected NullPointerException"); - } catch (NullPointerException e) { - // expected - } + }); } } - @DataProvider(name = "writeableFields") - private Object[][] writeableFields() { + private static Object[][] writeableFields() { Fields obj = new Fields(); return new Object[][]{ // instance fields with and without setAccessible(true) @@ -352,7 +335,8 @@ public class NegativeTest { * NullPointerException is thrown if the receiver of an instance field is null. * The receiver is checked */ - @Test(dataProvider = "writeableFields") + @ParameterizedTest + @MethodSource("writeableFields") public void testSetValue(Field f, Object obj, Object value) throws IllegalAccessException { f.set(obj, value); Class fType = f.getType(); @@ -369,25 +353,14 @@ public class NegativeTest { } // test null value only if it's primitive type - try { - f.set(obj, null); - fail("expected IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // expected - } + assertThrows(IllegalArgumentException.class, () -> f.set(obj, null)); } Object badValue = new NegativeTest(); - try { - f.set(obj, badValue); - fail("expected IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // expected - } + assertThrows(IllegalArgumentException.class, () -> f.set(obj, badValue)); } - @DataProvider(name = "readOnlyFinalFields") - private Object[][] readOnlyFinalFields() { + private static Object[][] readOnlyFinalFields() { Object obj = INSTANCE; return new Object[][]{ // instance final fields @@ -427,19 +400,15 @@ public class NegativeTest { * IllegalAccessException is thrown regardless of whether the value * is of a bad type or not. */ - @Test(dataProvider = "readOnlyFinalFields") + @ParameterizedTest + @MethodSource("readOnlyFinalFields") public void testSetValueOnFinalField(Field f, Object obj, Object value) { assertTrue(Modifier.isFinal(f.getModifiers())); - try { - f.set(obj, value); - fail("expected IllegalAccessException"); - } catch (IllegalAccessException e) { - // expected - } + assertThrows(IllegalAccessException.class, () -> f.set(obj, value)); Class fType = f.getType(); if (fType.isPrimitive()) { - try { + assertThrows(IllegalAccessException.class, () -> { switch (fType.descriptorString()) { case "B" -> f.setByte(obj, ((Byte)value).byteValue()); case "C" -> f.setChar(obj, ((Character)value).charValue()); @@ -450,33 +419,17 @@ public class NegativeTest { case "S" -> f.setShort(obj, ((Short)value).shortValue()); case "Z" -> f.setBoolean(obj, ((Boolean)value).booleanValue()); } - fail("expected IllegalAccessException"); - } catch (IllegalAccessException e) { - // expected - } + }); // test null value only if it's primitive type - try { - f.set(obj, null); - fail("expected IllegalAccessException"); - } catch (IllegalAccessException e) { - // expected - } + assertThrows(IllegalAccessException.class, () -> f.set(obj, null)); } Object badValue = new NegativeTest(); - try { - f.set(obj, badValue); - fail("expected IllegalAccessException"); - } catch (IllegalAccessException e) { - // expected - } + assertThrows(IllegalAccessException.class, () -> f.set(obj, badValue)); } - - - @DataProvider(name = "finalInstanceFields") - private Object[][] finalInstanceFields() { + private static Object[][] finalInstanceFields() { return new Object[][]{ new Object[]{fi_field, Integer.valueOf(10)}, new Object[]{fc_field, Character.valueOf('c')}, @@ -497,54 +450,27 @@ public class NegativeTest { * The receiver is checked before the access check is performed and * also before the value is checked. */ - @Test(dataProvider = "finalInstanceFields") + @ParameterizedTest + @MethodSource("finalInstanceFields") public void testReceiverOnFinalField(Field f, Object value) { assertTrue(Modifier.isFinal(f.getModifiers())); Object badReceiver = new NegativeTest(); // set the field with a bad receiver with a good value - try { - f.set(badReceiver, value); - fail("expected IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // expected - } catch (IllegalAccessException e) { - throw new RuntimeException("Expected IllegalArgumentException but got: " + e.getMessage(), e); - } + assertThrows(IllegalArgumentException.class, () -> f.set(badReceiver, value)); // set the field with a bad receiver with a bad value Object badValue = new NegativeTest(); - try { - f.set(badReceiver, badValue); - fail("expected IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // expected - } catch (IllegalAccessException e) { - throw new RuntimeException("Expected IllegalArgumentException but got: " + e.getMessage(), e); - } + assertThrows(IllegalArgumentException.class, () -> f.set(badReceiver, badValue)); // set the field with a null receiver with a good value - try { - f.set(null, value); - fail("expected NullPointerException"); - } catch (NullPointerException e) { - // expected - } catch (IllegalAccessException e) { - throw new RuntimeException("Expected NullPointerException but got: " + e.getMessage(), e); - } + assertThrows(NullPointerException.class, () -> f.set(null, value)); // set the field with a null receiver with a bad value - try { - f.set(null, badValue); - fail("expected NullPointerException"); - } catch (NullPointerException e) { - // expected - } catch (IllegalAccessException e) { - throw new RuntimeException("Expected NullPointerException but got: " + e.getMessage(), e); - } + assertThrows(NullPointerException.class, () -> f.set(null, badValue)); Class fType = f.getType(); if (fType.isPrimitive()) { // test bad receiver - try { + assertThrows(IllegalArgumentException.class, () -> { switch (fType.descriptorString()) { case "B" -> f.setByte(badReceiver, ((Byte) value).byteValue()); case "C" -> f.setChar(badReceiver, ((Character) value).charValue()); @@ -555,12 +481,9 @@ public class NegativeTest { case "S" -> f.setShort(badReceiver, ((Short) value).shortValue()); case "Z" -> f.setBoolean(badReceiver, ((Boolean) value).booleanValue()); } - } catch (IllegalArgumentException e) { - } catch (IllegalAccessException e) { - throw new RuntimeException("Expected IllegalArgumentException but got: " + e.getMessage(), e); - } + }); // test null receiver - try { + assertThrows(NullPointerException.class, () -> { switch (fType.descriptorString()) { case "B" -> f.setByte(null, ((Byte) value).byteValue()); case "C" -> f.setChar(null, ((Character) value).charValue()); @@ -571,11 +494,7 @@ public class NegativeTest { case "S" -> f.setShort(null, ((Short) value).shortValue()); case "Z" -> f.setBoolean(null, ((Boolean) value).booleanValue()); } - } catch (NullPointerException e) { - // expected - } catch (IllegalAccessException e) { - throw new RuntimeException("Expected NullPointerException but got: " + e.getMessage(), e); - } + }); } } } diff --git a/test/jdk/java/lang/reflect/Generics/ThreadSafety.java b/test/jdk/java/lang/reflect/Generics/ThreadSafety.java index 1aa1a4e9386..81ca2ae488a 100644 --- a/test/jdk/java/lang/reflect/Generics/ThreadSafety.java +++ b/test/jdk/java/lang/reflect/Generics/ThreadSafety.java @@ -21,17 +21,16 @@ * questions. */ -/** +/* * @test * @bug 8062771 8016236 * @summary Test publication of Class objects via a data race - * @run testng ThreadSafety + * @run junit ThreadSafety */ import java.io.File; import java.net.URL; import java.net.URLClassLoader; -import java.nio.file.Path; import java.nio.file.Paths; import java.util.Collections; import java.util.concurrent.BrokenBarrierException; @@ -43,8 +42,8 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeoutException; import static java.util.concurrent.TimeUnit.SECONDS; -import static org.testng.Assert.*; -import org.testng.annotations.Test; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; /** * A test resulting from an attempt to repro this failure (in guice): diff --git a/test/jdk/java/lang/reflect/IllegalArgumentsTest.java b/test/jdk/java/lang/reflect/IllegalArgumentsTest.java index 7260c04c10a..58115523a3d 100644 --- a/test/jdk/java/lang/reflect/IllegalArgumentsTest.java +++ b/test/jdk/java/lang/reflect/IllegalArgumentsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,12 +25,14 @@ * @test * @bug 8277964 * @summary Test IllegalArgumentException be thrown when an argument is invalid - * @run testng/othervm/timeout=720 IllegalArgumentsTest + * @comment Avoid using framework utilities; this is effectively a runtime test + * sensitive to stack traces + * @run junit/othervm/timeout=720 IllegalArgumentsTest */ import java.lang.reflect.Constructor; import java.lang.reflect.Method; -import org.testng.annotations.Test; +import org.junit.jupiter.api.Test; public class IllegalArgumentsTest { static class T { diff --git a/test/jdk/java/lang/reflect/Method/MethodArityLimit.java b/test/jdk/java/lang/reflect/Method/MethodArityLimit.java index 536b3a5e317..05d4ef609ef 100644 --- a/test/jdk/java/lang/reflect/Method/MethodArityLimit.java +++ b/test/jdk/java/lang/reflect/Method/MethodArityLimit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,18 +24,16 @@ /* * @test * @bug 8271820 - * @run testng/othervm MethodArityLimit + * @run junit/othervm MethodArityLimit * @summary Method exceeds the method handle arity limit (255). */ -import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.reflect.Method; -import org.testng.annotations.Test; +import org.junit.jupiter.api.Test; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.fail; +import static org.junit.jupiter.api.Assertions.*; public class MethodArityLimit { @Test @@ -74,12 +72,10 @@ public class MethodArityLimit { 106L, 107L, 108L, 109L, 110L, 111L, 112L, 113L, 114L, 115L, 116L, 117L, 118L, 119L, 120L, 121L, 122L, 123L, 124L, 125L, 126L, 127); - assertEquals(resultViaMethod, 127); + assertEquals(127, resultViaMethod); - try { - MethodHandle mh = MethodHandles.lookup().unreflect(m); - fail("should fail in creating the method handle"); - } catch (IllegalArgumentException e) {} + var lookup = MethodHandles.lookup(); + assertThrows(IllegalArgumentException.class, () -> lookup.unreflect(m)); } public static long f(long a0, long a1, long a2, long a3, long a4, long a5, diff --git a/test/jdk/java/lang/reflect/MethodHandleAccessorsTest.java b/test/jdk/java/lang/reflect/MethodHandleAccessorsTest.java index b7e6b52b5dc..af72d8dec58 100644 --- a/test/jdk/java/lang/reflect/MethodHandleAccessorsTest.java +++ b/test/jdk/java/lang/reflect/MethodHandleAccessorsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 @@ * @bug 8271820 8300924 * @modules java.base/jdk.internal.reflect * @summary Test compliance of ConstructorAccessor, FieldAccessor, MethodAccessor implementations - * @run testng/othervm --add-exports java.base/jdk.internal.reflect=ALL-UNNAMED -XX:-ShowCodeDetailsInExceptionMessages MethodHandleAccessorsTest + * @run junit/othervm -XX:-ShowCodeDetailsInExceptionMessages MethodHandleAccessorsTest */ import jdk.internal.reflect.ConstructorAccessor; @@ -44,8 +44,11 @@ import java.util.Objects; import java.util.function.IntUnaryOperator; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.junit.jupiter.api.Assertions.assertThrows; public class MethodHandleAccessorsTest { public static void public_static_V() {} @@ -446,9 +449,7 @@ public class MethodHandleAccessorsTest { new InvocationTargetException(new IllegalArgumentException("IAE")) }; - - @DataProvider(name = "testNoArgMethods") - private Object[][] testNoArgMethods() { + private static Object[][] testNoArgMethods() { MethodHandleAccessorsTest inst = new MethodHandleAccessorsTest(); Object[] emptyArgs = new Object[]{}; return new Object[][] { @@ -468,8 +469,7 @@ public class MethodHandleAccessorsTest { }; } - @DataProvider(name = "testOneArgMethods") - private Object[][] testOneArgMethods() { + private static Object[][] testOneArgMethods() { MethodHandleAccessorsTest inst = new MethodHandleAccessorsTest(); Object wrongInst = new Object(); return new Object[][]{ @@ -497,8 +497,7 @@ public class MethodHandleAccessorsTest { }; } - @DataProvider(name = "testMultiArgMethods") - private Object[][] testMultiArgMethods() { + private static Object[][] testMultiArgMethods() { MethodHandleAccessorsTest inst = new MethodHandleAccessorsTest(); Class[] params_L3 = new Class[] { Object.class, Object.class, Object.class}; Class[] params_L4 = new Class[] { Object.class, Object.class, Object.class, Object.class}; @@ -515,8 +514,7 @@ public class MethodHandleAccessorsTest { }; } - @DataProvider(name = "testMethodsWithVarargs") - private Object[][] testMethodsWithVarargs() { + private static Object[][] testMethodsWithVarargs() { Class[] paramTypes = new Class[] { int[].class }; Class[] I_paramTypes = new Class[] { int.class, int[].class }; Class[] L_paramTypes = new Class[] { String.class, String[].class }; @@ -533,32 +531,35 @@ public class MethodHandleAccessorsTest { }; } - @Test(dataProvider = "testNoArgMethods") + @ParameterizedTest + @MethodSource("testNoArgMethods") public void testNoArgMethod(String methodname, Object target, Object[] args, Object expectedReturn, Throwable[] expectedExpections) throws Exception { doTest(MethodHandleAccessorsTest.class.getDeclaredMethod(methodname), target, args, expectedReturn, expectedExpections); } - @Test(dataProvider = "testOneArgMethods") + @ParameterizedTest + @MethodSource("testOneArgMethods") public void testOneArgMethod(String methodname, Class paramType, Object target, Object[] args, Object expectedReturn, Throwable[] expectedExpections) throws Exception { doTest(MethodHandleAccessorsTest.class.getDeclaredMethod(methodname, paramType), target, args, expectedReturn, expectedExpections); } - @Test(dataProvider = "testMultiArgMethods") + @ParameterizedTest + @MethodSource("testMultiArgMethods") public void testMultiArgMethod(String methodname, Class[] paramTypes, Object target, Object[] args, Object expectedReturn, Throwable[] expectedExpections) throws Exception { doTest(MethodHandleAccessorsTest.class.getDeclaredMethod(methodname, paramTypes), target, args, expectedReturn, expectedExpections); } - @Test(dataProvider = "testMethodsWithVarargs") + @ParameterizedTest + @MethodSource("testMethodsWithVarargs") public void testMethodsWithVarargs(String methodname, Class[] paramTypes, Object target, Object[] args, Object expectedReturn, Throwable[] expectedExpections) throws Exception { doTest(MethodHandleAccessorsTest.class.getDeclaredMethod(methodname, paramTypes), target, args, expectedReturn, expectedExpections); } - @DataProvider(name = "testConstructors") - private Object[][] testConstructors() { + private static Object[][] testConstructors() { return new Object[][]{ new Object[]{null, new Object[]{}, new Public(), noException}, new Object[]{null, null, new Public(), noException}, @@ -584,13 +585,13 @@ public class MethodHandleAccessorsTest { }; } - @Test(dataProvider = "testConstructors") + @ParameterizedTest + @MethodSource("testConstructors") public void testPublicConstructors(Class[] paramTypes, Object[] args, Object expectedReturn, Throwable[] expectedExpections) throws Exception { doTest(Public.class.getDeclaredConstructor(paramTypes), args, expectedReturn, expectedExpections); } - @DataProvider(name = "testMultiArgConstructors") - private Object[][] testMultiArgConstructors() { + private static Object[][] testMultiArgConstructors() { Class[] params_L3 = new Class[] { Object.class, Object.class, Object.class}; Class[] params_L4 = new Class[] { Object.class, Object.class, Object.class, Object.class}; Object o = "arg"; @@ -602,7 +603,8 @@ public class MethodHandleAccessorsTest { }; } - @Test(dataProvider = "testMultiArgConstructors") + @ParameterizedTest + @MethodSource("testMultiArgConstructors") public void testMultiArgConstructors(Class[] paramTypes, Object[] args, Object expectedReturn, Throwable[] expectedExpections) throws Exception { doTest(Public.class.getDeclaredConstructor(paramTypes), args, expectedReturn, expectedExpections); } @@ -616,8 +618,7 @@ public class MethodHandleAccessorsTest { doTest(Abstract.class.getDeclaredConstructor(), null, null, new InstantiationException()); } - @DataProvider(name = "throwException") - private Object[][] throwException() { + private static Object[][] throwException() { return new Object[][]{ new Object[] {new NullPointerException("NPE"), wrapped_npe}, new Object[] {new IllegalArgumentException("IAE"), wrapped_iae}, @@ -629,7 +630,8 @@ public class MethodHandleAccessorsTest { * Test Method::invoke and Constructor::newInstance to wrap NPE/CCE/IAE * thrown by the member */ - @Test(dataProvider = "throwException") + @ParameterizedTest + @MethodSource("throwException") public void testInvocationTargetException(Throwable ex, Throwable[] expectedExpections) throws Exception { Object[] args = new Object[] { ex }; // test static method @@ -646,8 +648,7 @@ public class MethodHandleAccessorsTest { doTest(applyAsIntMethod, intUnaryOp, new Object[]{12}, 12); } - @DataProvider(name = "readAccess") - private Object[][] readAccess() { + private static Object[][] readAccess() { String wrongInst = new String(); return new Object[][]{ new Object[]{"i", new Public(100), 100, noException}, @@ -657,8 +658,7 @@ public class MethodHandleAccessorsTest { new Object[]{"b", wrongInst, 0, cannot_get_field}, }; } - @DataProvider(name = "writeAccess") - private Object[][] writeAccess() { + private static Object[][] writeAccess() { Object o = new Object(); byte b = 1; return new Object[][]{ @@ -673,14 +673,16 @@ public class MethodHandleAccessorsTest { }; } - @Test(dataProvider = "readAccess") + @ParameterizedTest + @MethodSource("readAccess") public void testFieldReadAccess(String name, Object target, Object expectedValue, Throwable[] expectedExpections) throws Exception { Field f = Public.class.getDeclaredField(name); f.setAccessible(true); doTest(f, target, expectedValue, expectedExpections); } - @Test(dataProvider = "writeAccess") + @ParameterizedTest + @MethodSource("writeAccess") public void testFieldWriteAccess(String name, Object target, Object oldValue, Object newValue, Throwable[] expectedExpections) throws Exception { Field f = Public.class.getDeclaredField(name); f.setAccessible(true); @@ -693,8 +695,6 @@ public class MethodHandleAccessorsTest { Field f = Public.class.getDeclaredField("STATIC_FINAL"); doTest(f, new Public(), 1, noException); - try { - f.setInt(null, 100); - } catch (IllegalAccessException e) { } + assertThrows(IllegalAccessException.class, () -> f.setInt(null, 100)); } } diff --git a/test/jdk/java/lang/reflect/Proxy/DefaultMethods.java b/test/jdk/java/lang/reflect/Proxy/DefaultMethods.java index 48bb67f405e..e494e623119 100644 --- a/test/jdk/java/lang/reflect/Proxy/DefaultMethods.java +++ b/test/jdk/java/lang/reflect/Proxy/DefaultMethods.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,19 +23,19 @@ import java.io.IOException; import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Arrays; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; -/** +/* * @test * @bug 8159746 - * @run testng DefaultMethods + * @run junit DefaultMethods * @summary Basic tests for Proxy::invokeSuper default method */ @@ -96,15 +96,11 @@ public class DefaultMethods { } private static Method findDefaultMethod(Class refc, Method m) { - try { - assertTrue(refc.isInterface()); + assertTrue(refc.isInterface()); - Method method = refc.getMethod(m.getName(), m.getParameterTypes()); - assertTrue(method.isDefault()); - return method; - } catch (NoSuchMethodException e) { - throw new RuntimeException(e); - } + Method method = assertDoesNotThrow(() -> refc.getMethod(m.getName(), m.getParameterTypes())); + assertTrue(method.isDefault()); + return method; } @Test @@ -115,12 +111,11 @@ public class DefaultMethods { return InvocationHandler.invokeDefault(o, findDefaultMethod(I2.class, method), params); }); I1 i1 = (I1) proxy; - assertEquals(i1.m(), 20); + assertEquals(20, i1.m()); } // a default method is declared in one of the proxy interfaces - @DataProvider(name = "defaultMethods") - private Object[][] defaultMethods() { + private static Object[][] defaultMethods() { return new Object[][]{ new Object[]{new Class[]{I1.class, I2.class}, true, 10}, new Object[]{new Class[]{I1.class, I3.class}, true, 10}, @@ -133,13 +128,14 @@ public class DefaultMethods { }; } - @Test(dataProvider = "defaultMethods") + @ParameterizedTest + @MethodSource("defaultMethods") public void testDefaultMethod(Class[] intfs, boolean isDefault, int expected) throws Throwable { InvocationHandler ih = (proxy, method, params) -> { System.out.format("invoking %s with parameters: %s%n", method, Arrays.toString(params)); switch (method.getName()) { case "m": - assertTrue(method.isDefault() == isDefault); + assertEquals(isDefault, method.isDefault()); assertTrue(Arrays.stream(proxy.getClass().getInterfaces()) .anyMatch(intf -> method.getDeclaringClass() == intf), Arrays.toString(proxy.getClass().getInterfaces())); @@ -156,13 +152,12 @@ public class DefaultMethods { Object proxy = Proxy.newProxyInstance(DefaultMethods.class.getClassLoader(), intfs, ih); Method m = proxy.getClass().getMethod("m"); int result = (int)m.invoke(proxy); - assertEquals(result, expected); + assertEquals(expected, result); } // a default method may be declared in a proxy interface or // inherited from a superinterface of a proxy interface - @DataProvider(name = "supers") - private Object[][] supers() { + private static Object[][] supers() { return new Object[][]{ // invoke "m" implemented in the first proxy interface // same as the method passed to InvocationHandler::invoke @@ -188,7 +183,8 @@ public class DefaultMethods { }; } - @Test(dataProvider = "supers") + @ParameterizedTest + @MethodSource("supers") public void testSuper(Class[] intfs, Class proxyInterface, int expected) throws Throwable { final InvocationHandler ih = (proxy, method, params) -> { switch (method.getName()) { @@ -203,21 +199,21 @@ public class DefaultMethods { Object proxy = Proxy.newProxyInstance(loader, intfs, ih); if (proxyInterface == I1.class) { I1 i1 = (I1) proxy; - assertEquals(i1.m(), expected); + assertEquals(expected, i1.m()); } else if (proxyInterface == I2.class) { I2 i2 = (I2) proxy; - assertEquals(i2.m(), expected); + assertEquals(expected, i2.m()); } else if (proxyInterface == I3.class) { I3 i3 = (I3) proxy; - assertEquals(i3.m(), expected); + assertEquals(expected, i3.m()); } else if (proxyInterface == I4.class) { I4 i4 = (I4) proxy; - assertEquals(i4.m(), expected); + assertEquals(expected, i4.m()); } else { throw new UnsupportedOperationException(proxyInterface.toString()); } // invoke via InvocationHandler.invokeDefaultMethod directly - assertEquals(InvocationHandler.invokeDefault(proxy, proxyInterface.getMethod("m")), expected); + assertEquals(expected, InvocationHandler.invokeDefault(proxy, proxyInterface.getMethod("m"))); } // invoke I12 default methods with parameters and var args @@ -236,12 +232,12 @@ public class DefaultMethods { }; ClassLoader loader = DefaultMethods.class.getClassLoader(); I12 i12 = (I12) Proxy.newProxyInstance(loader, new Class[] { I12.class }, ih); - assertEquals(i12.sum(1, 2), 3); - assertEquals(i12.concat(1, 2, 3, 4), new Object[]{1, 2, 3, 4}); + assertEquals(3, i12.sum(1, 2)); + assertArrayEquals(new Object[]{1, 2, 3, 4}, i12.concat(1, 2, 3, 4)); Method m = I12.class.getMethod("concat", Object.class, Object[].class); assertTrue(m.isDefault()); - assertEquals(InvocationHandler.invokeDefault(i12, m, 100, new Object[] {"foo", true, "bar"}), - new Object[] {100, "foo", true, "bar"}); + assertArrayEquals(new Object[] {100, "foo", true, "bar"}, (Object[]) + InvocationHandler.invokeDefault(i12, m, 100, new Object[] {"foo", true, "bar"})); } // test a no-arg default method with and without arguments passed in the invocation @@ -250,13 +246,13 @@ public class DefaultMethods { ClassLoader loader = DefaultMethods.class.getClassLoader(); Object proxy = Proxy.newProxyInstance(loader, new Class[]{I4.class}, HANDLER); Method m1 = I4.class.getMethod("m"); - assertTrue(m1.getDeclaringClass() == I4.class); + assertSame(I4.class, m1.getDeclaringClass()); assertTrue(m1.isDefault()); InvocationHandler.invokeDefault(proxy, m1); InvocationHandler.invokeDefault(proxy, m1, new Object[0]); Method m2 = I4.class.getMethod("mix", int.class, String.class); - assertTrue(m1.getDeclaringClass() == I4.class); + assertSame(I4.class, m1.getDeclaringClass()); assertTrue(m1.isDefault()); InvocationHandler.invokeDefault(proxy, m2, Integer.valueOf(100), "foo"); } @@ -267,38 +263,37 @@ public class DefaultMethods { I3 proxy = (I3)Proxy.newProxyInstance(loader, new Class[]{I3.class}, HANDLER); Method m = I3.class.getMethod("m3", String[].class); assertTrue(m.isVarArgs() && m.isDefault()); - assertEquals(proxy.m3("a", "b", "cde"), 5); - assertEquals(InvocationHandler.invokeDefault(proxy, m, (Object)new String[] { "a", "bc" }), 3); + assertEquals(5, proxy.m3("a", "b", "cde")); + assertEquals(3, InvocationHandler.invokeDefault(proxy, m, (Object)new String[] { "a", "bc" })); } /* * Invoke I12::m which is an abstract method */ - @Test(expectedExceptions = {IllegalArgumentException.class}) + @Test public void invokeAbstractMethod() throws Exception { ClassLoader loader = DefaultMethods.class.getClassLoader(); I12 proxy = (I12) Proxy.newProxyInstance(loader, new Class[]{I12.class}, HANDLER); Method method = I12.class.getMethod("m"); - assertTrue(method.getDeclaringClass() == I12.class); + assertSame(I12.class, method.getDeclaringClass()); assertFalse(method.isDefault()); - proxy.m(); + assertThrows(IllegalArgumentException.class, () -> proxy.m()); } /* * Invoke a non proxy (default) method with parameters */ - @Test(expectedExceptions = {IllegalArgumentException.class}) + @Test public void invokeNonProxyMethod() throws Throwable { ClassLoader loader = DefaultMethods.class.getClassLoader(); I3 proxy = (I3) Proxy.newProxyInstance(loader, new Class[]{I3.class}, HANDLER); Method m = I4.class.getMethod("mix", int.class, String.class); assertTrue(m.isDefault()); - InvocationHandler.invokeDefault(proxy, m); + assertThrows(IllegalArgumentException.class, () -> InvocationHandler.invokeDefault(proxy, m)); } // negative cases - @DataProvider(name = "negativeCases") - private Object[][] negativeCases() { + private static Object[][] negativeCases() { return new Object[][]{ // I4::m overrides I1::m and I2::m new Object[] { new Class[]{I4.class}, I1.class, "m" }, @@ -315,25 +310,20 @@ public class DefaultMethods { }; } - @Test(dataProvider = "negativeCases", expectedExceptions = {IllegalArgumentException.class}) + @ParameterizedTest + @MethodSource("negativeCases") public void testNegativeCase(Class[] interfaces, Class defc, String name) throws Throwable { ClassLoader loader = DefaultMethods.class.getClassLoader(); Object proxy = Proxy.newProxyInstance(loader, interfaces, HANDLER); - try { - Method method = defc.getDeclaredMethod(name); - InvocationHandler.invokeDefault(proxy, method); - } catch (Throwable e) { - System.out.format("%s method %s::%s exception thrown: %s%n", - Arrays.toString(interfaces), defc.getName(), name, e.getMessage()); - throw e; - } + Method method = defc.getDeclaredMethod(name); + assertThrows(IllegalArgumentException.class, () -> + InvocationHandler.invokeDefault(proxy, method)); } - @DataProvider(name = "illegalArguments") - private Object[][] illegalArguments() { - return new Object[][] { - new Object[] { new Object[0]}, + private static Object[] illegalArguments() { + return new Object[] { + new Object[] { null }, new Object[] { new Object[] { 100 }}, new Object[] { new Object[] { 100, "foo", 100 }}, new Object[] { new Object[] { 100L, "foo" }}, @@ -342,21 +332,18 @@ public class DefaultMethods { }; } - @Test(dataProvider = "illegalArguments", expectedExceptions = {IllegalArgumentException.class}) + @ParameterizedTest + @MethodSource("illegalArguments") public void testIllegalArgument(Object[] args) throws Throwable { ClassLoader loader = DefaultMethods.class.getClassLoader(); I4 proxy = (I4)Proxy.newProxyInstance(loader, new Class[]{I4.class}, HANDLER); Method m = I4.class.getMethod("mix", int.class, String.class); assertTrue(m.isDefault()); - if (args.length == 0) { - // substitute empty args with null since @DataProvider doesn't allow null array - args = null; - } - InvocationHandler.invokeDefault(proxy, m, args); + assertThrows(IllegalArgumentException.class, () -> + InvocationHandler.invokeDefault(proxy, m, args)); } - @DataProvider(name = "throwables") - private Object[][] throwables() { + private static Object[][] throwables() { return new Object[][] { new Object[] { new IOException() }, new Object[] { new IllegalArgumentException() }, @@ -367,16 +354,14 @@ public class DefaultMethods { }; } - @Test(dataProvider = "throwables") + @ParameterizedTest + @MethodSource("throwables") public void testInvocationException(Throwable exception) throws Throwable { ClassLoader loader = DefaultMethods.class.getClassLoader(); IX proxy = (IX)Proxy.newProxyInstance(loader, new Class[]{IX.class}, HANDLER); Method m = IX.class.getMethod("doThrow", Throwable.class); - try { - InvocationHandler.invokeDefault(proxy, m, exception); - } catch (Throwable e) { - assertEquals(e, exception); - } + assertSame(exception, assertThrows(Throwable.class, () -> + InvocationHandler.invokeDefault(proxy, m, exception))); } private static final InvocationHandler HANDLER = (proxy, method, params) -> { diff --git a/test/jdk/java/lang/reflect/Proxy/HiddenProxyInterface.java b/test/jdk/java/lang/reflect/Proxy/HiddenProxyInterface.java index e52d3671ab6..fbaf9db6325 100644 --- a/test/jdk/java/lang/reflect/Proxy/HiddenProxyInterface.java +++ b/test/jdk/java/lang/reflect/Proxy/HiddenProxyInterface.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /* * @test * @bug 8250219 - * @run testng HiddenProxyInterface + * @run junit HiddenProxyInterface */ import java.lang.invoke.MethodHandles; @@ -35,8 +35,8 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; public class HiddenProxyInterface { private static final Path CLASSES_DIR = Paths.get(System.getProperty("test.classes")); @@ -45,18 +45,19 @@ public class HiddenProxyInterface { void m(); } - @Test(expectedExceptions = { IllegalArgumentException.class }) + @Test public void testHiddenInterface() throws Exception { Path classFile = CLASSES_DIR.resolve("HiddenProxyInterface$Intf.class"); byte[] bytes = Files.readAllBytes(classFile); Class hiddenIntf = MethodHandles.lookup().defineHiddenClass(bytes, false).lookupClass(); - Proxy.newProxyInstance(HiddenProxyInterface.class.getClassLoader(), + assertThrows(IllegalArgumentException.class, () -> Proxy.newProxyInstance( + HiddenProxyInterface.class.getClassLoader(), new Class[]{ hiddenIntf }, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return null; } - }); + })); } } diff --git a/test/jdk/java/lang/reflect/Proxy/LazyInitializationTest.java b/test/jdk/java/lang/reflect/Proxy/LazyInitializationTest.java index cb65904cfdb..2a223873275 100644 --- a/test/jdk/java/lang/reflect/Proxy/LazyInitializationTest.java +++ b/test/jdk/java/lang/reflect/Proxy/LazyInitializationTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,14 +23,15 @@ import java.lang.reflect.Proxy; -import org.testng.Assert; -import org.testng.annotations.Test; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; /* * @test * @bug 8285401 * @summary Avoid initialization of parameter types in proxy construction - * @run testng LazyInitializationTest + * @run junit LazyInitializationTest */ public final class LazyInitializationTest { private static volatile boolean initialized = false; @@ -50,9 +51,9 @@ public final class LazyInitializationTest { Intf value = (Intf) Proxy.newProxyInstance(LazyInitializationTest.class.getClassLoader(), new Class[]{ Intf.class }, (proxy, method, args) -> null); - Assert.assertFalse(initialized, "parameter type initialized unnecessarily"); + assertFalse(initialized, "parameter type initialized unnecessarily"); value.m(new Parameter()); - Assert.assertTrue(initialized, "parameter type initialized after instantiation"); + assertTrue(initialized, "parameter type initialized after instantiation"); } } diff --git a/test/jdk/java/lang/reflect/Proxy/ProxyClassAccessTest.java b/test/jdk/java/lang/reflect/Proxy/ProxyClassAccessTest.java index 50fbd150ec7..265f9ce7104 100644 --- a/test/jdk/java/lang/reflect/Proxy/ProxyClassAccessTest.java +++ b/test/jdk/java/lang/reflect/Proxy/ProxyClassAccessTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * 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,17 +32,17 @@ import java.util.List; import jdk.test.lib.compiler.CompilerUtils; import static jdk.test.lib.process.ProcessTools.executeTestJava; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; -/** +/* * @test * @library /test/lib * @modules jdk.compiler * @build ProxyClassAccessTest q.NP * jdk.test.lib.compiler.CompilerUtils - * @run testng ProxyClassAccessTest + * @run junit ProxyClassAccessTest * @summary Driver for testing proxy class doesn't have access to * types referenced by proxy interfaces */ @@ -61,8 +61,8 @@ public class ProxyClassAccessTest { /** * Compiles all modules used by the test */ - @BeforeTest - public void compileAll() throws Exception { + @BeforeAll + public static void compileAll() throws Exception { for (String mn : modules) { Path msrc = SRC_DIR.resolve(mn); assertTrue(CompilerUtils.compile(msrc, MODS_DIR, "--module-source-path", SRC_DIR.toString())); @@ -80,7 +80,7 @@ public class ProxyClassAccessTest { .errorTo(System.out) .getExitValue(); - assertTrue(exitValue == 0); + assertEquals(0, exitValue); } /** @@ -105,16 +105,10 @@ public class ProxyClassAccessTest { } private void checkIAE(ClassLoader loader, Class[] interfaces) throws Throwable { - try { - Proxy.getProxyClass(loader, interfaces); - throw new RuntimeException("Expected IllegalArgumentException thrown"); - } catch (IllegalArgumentException e) {} + assertThrows(IllegalArgumentException.class, () -> Proxy.getProxyClass(loader, interfaces)); - try { - Proxy.newProxyInstance(loader, interfaces, - (proxy, m, params) -> { throw new RuntimeException(m.toString()); }); - throw new RuntimeException("Expected IllegalArgumentException thrown"); - } catch (IllegalArgumentException e) {} + assertThrows(IllegalArgumentException.class, () -> Proxy.newProxyInstance(loader, interfaces, + (proxy, m, params) -> { throw new RuntimeException(m.toString()); })); } } diff --git a/test/jdk/java/lang/reflect/Proxy/ProxyLayerTest.java b/test/jdk/java/lang/reflect/Proxy/ProxyLayerTest.java index 85ebf922a20..d2708e18c0e 100644 --- a/test/jdk/java/lang/reflect/Proxy/ProxyLayerTest.java +++ b/test/jdk/java/lang/reflect/Proxy/ProxyLayerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * 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,17 +32,18 @@ import java.util.Arrays; import jdk.test.lib.compiler.CompilerUtils; import static jdk.test.lib.process.ProcessTools.executeTestJava; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; -/** +/* * @test * @library /test/lib * @modules jdk.compiler * @build ProxyTest jdk.test.lib.process.ProcessTools * jdk.test.lib.compiler.CompilerUtils - * @run testng ProxyLayerTest + * @run junit ProxyLayerTest * @summary Test proxies to implement interfaces in a layer */ @@ -62,8 +63,8 @@ public class ProxyLayerTest { /** * Compiles all modules used by the test */ - @BeforeTest - public void compileAll() throws Exception { + @BeforeAll + public static void compileAll() throws Exception { for (String mn : modules) { Path msrc = SRC_DIR.resolve(mn); assertTrue(CompilerUtils.compile(msrc, MODS_DIR, "--module-source-path", SRC_DIR.toString())); @@ -102,7 +103,7 @@ public class ProxyLayerTest { assertTrue(proxyClass.getModule().isNamed()); assertTrue(pkg.isSealed()); assertTrue(proxyClass.getModule().isExported(pkg.getName())); - assertEquals(proxyClass.getModule().getLayer(), null); + assertNull(proxyClass.getModule().getLayer()); } /** @@ -134,7 +135,7 @@ public class ProxyLayerTest { assertTrue(proxyClass.getModule().isNamed()); assertTrue(pkg.isSealed()); assertFalse(proxyClass.getModule().isExported(pkg.getName())); - assertEquals(proxyClass.getModule().getLayer(), null); + assertNull(proxyClass.getModule().getLayer()); } /** @@ -164,15 +165,8 @@ public class ProxyLayerTest { } private void checkIAE(ClassLoader loader, Class[] interfaces) { - try { - Proxy.getProxyClass(loader, interfaces); - throw new RuntimeException("Expected IllegalArgumentException thrown"); - } catch (IllegalArgumentException e) {} - - try { - Proxy.newProxyInstance(loader, interfaces, handler); - throw new RuntimeException("Expected IllegalArgumentException thrown"); - } catch (IllegalArgumentException e) {} + assertThrows(IllegalArgumentException.class, () -> Proxy.getProxyClass(loader, interfaces)); + assertThrows(IllegalArgumentException.class, () -> Proxy.newProxyInstance(loader, interfaces, handler)); } private final static InvocationHandler handler = diff --git a/test/jdk/java/lang/reflect/Proxy/ProxyTest.java b/test/jdk/java/lang/reflect/Proxy/ProxyTest.java index 811471585a9..1da6a10260a 100644 --- a/test/jdk/java/lang/reflect/Proxy/ProxyTest.java +++ b/test/jdk/java/lang/reflect/Proxy/ProxyTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * 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,17 +29,17 @@ import java.util.List; import jdk.test.lib.compiler.CompilerUtils; import static jdk.test.lib.process.ProcessTools.executeTestJava; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; -/** +/* * @test * @library /test/lib * @modules jdk.compiler * @build ProxyTest q.U * jdk.test.lib.compiler.CompilerUtils - * @run testng ProxyTest + * @run junit ProxyTest * @summary Driver for testing proxies accessing interfaces in named modules */ @@ -59,8 +59,8 @@ public class ProxyTest { /** * Compiles all modules used by the test */ - @BeforeTest - public void compileAll() throws Exception { + @BeforeAll + public static void compileAll() throws Exception { for (String mn : modules) { Path msrc = SRC_DIR.resolve(mn); assertTrue(CompilerUtils.compile(msrc, MODS_DIR, "--module-source-path", SRC_DIR.toString())); @@ -79,7 +79,7 @@ public class ProxyTest { .errorTo(System.out) .getExitValue(); - assertTrue(exitValue == 0); + assertEquals(0, exitValue); } /** @@ -95,6 +95,6 @@ public class ProxyTest { .errorTo(System.out) .getExitValue(); - assertTrue(exitValue == 0); + assertEquals(0, exitValue); } } diff --git a/test/jdk/java/lang/reflect/Proxy/SealedInterfaceTest.java b/test/jdk/java/lang/reflect/Proxy/SealedInterfaceTest.java index 1337248f817..822c5d83319 100644 --- a/test/jdk/java/lang/reflect/Proxy/SealedInterfaceTest.java +++ b/test/jdk/java/lang/reflect/Proxy/SealedInterfaceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * 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,15 +24,15 @@ /* * @test * @bug 8269351 - * @run testng SealedInterfaceTest + * @run junit SealedInterfaceTest */ import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; public class SealedInterfaceTest { sealed interface Intf permits NonSealedInterface { @@ -43,16 +43,17 @@ public class SealedInterfaceTest { void m2(); } - @Test(expectedExceptions = { IllegalArgumentException.class }) + @Test public void testSealedInterface() { - Proxy.newProxyInstance(SealedInterfaceTest.class.getClassLoader(), + assertThrows(IllegalArgumentException.class, () -> Proxy.newProxyInstance( + SealedInterfaceTest.class.getClassLoader(), new Class[]{ Intf.class }, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return null; } - }); + })); } @Test diff --git a/test/jdk/java/lang/reflect/Proxy/TestVarArgs.java b/test/jdk/java/lang/reflect/Proxy/TestVarArgs.java index a472f75d4b7..b16831c7867 100644 --- a/test/jdk/java/lang/reflect/Proxy/TestVarArgs.java +++ b/test/jdk/java/lang/reflect/Proxy/TestVarArgs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,10 +21,10 @@ * questions. */ -/** +/* * @test * @bug 8022795 - * @run testng TestVarArgs + * @run junit TestVarArgs * @summary Verify if a method defined in a proxy interface has ACC_VARARGS set */ @@ -34,11 +34,10 @@ import java.lang.invoke.MethodType; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; -import java.util.Arrays; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; public class TestVarArgs { interface I { @@ -48,8 +47,7 @@ public class TestVarArgs { Object call(Object[] values); } - @DataProvider(name = "proxyInterfaces") - public Object[][] proxyInterfaces() { + public static Object[][] proxyInterfaces() { return new Object[][] { { new Class[] { I.class }, true}, { new Class[] { J.class }, false}, @@ -58,11 +56,12 @@ public class TestVarArgs { }; } - @Test(dataProvider = "proxyInterfaces") + @ParameterizedTest + @MethodSource("proxyInterfaces") public void testMethod(Class[] proxyInterfaces, boolean isVarArgs) throws Throwable { // check if the first proxy interface with the method named "call" declares var result Method m = proxyInterfaces[0].getMethod("call", Object[].class); - assertTrue(m.isVarArgs() == isVarArgs); + assertEquals(isVarArgs, m.isVarArgs()); // the method in the generated proxy class should match the method // declared in the proxy interface @@ -71,19 +70,19 @@ public class TestVarArgs { Class proxyClass = proxy.getClass(); assertTrue(Proxy.isProxyClass(proxyClass)); Method method = proxyClass.getMethod("call", Object[].class); - assertTrue(method.isVarArgs() == isVarArgs); + assertEquals(isVarArgs, method.isVarArgs()); - Object params = new Object[] { "foo", "bar", "goo" }; - Object result; + Object[] params = new Object[] { "foo", "bar", "goo" }; + Object[] result; // test reflection - result = method.invoke(proxy, params); - assertEquals(result, params); + result = (Object[]) method.invoke(proxy, new Object[] {params}); + assertEquals(params, result); // test method handle MethodHandle mh = MethodHandles.lookup().findVirtual(proxyClass, "call", MethodType.methodType(Object.class, Object[].class)); - assertTrue(mh.isVarargsCollector() == isVarArgs); + assertEquals(isVarArgs, mh.isVarargsCollector()); MethodHandle mhVarArity = mh; MethodHandle mhFixedArity = mh; if (isVarArgs) { @@ -91,18 +90,18 @@ public class TestVarArgs { } else { mhVarArity = mh.asVarargsCollector(Object[].class); } - result = mhVarArity.invoke(proxy, "foo", "bar", "goo"); - assertEquals(result, params); + result = (Object[]) mhVarArity.invoke(proxy, "foo", "bar", "goo"); + assertArrayEquals(params, result); - result = mhFixedArity.invoke(proxy, params); - assertEquals(result, params); + result = (Object[]) mhFixedArity.invoke(proxy, params); + assertArrayEquals(params, result); if (!isVarArgs) { MethodType mt = MethodType.methodType(Object.class, Object.class, String.class, String.class, String.class); mh = mh.asVarargsCollector(Object[].class).asType(mt); } - result = mh.invoke(proxy, "foo", "bar", "goo"); - assertEquals(result, params); + result = (Object[]) mh.invoke(proxy, "foo", "bar", "goo"); + assertArrayEquals(params, result); } private static final InvocationHandler IH = new InvocationHandler() { diff --git a/test/jdk/java/lang/reflect/Proxy/nonPublicProxy/DefaultMethodProxy.java b/test/jdk/java/lang/reflect/Proxy/nonPublicProxy/DefaultMethodProxy.java index daf6f656aab..a304063638c 100644 --- a/test/jdk/java/lang/reflect/Proxy/nonPublicProxy/DefaultMethodProxy.java +++ b/test/jdk/java/lang/reflect/Proxy/nonPublicProxy/DefaultMethodProxy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. * 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,16 +25,17 @@ import java.lang.reflect.*; import java.util.Arrays; import java.util.stream.Collectors; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; /* * @test * @bug 8159746 * @summary Test invoking a default method in a non-public proxy interface * @build p.Foo p.Bar p.ProxyMaker - * @run testng DefaultMethodProxy + * @run junit DefaultMethodProxy */ public class DefaultMethodProxy { public interface I { @@ -42,7 +43,7 @@ public class DefaultMethodProxy { } @Test - public static void publicInterface() throws ReflectiveOperationException { + public void publicInterface() throws ReflectiveOperationException { // create a proxy instance of a public proxy interface should succeed Proxy proxy = (Proxy)Proxy.newProxyInstance(DefaultMethodProxy.class.getClassLoader(), new Class[] { I.class }, IH); @@ -50,11 +51,9 @@ public class DefaultMethodProxy { testDefaultMethod(proxy, "I"); // can get the invocation handler - assertTrue(Proxy.getInvocationHandler(proxy) == IH); + assertSame(IH, Proxy.getInvocationHandler(proxy)); } - - @DataProvider(name = "nonPublicIntfs") private static Object[][] nonPublicIntfs() throws ClassNotFoundException { Class fooClass = Class.forName("p.Foo"); Class barClass = Class.forName("p.Bar"); @@ -65,8 +64,9 @@ public class DefaultMethodProxy { }; } - @Test(dataProvider = "nonPublicIntfs") - public static void hasPackageAccess(Class[] intfs, String expected) throws ReflectiveOperationException { + @ParameterizedTest + @MethodSource("nonPublicIntfs") + public void hasPackageAccess(Class[] intfs, String expected) throws ReflectiveOperationException { Proxy proxy = (Proxy)Proxy.newProxyInstance(DefaultMethodProxy.class.getClassLoader(), intfs, IH); testDefaultMethod(proxy, expected); @@ -75,19 +75,13 @@ public class DefaultMethodProxy { } // IAE thrown at invocation time - @Test(dataProvider = "nonPublicIntfs", expectedExceptions = {IllegalAccessException.class}) - public static void noPackageAccess(Class[] intfs, String ignored) throws Throwable { + @ParameterizedTest + @MethodSource("nonPublicIntfs") + public void noPackageAccess(Class[] intfs, String ignored) throws Throwable { Proxy proxy = (Proxy)Proxy.newProxyInstance(DefaultMethodProxy.class.getClassLoader(), intfs, IH_NO_ACCESS); - try { - testDefaultMethod(proxy, "dummy"); - } catch (InvocationTargetException e) { - // unwrap the exception - if (e.getCause() instanceof UndeclaredThrowableException) { - Throwable cause = e.getCause(); - throw cause.getCause(); - } - throw e; - } + InvocationTargetException ite = assertThrows(InvocationTargetException.class, () -> testDefaultMethod(proxy, "dummy")); + var ute = assertInstanceOf(UndeclaredThrowableException.class, ite.getCause(), "unwrap the InvocationTargetException"); + assertInstanceOf(IllegalAccessException.class, ute.getCause(), "unwrap the UndeclaredThrowableException"); } /* diff --git a/test/jdk/java/lang/reflect/annotationSharing/AnnotationSharing.java b/test/jdk/java/lang/reflect/annotationSharing/AnnotationSharing.java index 98a13d6416c..b29c74637d6 100644 --- a/test/jdk/java/lang/reflect/annotationSharing/AnnotationSharing.java +++ b/test/jdk/java/lang/reflect/annotationSharing/AnnotationSharing.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * 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,13 +27,13 @@ * @summary Test sharing of annotations between Executable/Field instances. * Sharing should not be noticeable when performing mutating * operations. - * @run testng AnnotationSharing + * @run junit AnnotationSharing */ import java.lang.annotation.*; import java.lang.reflect.*; -import org.testng.annotations.Test; +import org.junit.jupiter.api.Test; public class AnnotationSharing { @Test diff --git a/test/jdk/java/lang/reflect/callerCache/CustomLoaderTest.java b/test/jdk/java/lang/reflect/callerCache/CustomLoaderTest.java index f3a429027d9..6951cc0829c 100644 --- a/test/jdk/java/lang/reflect/callerCache/CustomLoaderTest.java +++ b/test/jdk/java/lang/reflect/callerCache/CustomLoaderTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 @@ * @library /test/lib/ * @modules jdk.compiler * @build CustomLoaderTest jdk.test.lib.compiler.CompilerUtils - * @run testng/othervm CustomLoaderTest + * @run junit/othervm CustomLoaderTest * * @summary Test method whose parameter types and return type are not visible to the caller. */ @@ -42,27 +42,23 @@ import java.nio.file.Paths; import java.util.concurrent.atomic.AtomicInteger; import jdk.test.lib.compiler.CompilerUtils; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; public class CustomLoaderTest { private static final Path CLASSES = Paths.get("classes"); - @BeforeTest - public void setup() throws IOException { + @BeforeAll + public static void setup() throws IOException { String src = System.getProperty("test.src", "."); String classpath = System.getProperty("test.classes", "."); boolean rc = CompilerUtils.compile(Paths.get(src, "ReflectTest.java"), CLASSES, "-cp", classpath); if (!rc) { - throw new RuntimeException("fail compilation"); - } - try { - Class p = Class.forName("ReflectTest$P"); - fail("should not be visible to this loader"); - } catch (ClassNotFoundException e) { - e.printStackTrace(); + fail("fail compilation"); } + assertThrows(ClassNotFoundException.class, () -> Class.forName("ReflectTest$P"), + "should not be visible to this loader"); } @Test @@ -72,17 +68,17 @@ public class CustomLoaderTest { Method m1 = loader1.findMethod(); Method m2 = loader2.findMethod(); - assertTrue(m1.getDeclaringClass() != m2.getDeclaringClass()); + assertNotSame(m1.getDeclaringClass(), m2.getDeclaringClass()); - assertTrue(m1.getDeclaringClass() == loader1.c); - assertTrue(m2.getDeclaringClass() == loader2.c); + assertSame(loader1.c, m1.getDeclaringClass()); + assertSame(loader2.c, m2.getDeclaringClass()); Object o1 = m1.invoke(loader1.c.newInstance(), loader1.p.newInstance(), loader1.q.newInstance()); Object o2 = m2.invoke(loader2.c.newInstance(), loader2.p.newInstance(), loader2.q.newInstance()); - assertTrue(o1.getClass() != o2.getClass()); - assertTrue(o1.getClass() == loader1.r); - assertTrue(o2.getClass() == loader2.r); + assertNotSame(o1.getClass(), o2.getClass()); + assertSame(loader1.r, o1.getClass()); + assertSame(loader2.r, o2.getClass()); } static class TestLoader extends URLClassLoader { diff --git a/test/jdk/java/lang/reflect/callerCache/ReflectionCallerCacheTest.java b/test/jdk/java/lang/reflect/callerCache/ReflectionCallerCacheTest.java index b640a5e2150..4513c698a54 100644 --- a/test/jdk/java/lang/reflect/callerCache/ReflectionCallerCacheTest.java +++ b/test/jdk/java/lang/reflect/callerCache/ReflectionCallerCacheTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 @@ * @library /test/lib/ * @modules jdk.compiler * @build ReflectionCallerCacheTest Members jdk.test.lib.compiler.CompilerUtils - * @run testng/othervm ReflectionCallerCacheTest + * @run junit/othervm ReflectionCallerCacheTest */ import java.io.IOException; @@ -44,16 +44,16 @@ import java.util.concurrent.Callable; import jdk.test.lib.compiler.CompilerUtils; import jdk.test.lib.util.ForceGC; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; public class ReflectionCallerCacheTest { private static final Path CLASSES = Paths.get("classes"); private static final ReflectionCallerCacheTest TEST = new ReflectionCallerCacheTest(); - @BeforeTest - public void setup() throws IOException { + @BeforeAll + public static void setup() throws IOException { String src = System.getProperty("test.src", "."); String classpath = System.getProperty("test.classes", "."); boolean rc = CompilerUtils.compile(Paths.get(src, "AccessTest.java"), CLASSES, "-cp", classpath); @@ -61,8 +61,8 @@ public class ReflectionCallerCacheTest { throw new RuntimeException("fail compilation"); } } - @DataProvider(name = "memberAccess") - public Object[][] memberAccess() { + + public static Object[][] memberAccess() { return new Object[][] { { "AccessTest$PublicConstructor" }, { "AccessTest$PublicMethod" }, @@ -102,8 +102,9 @@ public class ReflectionCallerCacheTest { } } - @Test(dataProvider = "memberAccess") - private void load(String classname) throws Exception { + @ParameterizedTest + @MethodSource("memberAccess") + void load(String classname) throws Exception { WeakReference weakLoader = loadAndRunClass(classname); // Force garbage collection to trigger unloading of class loader diff --git a/test/jdk/java/lang/reflect/records/CheckEqualityIsBasedOnFields.java b/test/jdk/java/lang/reflect/records/CheckEqualityIsBasedOnFields.java index b5c438e4f9a..c3e4431bd84 100644 --- a/test/jdk/java/lang/reflect/records/CheckEqualityIsBasedOnFields.java +++ b/test/jdk/java/lang/reflect/records/CheckEqualityIsBasedOnFields.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. * 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,15 @@ * @test * @bug 8257598 * @summary check that Record::equals uses the fields and not the accessors for the comparison - * @run testng CheckEqualityIsBasedOnFields + * @run junit CheckEqualityIsBasedOnFields */ import java.lang.reflect.Constructor; -import java.lang.reflect.Field; import java.lang.reflect.Method; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; public class CheckEqualityIsBasedOnFields { public record R01(boolean x) { @@ -91,8 +89,7 @@ public class CheckEqualityIsBasedOnFields { } } - @DataProvider(name = "recordData") - public Object[][] recordTypeAndExpectedValue() { + public static Object[][] recordTypeAndExpectedValue() { return new Object[][] { new Object[] { R01.class, boolean.class, new Object[]{true, false} }, new Object[] { R02.class, byte.class, new Object[]{(byte)0, (byte)1, (byte)2, (byte)3, (byte)4, (byte)5, @@ -112,7 +109,8 @@ public class CheckEqualityIsBasedOnFields { }; } - @Test(dataProvider = "recordData") + @ParameterizedTest + @MethodSource("recordTypeAndExpectedValue") public void testEqualsDoesntUseAccessors(Class clazz, Class componentClass, Object[] expectedXValues) throws Exception { Constructor ctor; Method getter, equalsMethod; @@ -125,8 +123,8 @@ public class CheckEqualityIsBasedOnFields { System.out.println(rec1.toString()); System.out.println(rec2.toString()); assertFalse((boolean) equalsMethod.invoke(rec1, rec2)); - assertNotEquals(expectedXValues[i], expectedXValues[i + expectedXValues.length / 2]); - assertEquals(getter.invoke(rec1), getter.invoke(rec2)); + assertNotEquals(expectedXValues[i + expectedXValues.length / 2], expectedXValues[i]); + assertEquals(getter.invoke(rec2), getter.invoke(rec1)); } } } diff --git a/test/jdk/java/lang/reflect/records/IsRecordTest.java b/test/jdk/java/lang/reflect/records/IsRecordTest.java index 4888e6d506e..153329a7832 100644 --- a/test/jdk/java/lang/reflect/records/IsRecordTest.java +++ b/test/jdk/java/lang/reflect/records/IsRecordTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. * 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,32 +26,31 @@ * @bug 8255560 * @summary Class::isRecord should check that the current class is final and not abstract * @library /test/lib - * @run testng/othervm IsRecordTest + * @run junit/othervm IsRecordTest */ import java.lang.classfile.ClassFile; import java.lang.constant.ClassDesc; -import java.lang.reflect.AccessFlag; import java.util.List; import java.util.Map; import java.lang.classfile.attribute.RecordAttribute; import java.lang.classfile.attribute.RecordComponentInfo; import jdk.test.lib.ByteCodeLoader; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import static java.lang.System.out; import static java.lang.classfile.ClassFile.ACC_ABSTRACT; import static java.lang.classfile.ClassFile.ACC_FINAL; import static java.lang.constant.ConstantDescs.CD_int; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertTrue; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.junit.jupiter.api.Assertions.*; public class IsRecordTest { - @DataProvider(name = "scenarios") - public Object[][] scenarios() { + public static Object[][] scenarios() { return new Object[][] { // isFinal, isAbstract, extendJLR, withRecAttr, expectIsRecord { false, false, false, true, false }, @@ -75,7 +74,8 @@ public class IsRecordTest { * iii) direct subclass of j.l.Record (or not), along with the presence or * absence of a record attribute. */ - @Test(dataProvider = "scenarios") + @ParameterizedTest + @MethodSource("scenarios") public void testDirectSubClass(boolean isFinal, boolean isAbstract, boolean extendsJLR, @@ -92,9 +92,8 @@ public class IsRecordTest { Class cls = ByteCodeLoader.load("C", classBytes); out.println("cls=%s, Record::isAssignable=%s, isRecord=%s" .formatted(cls, Record.class.isAssignableFrom(cls), cls.isRecord())); - assertEquals(cls.isRecord(), expectIsRecord); - var getRecordComponents = cls.getRecordComponents(); - assertTrue(expectIsRecord ? getRecordComponents != null : getRecordComponents == null); + assertEquals(expectIsRecord, cls.isRecord()); + assertEquals(expectIsRecord, cls.getRecordComponents() != null); } /** @@ -102,7 +101,8 @@ public class IsRecordTest { * along with the presence or absence of a record attribute, where the class has * a superclass whose superclass is j.l.Record. */ - @Test(dataProvider = "scenarios") + @ParameterizedTest + @MethodSource("scenarios") public void testIndirectSubClass(boolean isFinal, boolean isAbstract, boolean unused1, @@ -127,8 +127,8 @@ public class IsRecordTest { .formatted(cls, Record.class.isAssignableFrom(cls), cls.isRecord())); assertFalse(supFooCls.isRecord()); assertFalse(subFooCls.isRecord()); - assertEquals(supFooCls.getRecordComponents(), null); - assertEquals(subFooCls.getRecordComponents(), null); + assertNull(supFooCls.getRecordComponents()); + assertNull(subFooCls.getRecordComponents()); } /** Tests record-ness properties of traditionally compiled classes. */ @@ -137,23 +137,23 @@ public class IsRecordTest { out.println("\n--- testBasicRecords ---"); record EmptyRecord () { } assertTrue(EmptyRecord.class.isRecord()); - assertEquals(EmptyRecord.class.getRecordComponents().length, 0); + assertEquals(0, EmptyRecord.class.getRecordComponents().length); record FooRecord (int x) { } assertTrue(FooRecord.class.isRecord()); - assertTrue(FooRecord.class.getRecordComponents() != null); + assertNotNull(FooRecord.class.getRecordComponents()); final record FinalFooRecord (int x) { } assertTrue(FinalFooRecord.class.isRecord()); - assertTrue(FinalFooRecord.class.getRecordComponents() != null); + assertNotNull(FinalFooRecord.class.getRecordComponents()); class A { } assertFalse(A.class.isRecord()); - assertFalse(A.class.getRecordComponents() != null); + assertNull(A.class.getRecordComponents()); final class B { } assertFalse(B.class.isRecord()); - assertFalse(B.class.getRecordComponents() != null); + assertNull(B.class.getRecordComponents()); } // -- infra diff --git a/test/jdk/java/lang/reflect/records/RecordReflectionTest.java b/test/jdk/java/lang/reflect/records/RecordReflectionTest.java index 0598e88f0c1..5cc2fd4f8eb 100644 --- a/test/jdk/java/lang/reflect/records/RecordReflectionTest.java +++ b/test/jdk/java/lang/reflect/records/RecordReflectionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2026, Oracle and/or its affiliates. All rights reserved. * 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,16 +27,17 @@ * @summary reflection test for records * @build R10 * @compile RecordReflectionTest.java - * @run testng/othervm RecordReflectionTest + * @run junit/othervm RecordReflectionTest */ import java.lang.annotation.*; import java.lang.reflect.*; import java.util.List; -import org.testng.annotations.*; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; -@Test public class RecordReflectionTest { class NoRecord {} @@ -78,8 +79,7 @@ public class RecordReflectionTest { R13 {} // compact constructor, will contain mandated parameters } - @DataProvider(name = "recordClasses") - public Object[][] recordClassData() { + public static Object[][] recordClassData() { return List.of(R1.class, R2.class, R3.class, @@ -96,17 +96,17 @@ public class RecordReflectionTest { ).stream().map(c -> new Object[] {c}).toArray(Object[][]::new); } - @Test(dataProvider = "recordClasses") + @ParameterizedTest + @MethodSource("recordClassData") public void testIsRecord(Class cls) { String message = cls.toGenericString(); assertTrue(cls.isRecord()); - assertTrue(cls.getSuperclass() == java.lang.Record.class); - assertTrue(cls.getRecordComponents() != null); + assertSame(Record.class, cls.getSuperclass()); + assertNotNull(cls.getRecordComponents()); assertTrue(message.contains("record"), message); } - @DataProvider(name = "notRecordClasses") - public Object[][] notRecordClasses() { + public static List> notRecordClasses() { return List.of(NoRecord.class, NoRecord[].class, Record.class, // java.lang.Record is not itself a record class @@ -116,19 +116,18 @@ public class RecordReflectionTest { int.class, int[].class, long.class, - long[].class) - .stream().map(c -> new Object[] {c}).toArray(Object[][]::new); + long[].class); } - @Test(dataProvider = "notRecordClasses") + @ParameterizedTest + @MethodSource("notRecordClasses") public void testNotARecordClass(Class cls) { assertFalse(cls.isRecord()); - assertFalse(cls.getSuperclass() == java.lang.Record.class); - assertTrue(cls.getRecordComponents() == null); + assertNotSame(Record.class, cls.getSuperclass()); + assertNull(cls.getRecordComponents()); } - @DataProvider(name = "reflectionData") - public Object[][] reflectionData() { + public static Object[][] reflectionData() { return new Object[][] { new Object[] { new R1(), 0, @@ -181,7 +180,8 @@ public class RecordReflectionTest { }; } - @Test(dataProvider = "reflectionData") + @ParameterizedTest + @MethodSource("reflectionData") public void testRecordReflection(Object recordOb, int numberOfComponents, Object[] values, @@ -192,13 +192,13 @@ public class RecordReflectionTest { Class recordClass = recordOb.getClass(); assertTrue(recordClass.isRecord()); RecordComponent[] recordComponents = recordClass.getRecordComponents(); - assertEquals(recordComponents.length, numberOfComponents); + assertEquals(numberOfComponents, recordComponents.length); int i = 0; for (RecordComponent rc : recordComponents) { - assertEquals(rc.getName(), names[i]); - assertEquals(rc.getType(), rc.getAccessor().getReturnType()); - assertEquals(rc.getAccessor().invoke(recordOb), values[i]); - assertEquals(rc.getAccessor().getGenericReturnType().toString(), signatures[i], + assertEquals(names[i], rc.getName()); + assertEquals(rc.getAccessor().getReturnType(), rc.getType()); + assertEquals(values[i], rc.getAccessor().invoke(recordOb)); + assertEquals(signatures[i], rc.getAccessor().getGenericReturnType().toString(), String.format("signature of method \"%s\" different from expected signature \"%s\"", rc.getAccessor().getGenericReturnType(), signatures[i])); i++; @@ -207,7 +207,7 @@ public class RecordReflectionTest { var constructor = recordClass.getDeclaredConstructors()[0]; i = 0; for (var p: constructor.getParameters()) { - assertEquals(p.getParameterizedType().toString(), signatures[i], + assertEquals(signatures[i], p.getParameterizedType().toString(), String.format("signature of method \"%s\" different from expected signature \"%s\"", p.getType().toString(), signatures[i])); i++; @@ -215,7 +215,7 @@ public class RecordReflectionTest { // similar as above but testing another API i = 0; for (var p : constructor.getGenericParameterTypes()) { - assertEquals(p.toString(), signatures[i], + assertEquals(signatures[i], p.toString(), String.format("signature of method \"%s\" different from expected signature \"%s\"", p.toString(), signatures[i])); i++; @@ -228,16 +228,17 @@ public class RecordReflectionTest { record AnnotatedRec(@RCA int i) {} + @Test public void testDeclAnnotationsInRecordComp() throws Throwable { Class recordClass = AnnotatedRec.class; RecordComponent rc = recordClass.getRecordComponents()[0]; Annotation[] annos = rc.getAnnotations(); - assertEquals(annos.length, 1); - assertEquals(annos[0].toString(), "@RecordReflectionTest.RCA()"); + assertEquals(1, annos.length); + assertEquals("@RecordReflectionTest.RCA()", annos[0].toString()); Field f = recordClass.getDeclaredField("i"); - assertEquals(f.getAnnotations().length, 1); - assertEquals(f.getAnnotations()[0].toString(), annos[0].toString()); + assertEquals(1, f.getAnnotations().length); + assertEquals(annos[0].toString(), f.getAnnotations()[0].toString()); } @Retention(RetentionPolicy.RUNTIME) @@ -246,30 +247,28 @@ public class RecordReflectionTest { record TypeAnnotatedRec(@TYPE_USE int i) {} + @Test public void testTypeAnnotationsInRecordComp() throws Throwable { Class recordClass = TypeAnnotatedRec.class; RecordComponent rc = recordClass.getRecordComponents()[0]; AnnotatedType at = rc.getAnnotatedType(); Annotation[] annos = at.getAnnotations(); - assertEquals(annos.length, 1); - assertEquals(annos[0].toString(), "@RecordReflectionTest.TYPE_USE()"); + assertEquals(1, annos.length); + assertEquals("@RecordReflectionTest.TYPE_USE()", annos[0].toString()); Field f = recordClass.getDeclaredField("i"); - assertEquals(f.getAnnotatedType().getAnnotations().length, 1); - assertEquals(f.getAnnotatedType().getAnnotations()[0].toString(), annos[0].toString()); + assertEquals(1, f.getAnnotatedType().getAnnotations().length); + assertEquals(annos[0].toString(), f.getAnnotatedType().getAnnotations()[0].toString()); } + @Test public void testReadOnlyFieldInRecord() throws Throwable { R2 o = new R2(1, 2); Class recordClass = R2.class; String fieldName = "i"; Field f = recordClass.getDeclaredField(fieldName); assertTrue(f.trySetAccessible()); - assertTrue(f.get(o) != null); - try { - f.set(o, null); - assertTrue(false, "should fail to set " + fieldName); - } catch (IllegalAccessException e) { - } + assertNotNull(f.get(o)); + assertThrows(IllegalAccessException.class, () -> f.set(o, null)); } } diff --git a/test/jdk/java/lang/reflect/sealed_classes/SealedClassesReflectionTest.java b/test/jdk/java/lang/reflect/sealed_classes/SealedClassesReflectionTest.java index 03caebb49e8..6e14a5d540e 100644 --- a/test/jdk/java/lang/reflect/sealed_classes/SealedClassesReflectionTest.java +++ b/test/jdk/java/lang/reflect/sealed_classes/SealedClassesReflectionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. * 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,18 +26,17 @@ * @bug 8227046 * @summary reflection test for sealed classes * @compile SealedClassesReflectionTest.java - * @run testng/othervm SealedClassesReflectionTest + * @run junit/othervm SealedClassesReflectionTest */ import java.lang.annotation.*; -import java.lang.constant.ClassDesc; import java.lang.reflect.*; import java.util.Arrays; import java.util.List; -import org.testng.annotations.*; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; -@Test public class SealedClassesReflectionTest { sealed class SealedClass1 permits FinalSubclass1, NonSealedSubclass1 {} @@ -68,8 +67,7 @@ public class SealedClassesReflectionTest { sealed class SealedSubclass2 implements SealedInt3 permits NonSealedSubclass2 {} non-sealed class NonSealedSubclass2 extends SealedSubclass2 {} - @DataProvider(name = "sealedClasses") - public Object[][] sealedClassesData() { + public static List> sealedClassesData() { return List.of( SealedClass1.class, SealedClass2.class, @@ -79,19 +77,19 @@ public class SealedClassesReflectionTest { SealedInt2.class, SealedInt3.class, SealedSubInt1.class - ).stream().map(c -> new Object[] {c}).toArray(Object[][]::new); + ); } - @Test(dataProvider = "sealedClasses") + @ParameterizedTest + @MethodSource("sealedClassesData") public void testSealedClasses(Class cls) { assertTrue(cls.isSealed()); - assertTrue(!Modifier.isFinal(cls.getModifiers())); - assertTrue(cls.getPermittedSubclasses() != null); + assertFalse(Modifier.isFinal(cls.getModifiers())); + assertNotNull(cls.getPermittedSubclasses()); assertTrue(cls.getPermittedSubclasses().length > 0); } - @DataProvider(name = "notSealedClasses") - public Object[][] notSealedClassesData() { + public static List> notSealedClassesData() { return List.of( Object.class, void.class, Void.class, Void[].class, @@ -104,34 +102,34 @@ public class SealedClassesReflectionTest { double.class, double[].class, Double.class, Double[].class, boolean.class, boolean[].class, Boolean.class, Boolean[].class, String.class, String[].class - ).stream().map(c -> new Object[] {c}).toArray(Object[][]::new); + ); } - @Test(dataProvider = "notSealedClasses") + @ParameterizedTest + @MethodSource("notSealedClassesData") public void testNotSealedClasses(Class cls) { - assertTrue(!cls.isSealed()); - assertTrue(cls.getPermittedSubclasses() == null); + assertFalse(cls.isSealed()); + assertNull(cls.getPermittedSubclasses()); } - @DataProvider(name = "non_sealedClasses") - public Object[][] non_sealedClassesData() { + public static List> non_sealedClassesData() { return List.of( NonSealedSubclass1.class, NonSealedSubInt1.class, NonSealedSubclass2.class - ).stream().map(c -> new Object[] {c}).toArray(Object[][]::new); + ); } - @Test(dataProvider = "non_sealedClasses") + @ParameterizedTest + @MethodSource("non_sealedClassesData") public void testnon_sealedClasses(Class cls) { - assertTrue(!cls.isSealed()); - assertTrue(!Modifier.isFinal(cls.getModifiers())); + assertFalse(cls.isSealed()); + assertFalse(Modifier.isFinal(cls.getModifiers())); assertTrue((cls.getSuperclass() != null && cls.getSuperclass().isSealed()) || Arrays.stream(cls.getInterfaces()).anyMatch(Class::isSealed)); - assertTrue(cls.getPermittedSubclasses() == null); + assertNull(cls.getPermittedSubclasses()); } - @DataProvider(name = "reflectionData") - public Object[][] reflectionData() { + public static Object[][] reflectionData() { return new Object[][] { new Object[] { SealedClass1.class, @@ -204,7 +202,8 @@ public class SealedClassesReflectionTest { SEALED, NON_SEALED, FINAL } - @Test(dataProvider = "reflectionData") + @ParameterizedTest + @MethodSource("reflectionData") public void testSealedReflection(Class sealedClass, int numberOfSubclasses, String[] subclassDescriptors, @@ -213,10 +212,10 @@ public class SealedClassesReflectionTest { throws ReflectiveOperationException { assertTrue(sealedClass.isSealed()); - assertTrue(sealedClass.getPermittedSubclasses().length == numberOfSubclasses); + assertEquals(numberOfSubclasses, sealedClass.getPermittedSubclasses().length); int i = 0; for (Class cd : sealedClass.getPermittedSubclasses()) { - assertTrue(cd.getName().equals(subclassDescriptors[i]), "expected: " + subclassDescriptors[i] + " found: " + cd.getName()); + assertEquals(subclassDescriptors[i], cd.getName()); i++; } i = 0; diff --git a/test/jdk/java/lang/runtime/ExactnessConversionsSupportTest.java b/test/jdk/java/lang/runtime/ExactnessConversionsSupportTest.java index 6e1ef8e4c9f..3fbdfc5e9ab 100644 --- a/test/jdk/java/lang/runtime/ExactnessConversionsSupportTest.java +++ b/test/jdk/java/lang/runtime/ExactnessConversionsSupportTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,46 +21,20 @@ * questions. */ -import org.testng.annotations.Test; - -import java.io.Serializable; -import java.lang.Enum.EnumDesc; -import java.lang.classfile.ClassFile; -import java.lang.constant.ClassDesc; -import java.lang.constant.ConstantDescs; -import java.lang.constant.MethodTypeDesc; -import java.lang.invoke.CallSite; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; -import java.lang.reflect.AccessFlag; import java.lang.runtime.ExactConversionsSupport; -import java.lang.runtime.SwitchBootstraps; -import java.util.concurrent.atomic.AtomicBoolean; - -import static org.testng.Assert.*; +import org.junit.jupiter.api.Test; /** * @test * @bug 8304487 * @summary Verify boundary and special cases of exact conversion predicates * @compile ExactnessConversionsSupportTest.java - * @run testng/othervm ExactnessConversionsSupportTest + * @run junit/othervm ExactnessConversionsSupportTest */ -@Test public class ExactnessConversionsSupportTest { - public static void main(String[] args) { - testByte(); - testShort(); - testChar(); - testInt(); - testLong(); - testFloat(); - testDouble(); - } - - public static void testByte() { + @Test + public void testByte() { assertEquals(true, ExactConversionsSupport.isIntToByteExact((byte) (Byte.MAX_VALUE))); assertEquals(true, ExactConversionsSupport.isIntToByteExact((byte) (0))); assertEquals(true, ExactConversionsSupport.isIntToByteExact((byte) (Byte.MIN_VALUE))); @@ -92,7 +66,8 @@ public class ExactnessConversionsSupportTest { assertEquals(false, ExactConversionsSupport.isDoubleToByteExact(-0.0d)); assertEquals(true, ExactConversionsSupport.isDoubleToByteExact(+0.0d)); } - public static void testShort() { + @Test + public void testShort() { assertEquals(true, ExactConversionsSupport.isIntToShortExact((byte) (Byte.MAX_VALUE))); assertEquals(true, ExactConversionsSupport.isIntToShortExact((byte) (0))); assertEquals(true, ExactConversionsSupport.isIntToShortExact((byte) (Byte.MIN_VALUE))); @@ -125,7 +100,8 @@ public class ExactnessConversionsSupportTest { assertEquals(false, ExactConversionsSupport.isDoubleToShortExact(-0.0d)); assertEquals(true, ExactConversionsSupport.isDoubleToShortExact(+0.0d)); } - public static void testChar() { + @Test + public void testChar() { assertEquals(true, ExactConversionsSupport.isIntToCharExact((byte) (Byte.MAX_VALUE))); assertEquals(true, ExactConversionsSupport.isIntToCharExact((byte) (0))); assertEquals(false, ExactConversionsSupport.isIntToCharExact((byte) (Byte.MIN_VALUE))); @@ -157,7 +133,8 @@ public class ExactnessConversionsSupportTest { assertEquals(false, ExactConversionsSupport.isDoubleToCharExact(-0.0d)); assertEquals(true, ExactConversionsSupport.isDoubleToCharExact(+0.0d)); } - public static void testInt() { + @Test + public void testInt() { assertEquals(false, ExactConversionsSupport.isLongToIntExact((Long.MAX_VALUE))); assertEquals(true, ExactConversionsSupport.isLongToIntExact((0L))); assertEquals(false, ExactConversionsSupport.isLongToIntExact((Long.MIN_VALUE))); @@ -178,7 +155,8 @@ public class ExactnessConversionsSupportTest { assertEquals(false, ExactConversionsSupport.isDoubleToIntExact((-0.0d))); assertEquals(true, ExactConversionsSupport.isDoubleToIntExact((+0.0d))); } - public static void testLong() { + @Test + public void testLong() { assertEquals(false, ExactConversionsSupport.isFloatToLongExact((Float.MAX_VALUE))); assertEquals(true, ExactConversionsSupport.isFloatToLongExact(((float) 0))); assertEquals(false, ExactConversionsSupport.isFloatToLongExact((Float.MIN_VALUE))); @@ -196,7 +174,8 @@ public class ExactnessConversionsSupportTest { assertEquals(false, ExactConversionsSupport.isDoubleToLongExact((-0.0d))); assertEquals(true, ExactConversionsSupport.isDoubleToLongExact((+0.0d))); } - public static void testFloat() { + @Test + public void testFloat() { assertEquals(true, ExactConversionsSupport.isIntToFloatExact(((byte) (Byte.MAX_VALUE)))); assertEquals(true, ExactConversionsSupport.isIntToFloatExact(((byte) (0)))); assertEquals(true, ExactConversionsSupport.isIntToFloatExact(((byte) (Byte.MIN_VALUE)))); @@ -220,7 +199,8 @@ public class ExactnessConversionsSupportTest { assertEquals(true, ExactConversionsSupport.isDoubleToFloatExact((-0.0d))); assertEquals(true, ExactConversionsSupport.isDoubleToFloatExact((+0.0d))); } - public static void testDouble() { + @Test + public void testDouble() { assertEquals(false, ExactConversionsSupport.isLongToDoubleExact((Long.MAX_VALUE))); assertEquals(true, ExactConversionsSupport.isLongToDoubleExact((0L))); assertEquals(true, ExactConversionsSupport.isLongToDoubleExact((Long.MIN_VALUE))); diff --git a/test/jdk/java/lang/runtime/ObjectMethodsTest.java b/test/jdk/java/lang/runtime/ObjectMethodsTest.java index 62c8b034ed1..951d3b68383 100644 --- a/test/jdk/java/lang/runtime/ObjectMethodsTest.java +++ b/test/jdk/java/lang/runtime/ObjectMethodsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ * @test * @bug 8246774 * @summary Basic tests for ObjectMethods - * @run testng ObjectMethodsTest + * @run junit ObjectMethodsTest */ import java.util.List; @@ -34,14 +34,14 @@ import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.lang.runtime.ObjectMethods; -import org.testng.annotations.Test; import static java.lang.invoke.MethodType.methodType; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertThrows; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertTrue; -@Test +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; + public class ObjectMethodsTest { public static class C { @@ -80,6 +80,7 @@ public class ObjectMethodsTest { static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup(); + @Test public void testEqualsC() throws Throwable { CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "equals", C.EQUALS_DESC, C.class, C.NAME_LIST, C.ACCESSORS); MethodHandle handle = cs.dynamicInvoker(); @@ -92,6 +93,7 @@ public class ObjectMethodsTest { assertFalse((boolean)handle.invokeExact(c, new Object())); } + @Test public void testEqualsEmpty() throws Throwable { CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "equals", Empty.EQUALS_DESC, Empty.class, Empty.NAME_LIST, Empty.ACCESSORS); MethodHandle handle = cs.dynamicInvoker(); @@ -102,45 +104,50 @@ public class ObjectMethodsTest { assertFalse((boolean)handle.invokeExact(e, new Object())); } + @Test public void testHashCodeC() throws Throwable { CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "hashCode", C.HASHCODE_DESC, C.class, "x;y", C.ACCESSORS); MethodHandle handle = cs.dynamicInvoker(); C c = new C(6, 7); int hc = (int)handle.invokeExact(c); - assertEquals(hc, hashCombiner(c.x(), c.y())); + assertEquals(hashCombiner(c.x(), c.y()), hc); - assertEquals((int)handle.invokeExact(new C(100, 1)), hashCombiner(100, 1)); - assertEquals((int)handle.invokeExact(new C(0, 0)), hashCombiner(0, 0)); - assertEquals((int)handle.invokeExact(new C(-1, 100)), hashCombiner(-1, 100)); - assertEquals((int)handle.invokeExact(new C(100, 1)), hashCombiner(100, 1)); - assertEquals((int)handle.invokeExact(new C(100, -1)), hashCombiner(100, -1)); + assertEquals(hashCombiner(100, 1), (int)handle.invokeExact(new C(100, 1))); + assertEquals(hashCombiner(0, 0), (int)handle.invokeExact(new C(0, 0))); + assertEquals(hashCombiner(-1, 100), (int)handle.invokeExact(new C(-1, 100))); + assertEquals(hashCombiner(100, 1), (int)handle.invokeExact(new C(100, 1))); + assertEquals(hashCombiner(100, -1), (int)handle.invokeExact(new C(100, -1))); } + @Test public void testHashCodeEmpty() throws Throwable { CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "hashCode", Empty.HASHCODE_DESC, Empty.class, "", Empty.ACCESSORS); MethodHandle handle = cs.dynamicInvoker(); Empty e = new Empty(); - assertEquals((int)handle.invokeExact(e), 0); + assertEquals(0, (int)handle.invokeExact(e)); } + @Test public void testToStringC() throws Throwable { CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "toString", C.TO_STRING_DESC, C.class, C.NAME_LIST, C.ACCESSORS); MethodHandle handle = cs.dynamicInvoker(); - assertEquals((String)handle.invokeExact(new C(8, 9)), "C[x=8, y=9]" ); - assertEquals((String)handle.invokeExact(new C(10, 11)), "C[x=10, y=11]" ); - assertEquals((String)handle.invokeExact(new C(100, -9)), "C[x=100, y=-9]"); - assertEquals((String)handle.invokeExact(new C(0, 0)), "C[x=0, y=0]" ); + assertEquals("C[x=8, y=9]", (String)handle.invokeExact(new C(8, 9)) ); + assertEquals("C[x=10, y=11]", (String)handle.invokeExact(new C(10, 11)) ); + assertEquals("C[x=100, y=-9]", (String)handle.invokeExact(new C(100, -9))); + assertEquals("C[x=0, y=0]", (String)handle.invokeExact(new C(0, 0)) ); } + @Test public void testToStringEmpty() throws Throwable { CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "toString", Empty.TO_STRING_DESC, Empty.class, Empty.NAME_LIST, Empty.ACCESSORS); MethodHandle handle = cs.dynamicInvoker(); - assertEquals((String)handle.invokeExact(new Empty()), "Empty[]"); + assertEquals("Empty[]", (String)handle.invokeExact(new Empty())); } Class NPE = NullPointerException.class; Class IAE = IllegalArgumentException.class; + @Test public void exceptions() { assertThrows(IAE, () -> ObjectMethods.bootstrap(LOOKUP, "badName", C.EQUALS_DESC, C.class, C.NAME_LIST, C.ACCESSORS)); assertThrows(IAE, () -> ObjectMethods.bootstrap(LOOKUP, "toString", C.TO_STRING_DESC, C.class, "x;y;z", C.ACCESSORS)); diff --git a/test/jdk/java/lang/runtime/SwitchBootstrapsTest.java b/test/jdk/java/lang/runtime/SwitchBootstrapsTest.java index 3a8608866dc..061ce2ae241 100644 --- a/test/jdk/java/lang/runtime/SwitchBootstrapsTest.java +++ b/test/jdk/java/lang/runtime/SwitchBootstrapsTest.java @@ -35,21 +35,20 @@ import java.lang.runtime.SwitchBootstraps; import java.util.concurrent.atomic.AtomicBoolean; import java.lang.classfile.ClassFile; -import org.testng.annotations.Test; +import org.junit.jupiter.api.Test; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertTrue; -import static org.testng.Assert.fail; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * @test * @bug 8318144 * @enablePreview * @compile SwitchBootstrapsTest.java - * @run testng/othervm SwitchBootstrapsTest + * @run junit/othervm SwitchBootstrapsTest */ -@Test public class SwitchBootstrapsTest { public static final MethodHandle BSM_TYPE_SWITCH; @@ -70,14 +69,14 @@ public class SwitchBootstrapsTest { private void testType(Object target, int start, int result, Object... labels) throws Throwable { MethodType switchType = MethodType.methodType(int.class, Object.class, int.class); MethodHandle indy = ((CallSite) BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", switchType, labels)).dynamicInvoker(); - assertEquals((int) indy.invoke(target, start), result); + assertEquals(result, (int) indy.invoke(target, start)); assertEquals(-1, (int) indy.invoke(null, start)); } private void testPrimitiveType(Object target, Class targetType, int start, int result, Object... labels) throws Throwable { MethodType switchType = MethodType.methodType(int.class, targetType, int.class); MethodHandle indy = ((CallSite) BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", switchType, labels)).dynamicInvoker(); - assertEquals((int) indy.invoke(target, start), result); + assertEquals(result, (int) indy.invoke(target, start)); } private void testEnum(Enum target, int start, int result, Object... labels) throws Throwable { @@ -87,7 +86,7 @@ public class SwitchBootstrapsTest { private void testEnum(Class targetClass, Enum target, int start, int result, Object... labels) throws Throwable { MethodType switchType = MethodType.methodType(int.class, targetClass, int.class); MethodHandle indy = ((CallSite) BSM_ENUM_SWITCH.invoke(MethodHandles.lookup(), "", switchType, labels)).dynamicInvoker(); - assertEquals((int) indy.invoke(target, start), result); + assertEquals(result, (int) indy.invoke(target, start)); assertEquals(-1, (int) indy.invoke(null, start)); } @@ -100,6 +99,7 @@ public class SwitchBootstrapsTest { C; } + @Test public void testTypes() throws Throwable { testType("", 0, 0, String.class, Object.class); testType("", 0, 0, Object.class); @@ -138,6 +138,7 @@ public class SwitchBootstrapsTest { }, 0, 1, 1L); } + @Test public void testPrimitiveTypes() throws Throwable { testPrimitiveType((short) 1, short.class, 0, 1, String.class); testPrimitiveType((byte) 1, byte.class,0, 1, String.class, byte.class); @@ -150,52 +151,32 @@ public class SwitchBootstrapsTest { testPrimitiveType(true, boolean.class,0, 1, String.class, boolean.class); } + @Test public void testEnums() throws Throwable { testEnum(E1.A, 0, 2, "B", "C", "A", E1.class); testEnum(E1.B, 0, 0, "B", "C", "A", E1.class); testEnum(E1.B, 1, 3, "B", "C", "A", E1.class); - try { - testEnum(E1.B, 0, -1, E2.class); - fail("Didn't get the expected exception."); - } catch (IllegalArgumentException ex) { - //OK - } - try { - testEnum(E1.B, 0, -1, String.class); - fail("Didn't get the expected exception."); - } catch (IllegalArgumentException ex) { - //OK - } - try { - testEnum(E1.B, 0, -1, 10); - fail("Didn't get the expected exception."); - } catch (IllegalArgumentException ex) { - //OK - } - try { - testEnum(E1.B, 0, -1, new Object()); - fail("Didn't get the expected exception."); - } catch (IllegalArgumentException ex) { - //OK - } - try { - testEnum(E1.B, 0, -1, new Object[] { null }); - fail("Didn't get the expected exception."); - } catch (IllegalArgumentException ex) { - //OK - } - try { - testEnum(E1.B, 0, -1, ""); - fail("Didn't get the expected exception."); - } catch (IllegalArgumentException ex) { - //OK - } - try { - testEnum(E1.B, 0, -1, (Object[]) null); - fail("Didn't get the expected exception."); - } catch (NullPointerException ex) { - //OK - } + assertThrows(IllegalArgumentException.class, () -> + testEnum(E1.B, 0, -1, E2.class) + ); + assertThrows(IllegalArgumentException.class, () -> + testEnum(E1.B, 0, -1, String.class) + ); + assertThrows(IllegalArgumentException.class, () -> + testEnum(E1.B, 0, -1, 10) + ); + assertThrows(IllegalArgumentException.class, () -> + testEnum(E1.B, 0, -1, new Object()) + ); + assertThrows(IllegalArgumentException.class, () -> + testEnum(E1.B, 0, -1, new Object[] { null }) + ); + assertThrows(IllegalArgumentException.class, () -> + testEnum(E1.B, 0, -1, "") + ); + assertThrows(NullPointerException.class, () -> + testEnum(E1.B, 0, -1, (Object[]) null) + ); testEnum(E1.B, 0, 0, "B", "A"); testEnum(E1.A, 0, 1, "B", "A"); testEnum(E1.A, 0, 0, "A", "A", "B"); @@ -208,9 +189,10 @@ public class SwitchBootstrapsTest { //null invocation name: MethodType switchType = MethodType.methodType(int.class, E1.class, int.class); MethodHandle indy = ((CallSite) BSM_ENUM_SWITCH.invoke(MethodHandles.lookup(), null, switchType)).dynamicInvoker(); - assertEquals((int) indy.invoke(E1.A, 0), 0); + assertEquals(0, (int) indy.invoke(E1.A, 0)); } + @Test public void testEnumsWithConstants() throws Throwable { enum E { A {}, @@ -239,18 +221,16 @@ public class SwitchBootstrapsTest { testEnum(E.class, E.C, 2, 2, "A", "B"); } + @Test public void testWrongSwitchTypes() throws Throwable { MethodType[] switchTypes = new MethodType[] { MethodType.methodType(int.class, Object.class), MethodType.methodType(int.class, Object.class, Integer.class) }; for (MethodType switchType : switchTypes) { - try { - BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", switchType); - fail("Didn't get the expected exception."); - } catch (IllegalArgumentException ex) { - //OK, expected - } + assertThrows(IllegalArgumentException.class, () -> + BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", switchType) + ); } MethodType[] enumSwitchTypes = new MethodType[] { MethodType.methodType(int.class, Enum.class), @@ -259,25 +239,21 @@ public class SwitchBootstrapsTest { MethodType.methodType(int.class, Enum.class, Integer.class) }; for (MethodType enumSwitchType : enumSwitchTypes) { - try { - BSM_ENUM_SWITCH.invoke(MethodHandles.lookup(), "", enumSwitchType); - fail("Didn't get the expected exception."); - } catch (IllegalArgumentException ex) { - //OK, expected - } + assertThrows(IllegalArgumentException.class, () -> + BSM_ENUM_SWITCH.invoke(MethodHandles.lookup(), "", enumSwitchType) + ); } } + @Test public void testSwitchLabelTypes() throws Throwable { enum E {A} - try { - testType(E.A, 0, -1, E.A); - fail("Didn't get the expected exception."); - } catch (IllegalArgumentException ex) { - //OK, expected - } + assertThrows(IllegalArgumentException.class, () -> + testType(E.A, 0, -1, E.A) + ); } + @Test public void testSwitchQualifiedEnum() throws Throwable { enum E {A, B, C} Object[] labels = new Object[] { @@ -290,41 +266,31 @@ public class SwitchBootstrapsTest { testType(E.C, 0, 2, labels); } + @Test public void testNullLabels() throws Throwable { MethodType switchType = MethodType.methodType(int.class, Object.class, int.class); - try { - BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", switchType, (Object[]) null); - fail("Didn't get the expected exception."); - } catch (NullPointerException ex) { - //OK - } - try { + assertThrows(NullPointerException.class, () -> + BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", switchType, (Object[]) null) + ); + assertThrows(IllegalArgumentException.class, () -> BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", switchType, - new Object[] {1, null, String.class}); - fail("Didn't get the expected exception."); - } catch (IllegalArgumentException ex) { - //OK - } + new Object[] {1, null, String.class}) + ); MethodType enumSwitchType = MethodType.methodType(int.class, E1.class, int.class); - try { - BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", enumSwitchType, (Object[]) null); - fail("Didn't get the expected exception."); - } catch (NullPointerException ex) { - //OK - } - try { + assertThrows(NullPointerException.class, () -> + BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", enumSwitchType, (Object[]) null) + ); + assertThrows(IllegalArgumentException.class, () -> BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", enumSwitchType, - new Object[] {1, null, String.class}); - fail("Didn't get the expected exception."); - } catch (IllegalArgumentException ex) { - //OK - } + new Object[] {1, null, String.class}) + ); //null invocationName is OK: BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), null, switchType, new Object[] {Object.class}); } private static AtomicBoolean enumInitialized = new AtomicBoolean(); + @Test public void testEnumInitialization1() throws Throwable { enumInitialized.set(false); @@ -340,13 +306,14 @@ public class SwitchBootstrapsTest { CallSite invocation = (CallSite) BSM_ENUM_SWITCH.invoke(MethodHandles.lookup(), "", enumSwitchType, new Object[] {"A"}); assertFalse(enumInitialized.get()); - assertEquals(invocation.dynamicInvoker().invoke(null, 0), -1); + assertEquals(-1, invocation.dynamicInvoker().invoke(null, 0)); assertFalse(enumInitialized.get()); E e = E.A; assertTrue(enumInitialized.get()); - assertEquals(invocation.dynamicInvoker().invoke(e, 0), 0); + assertEquals(0, invocation.dynamicInvoker().invoke(e, 0)); } + @Test public void testEnumInitialization2() throws Throwable { enumInitialized.set(false); @@ -365,60 +332,46 @@ public class SwitchBootstrapsTest { }; CallSite invocation = (CallSite) BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", switchType, labels); assertFalse(enumInitialized.get()); - assertEquals(invocation.dynamicInvoker().invoke(null, 0), -1); + assertEquals(-1, invocation.dynamicInvoker().invoke(null, 0)); assertFalse(enumInitialized.get()); - assertEquals(invocation.dynamicInvoker().invoke("test", 0), 1); + assertEquals(1, invocation.dynamicInvoker().invoke("test", 0)); assertFalse(enumInitialized.get()); E e = E.A; assertTrue(enumInitialized.get()); - assertEquals(invocation.dynamicInvoker().invoke(e, 0), 0); + assertEquals(0, invocation.dynamicInvoker().invoke(e, 0)); } + @Test public void testIncorrectEnumLabels() throws Throwable { - try { - testEnum(E1.B, 0, -1, "B", 1); - fail("Didn't get the expected exception."); - } catch (IllegalArgumentException ex) { - //OK - } - try { - testEnum(E1.B, 0, -1, "B", null); - fail("Didn't get the expected exception."); - } catch (IllegalArgumentException ex) { - //OK - } + assertThrows(IllegalArgumentException.class, () -> + testEnum(E1.B, 0, -1, "B", 1) + ); + assertThrows(IllegalArgumentException.class, () -> + testEnum(E1.B, 0, -1, "B", null) + ); } + @Test public void testIncorrectEnumStartIndex() throws Throwable { - try { - testEnum(E1.B, -1, -1, "B"); - fail("Didn't get the expected exception."); - } catch (IndexOutOfBoundsException ex) { - //OK - } - try { - testEnum(E1.B, 2, -1, "B"); - fail("Didn't get the expected exception."); - } catch (IndexOutOfBoundsException ex) { - //OK - } + assertThrows(IndexOutOfBoundsException.class, () -> + testEnum(E1.B, -1, -1, "B") + ); //OK + assertThrows(IndexOutOfBoundsException.class, () -> + testEnum(E1.B, 2, -1, "B") + ); } + @Test public void testIncorrectTypeStartIndex() throws Throwable { - try { - testType("", -1, -1, ""); - fail("Didn't get the expected exception."); - } catch (IndexOutOfBoundsException ex) { - //OK - } - try { - testType("", 2, -1, ""); - fail("Didn't get the expected exception."); - } catch (IndexOutOfBoundsException ex) { - //OK - } + assertThrows(IndexOutOfBoundsException.class, () -> + testType("", -1, -1, "") + ); + assertThrows(IndexOutOfBoundsException.class, () -> + testType("", 2, -1, "") + ); } + @Test public void testHiddenClassAsCaseLabel() throws Throwable { MethodHandles.Lookup lookup = MethodHandles.lookup(); byte[] classBytes = createClass(); @@ -448,30 +401,22 @@ public class SwitchBootstrapsTest { }); } + @Test public void testNullLookup() throws Throwable { - try { + assertThrows(NullPointerException.class, () -> { MethodType switchType = MethodType.methodType(int.class, Object.class, int.class); BSM_TYPE_SWITCH.invoke(null, "", switchType, Object.class); - fail("Didn't get the expected exception."); - } catch (NullPointerException ex) { - //OK - } + }); enum E {} - try { + assertThrows(NullPointerException.class, () -> { MethodType switchType = MethodType.methodType(int.class, E.class, int.class); BSM_ENUM_SWITCH.invoke(null, "", switchType, - new Object[] {}); - fail("Didn't get the expected exception."); - } catch (NullPointerException ex) { - //OK - } - try { + new Object[] {}); + }); + assertThrows(NullPointerException.class, () -> { MethodType switchType = MethodType.methodType(int.class, E.class, int.class); BSM_ENUM_SWITCH.invoke(null, "", switchType, - new Object[] {"A"}); - fail("Didn't get the expected exception."); - } catch (NullPointerException ex) { - //OK - } + new Object[] {"A"}); + }); } } diff --git a/test/jdk/java/net/httpclient/CancelRequestTest.java b/test/jdk/java/net/httpclient/CancelRequestTest.java index 86e06bb78f7..2a0ec19a0ed 100644 --- a/test/jdk/java/net/httpclient/CancelRequestTest.java +++ b/test/jdk/java/net/httpclient/CancelRequestTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,7 +49,6 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLHandshakeException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -65,6 +64,7 @@ import java.net.http.HttpResponse.BodyHandlers; import java.util.Arrays; import java.util.Iterator; import java.util.List; +import java.util.Objects; import java.util.Random; import java.util.concurrent.CancellationException; import java.util.concurrent.CompletableFuture; @@ -87,11 +87,14 @@ import static java.net.http.HttpOption.H3_DISCOVERY; import static java.nio.charset.StandardCharsets.UTF_8; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotEquals; import static org.testng.Assert.assertTrue; public class CancelRequestTest implements HttpServerAdapters { private static final Random random = RandomFactory.getRandom(); + private static final ConcurrentHashMap latches + = new ConcurrentHashMap<>(); private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); HttpTestServer httpTestServer; // HTTP/1.1 [ 4 servers ] @@ -117,6 +120,7 @@ public class CancelRequestTest implements HttpServerAdapters { static volatile boolean tasksFailed; static final AtomicLong serverCount = new AtomicLong(); static final AtomicLong clientCount = new AtomicLong(); + static final AtomicLong requestCount = new AtomicLong(); static final long start = System.nanoTime(); public static String now() { long now = System.nanoTime() - start; @@ -278,10 +282,12 @@ public class CancelRequestTest implements HttpServerAdapters { // set HTTP/3 version on the request when targeting // an HTTP/3 server private HttpRequest.Builder requestBuilder(String uri) { - var builder = HttpRequest.newBuilder(URI.create(uri)); + var u = URI.create(uri+"?req="+requestCount.incrementAndGet()); + var builder = HttpRequest.newBuilder(u); if (uri.contains("h3")) { builder.version(HTTP_3); } + builder.setHeader("X-expect-exception", "true"); return builder; } @@ -324,6 +330,24 @@ public class CancelRequestTest implements HttpServerAdapters { assertEquals(resp.statusCode(), 200); } + private static void releaseLatches() { + // release left over latches + for (var latch : latches.values()) { + latch.countDown(); + } + latches.clear(); + } + + private static CountDownLatch addLatchFor(HttpRequest req) { + // release left over latches + releaseLatches(); + String key = Objects.requireNonNull(req.uri().getRawQuery(), "query"); + var latch = new CountDownLatch(1); + latches.put(key, latch); + out.println(now() + "CountDownLatch " + latch + " added for " + req.uri()); + return latch; + } + @Test(dataProvider = "asyncurls") public void testGetSendAsync(String uri, boolean sameClient, boolean mayInterruptIfRunning) throws Exception { @@ -343,18 +367,21 @@ public class CancelRequestTest implements HttpServerAdapters { .GET() .setOption(H3_DISCOVERY, config) .build(); + var requestLatch = addLatchFor(req); + BodyHandler handler = BodyHandlers.ofString(); CountDownLatch latch = new CountDownLatch(1); + out.println(now() + "Sending (async): " + req.uri()); CompletableFuture> response = client.sendAsync(req, handler); var cf1 = response.whenComplete((r,t) -> System.out.println(t)); CompletableFuture> cf2 = cf1.whenComplete((r,t) -> latch.countDown()); - out.println("iteration: " + i + ", req: " + req.uri()); + out.println(now() + "iteration: " + i + ", req sent: " + req.uri()); out.println("response: " + response); out.println("cf1: " + cf1); out.println("cf2: " + cf2); delay(); cf1.cancel(mayInterruptIfRunning); - out.println("response after cancel: " + response); + out.println(now() + "response after cancel: " + response); out.println("cf1 after cancel: " + cf1); out.println("cf2 after cancel: " + cf2); try { @@ -362,8 +389,10 @@ public class CancelRequestTest implements HttpServerAdapters { assertEquals(body, String.join("", BODY.split("\\|"))); throw new AssertionError("Expected CancellationException not received"); } catch (ExecutionException x) { - out.println("Got expected exception: " + x); + out.println(now() + "Got expected exception: " + x); assertTrue(isCancelled(x)); + } finally { + requestLatch.countDown(); } // Cancelling the request may cause an IOException instead... @@ -371,7 +400,7 @@ public class CancelRequestTest implements HttpServerAdapters { try { cf1.get(); } catch (CancellationException | ExecutionException x) { - out.println("Got expected exception: " + x); + out.println(now() + "Got expected exception: " + x); assertTrue(isCancelled(x)); hasCancellationException = x instanceof CancellationException; } @@ -393,7 +422,7 @@ public class CancelRequestTest implements HttpServerAdapters { if (mayInterruptIfRunning) { if (CancellationException.class.isAssignableFrom(wrapped.getClass())) { cause = wrapped.getCause(); - out.println("CancellationException cause: " + x); + out.println(now() + "CancellationException cause: " + x); } else if (!isCancelled(cause)) { throw new RuntimeException("Unexpected cause: " + cause); } @@ -403,15 +432,15 @@ public class CancelRequestTest implements HttpServerAdapters { } } if (!IOException.class.isInstance(cause)) { - out.println("Unexpected cause: " + cause.getClass()); + out.println(now() + "Unexpected cause: " + cause.getClass()); cause.printStackTrace(out); } assertTrue(IOException.class.isAssignableFrom(cause.getClass())); if (mayInterruptIfRunning) { - out.println("Got expected exception: " + wrapped); + out.println(now() + "Got expected exception: " + wrapped); out.println("\tcause: " + cause); } else { - out.println("Unexpected exception: " + wrapped); + out.println(now() + "Unexpected exception: " + wrapped); wrapped.printStackTrace(out); throw x; } @@ -453,13 +482,13 @@ public class CancelRequestTest implements HttpServerAdapters { @Override public Iterator iterator() { // this is dangerous - out.println("waiting for completion on: " + cancelFuture); + out.println(now() + "waiting for completion on: " + cancelFuture); boolean async = random.nextBoolean(); Runnable cancel = () -> { - out.println("Cancelling from " + Thread.currentThread()); + out.println(now() + "Cancelling from " + Thread.currentThread()); var cf1 = cancelFuture.join(); cf1.cancel(mayInterruptIfRunning); - out.println("cancelled " + cf1); + out.println(now() + "cancelled " + cf1); }; if (async) executor.execute(cancel); else cancel.run(); @@ -474,16 +503,20 @@ public class CancelRequestTest implements HttpServerAdapters { .POST(HttpRequest.BodyPublishers.ofByteArrays(iterable)) .setOption(H3_DISCOVERY, config) .build(); + var requestLatch = addLatchFor(req); + BodyHandler handler = BodyHandlers.ofString(); CountDownLatch latch = new CountDownLatch(1); + out.println(now() + "Sending (async): " + req.uri()); CompletableFuture> response = client.sendAsync(req, handler); - var cf1 = response.whenComplete((r,t) -> System.out.println(t)); + var cf1 = response.whenComplete((r,t) -> System.out.println(now() + t)); CompletableFuture> cf2 = cf1.whenComplete((r,t) -> latch.countDown()); + out.println(now() + "iteration: " + i + ", req sent: " + req.uri()); out.println("response: " + response); out.println("cf1: " + cf1); out.println("cf2: " + cf2); cancelFuture.complete(cf1); - out.println("response after cancel: " + response); + out.println(now() + "response after cancel: " + response); out.println("cf1 after cancel: " + cf1); out.println("cf2 after cancel: " + cf2); try { @@ -491,8 +524,10 @@ public class CancelRequestTest implements HttpServerAdapters { assertEquals(body, String.join("", BODY.split("\\|"))); throw new AssertionError("Expected CancellationException not received"); } catch (ExecutionException x) { - out.println("Got expected exception: " + x); + out.println(now() + "Got expected exception: " + x); assertTrue(isCancelled(x)); + } finally { + requestLatch.countDown(); } // Cancelling the request may cause an IOException instead... @@ -500,7 +535,7 @@ public class CancelRequestTest implements HttpServerAdapters { try { cf1.get(); } catch (CancellationException | ExecutionException x) { - out.println("Got expected exception: " + x); + out.println(now() + "Got expected exception: " + x); assertTrue(isCancelled(x)); hasCancellationException = x instanceof CancellationException; } @@ -521,7 +556,7 @@ public class CancelRequestTest implements HttpServerAdapters { Throwable cause = wrapped; if (CancellationException.class.isAssignableFrom(wrapped.getClass())) { cause = wrapped.getCause(); - out.println("CancellationException cause: " + x); + out.println(now() + "CancellationException cause: " + x); } else if (!isCancelled(cause)) { throw new RuntimeException("Unexpected cause: " + cause); } @@ -531,10 +566,10 @@ public class CancelRequestTest implements HttpServerAdapters { throw new RuntimeException("Unexpected timeout exception", cause); } if (mayInterruptIfRunning) { - out.println("Got expected exception: " + wrapped); + out.println(now() + "Got expected exception: " + wrapped); out.println("\tcause: " + cause); } else { - out.println("Unexpected exception: " + wrapped); + out.println(now() + "Unexpected exception: " + wrapped); wrapped.printStackTrace(out); throw x; } @@ -571,7 +606,7 @@ public class CancelRequestTest implements HttpServerAdapters { Thread main = Thread.currentThread(); CompletableFuture interruptingThread = new CompletableFuture<>(); - var uriStr = uri + "/post/req=" + i; + var uriStr = uri + "/post/i=" + i; Runnable interrupt = () -> { Thread current = Thread.currentThread(); out.printf("%s Interrupting main from: %s (%s)%n", now(), current, uriStr); @@ -593,39 +628,42 @@ public class CancelRequestTest implements HttpServerAdapters { .POST(HttpRequest.BodyPublishers.ofByteArrays(iterable)) .setOption(H3_DISCOVERY, config) .build(); + var requestLatch = addLatchFor(req); + String body = null; Exception failed = null; try { - out.println("Sending: " + uriStr); + out.println(now() + "Sending: " + req.uri()); body = client.send(req, BodyHandlers.ofString()).body(); } catch (Exception x) { failed = x; } - out.println(uriStr + ": got result or exception"); + requestLatch.countDown(); + out.println(now() + req.uri() + ": got result or exception"); if (failed instanceof InterruptedException) { - out.println(uriStr + ": Got expected exception: " + failed); + out.println(now() + req.uri() + ": Got expected exception: " + failed); } else if (failed instanceof IOException) { - out.println(uriStr + ": got IOException: " + failed); + out.println(now() + req.uri() + ": got IOException: " + failed); // that could be OK if the main thread was interrupted // from the main thread: the interrupted status could have // been caught by writing to the socket from the main // thread. if (interruptingThread.isDone() && interruptingThread.get() == main) { - out.println(uriStr + ": Accepting IOException: " + failed); + out.println(now() + req.uri() + ": Accepting IOException: " + failed); failed.printStackTrace(out); } else { - out.println(uriStr + ": unexpected exception: " + failed); + out.println(now() + req.uri() + ": unexpected exception: " + failed); throw failed; } } else if (failed != null) { - out.println(uriStr + ": unexpected exception: " + failed); + out.println(now() + req.uri() + ": unexpected exception: " + failed); throw failed; } else { assert failed == null; - out.println(uriStr + ": got body: " + body); + out.println(now() + req.uri() + ": got body: " + body); assertEquals(body, String.join("", BODY.split("\\|"))); } - out.println("next iteration"); + out.println(now() + "next iteration"); var error = TRACKER.check(tracker, 2000, (t) -> t.getOutstandingOperations() > 0 || t.getOutstandingSubscribers() > 0, @@ -700,7 +738,7 @@ public class CancelRequestTest implements HttpServerAdapters { } finally { if (fail != null) { if (sharedClientName != null) { - System.err.println("Shared client name is: " + sharedClientName); + System.err.println(now() + "Shared client name is: " + sharedClientName); } throw fail; } @@ -719,9 +757,9 @@ public class CancelRequestTest implements HttpServerAdapters { @Override public void handle(HttpTestExchange t) throws IOException { try { - out.println("HTTPSlowHandler received request to " + t.getRequestURI()); - System.err.println("HTTPSlowHandler received request to " + t.getRequestURI()); - + out.println(now() + "HTTPSlowHandler received request to " + t.getRequestURI()); + System.err.println(now() + "HTTPSlowHandler received request to " + t.getRequestURI()); + var requestLatch = latches.get(t.getRequestURI().getRawQuery()); boolean isThreadInterrupt = isThreadInterrupt(t); byte[] req; try (InputStream is = t.getRequestBody()) { @@ -729,7 +767,7 @@ public class CancelRequestTest implements HttpServerAdapters { } t.sendResponseHeaders(200, -1); // chunked/variable try (OutputStream os = t.getResponseBody()) { - // lets split the response in several chunks... + // let's split the response in several chunks... String msg = (req != null && req.length != 0) ? new String(req, UTF_8) : BODY; @@ -743,16 +781,29 @@ public class CancelRequestTest implements HttpServerAdapters { } catch (InterruptedException x) { // OK } - out.printf("Server wrote %d bytes%n", req.length); + out.printf(now() + "Server wrote %d bytes%n", req.length); + } + if (requestLatch != null) { + out.printf(now() + "Server awaiting latch %s for %s%n", + requestLatch, t.getRequestURI()); + try { + requestLatch.await(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + out.printf(now() + " ...latch released%n"); } } + } catch (IOException io) { + out.println(now() + "HTTPSlowHandler: IOexception is not unexpected: " + io); + throw io; } catch (Throwable e) { - out.println("HTTPSlowHandler: unexpected exception: " + e); + out.println(now() + "HTTPSlowHandler: unexpected exception: " + e); e.printStackTrace(); throw e; } finally { - out.printf("HTTPSlowHandler reply sent: %s%n", t.getRequestURI()); - System.err.printf("HTTPSlowHandler reply sent: %s%n", t.getRequestURI()); + out.printf(now() + "HTTPSlowHandler reply sent: %s%n", t.getRequestURI()); + System.err.printf(now() + "HTTPSlowHandler reply sent: %s%n", t.getRequestURI()); } } } diff --git a/test/jdk/java/net/httpclient/StreamingBody.java b/test/jdk/java/net/httpclient/StreamingBody.java index c2ad19cf7b7..3fb4f29208e 100644 --- a/test/jdk/java/net/httpclient/StreamingBody.java +++ b/test/jdk/java/net/httpclient/StreamingBody.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,11 +25,12 @@ * @test * @summary Exercise a streaming subscriber ( InputStream ) without holding a * strong (or any ) reference to the client. + * @key randomness * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.httpclient.test.lib.common.HttpServerAdapters jdk.test.lib.net.SimpleSSLContext - * @run testng/othervm + * @run junit/othervm * -Djdk.httpclient.HttpClient.log=trace,headers,requests - * StreamingBody + * ${test.main.class} */ import java.io.IOException; @@ -40,13 +41,15 @@ import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandlers; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicReference; import javax.net.ssl.SSLContext; import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.test.lib.RandomFactory; import jdk.test.lib.net.SimpleSSLContext; -import org.testng.annotations.AfterTest; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import static java.lang.System.out; import static java.net.http.HttpClient.Version.HTTP_1_1; import static java.net.http.HttpClient.Version.HTTP_2; @@ -55,8 +58,21 @@ import static java.net.http.HttpOption.Http3DiscoveryMode.HTTP_3_URI_ONLY; import static java.net.http.HttpOption.H3_DISCOVERY; import static java.nio.charset.StandardCharsets.UTF_8; import static java.net.http.HttpClient.Builder.NO_PROXY; -import static org.testng.Assert.assertEquals; +import org.junit.jupiter.api.AfterAll; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.extension.BeforeEachCallback; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.api.extension.TestWatcher; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class StreamingBody implements HttpServerAdapters { private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); @@ -71,10 +87,105 @@ public class StreamingBody implements HttpServerAdapters { String https2URI; String http3URI; + static final AtomicLong clientCount = new AtomicLong(); + static final AtomicLong serverCount = new AtomicLong(); + static final ConcurrentMap FAILURES = new ConcurrentHashMap<>(); + private static boolean stopAfterFirstFailure() { + return true; + } + + static final long start = System.nanoTime(); + public static String now() { + long now = System.nanoTime() - start; + long secs = now / 1000_000_000; + long mill = (now % 1000_000_000) / 1000_000; + long nan = now % 1000_000; + return String.format("[%d s, %d ms, %d ns] ", secs, mill, nan); + } + + final static class TestStopper implements TestWatcher, BeforeEachCallback { + final AtomicReference failed = new AtomicReference<>(); + TestStopper() { } + @Override + public void testFailed(ExtensionContext context, Throwable cause) { + if (stopAfterFirstFailure()) { + String msg = "Aborting due to: " + cause; + failed.compareAndSet(null, msg); + FAILURES.putIfAbsent(context.getDisplayName(), cause); + System.out.printf("%nTEST FAILED: %s%s%n\tAborting due to %s%n%n", + now(), context.getDisplayName(), cause); + System.err.printf("%nTEST FAILED: %s%s%n\tAborting due to %s%n%n", + now(), context.getDisplayName(), cause); + } + } + + @Override + public void beforeEach(ExtensionContext context) { + String msg = failed.get(); + Assumptions.assumeTrue(msg == null, msg); + } + } + + @RegisterExtension + static final TestStopper stopper = new TestStopper(); + + /// The GCTrigger triggers GC at random intervals to + /// help garbage collecting HttpClient intances. This test + /// wants to verify that HttpClient instances which are no + /// longer strongly referenced are not garbage collected + /// before pending HTTP requests are finished. The test + /// creates many client instances (up to 500) and relies + /// on the GC to collect them, since it does not want to + /// keep a strong reference, and therefore cannot not call + /// close(). This can put extra load on the machine since + /// we can't (and don't want to) control when the GC will + /// intervene. The purpose of this class is to trigger the + /// GC at random intervals to 1. help garbage collect client + /// instances earlier, thus reducing the load on the machine, + /// and 2. potentially trigger bugs if the client gets + /// inadvertently GC'ed before the request is finished + /// (which is the bug we're testing for here). + static class GCTrigger { + private final long gcinterval; + private final Thread runner; + private volatile boolean stop; + private final static Random RANDOM = RandomFactory.getRandom(); + + GCTrigger(long gcinterval) { + this.gcinterval = Math.clamp(gcinterval, 100, Long.MAX_VALUE/2); + runner = Thread.ofPlatform().daemon().unstarted(this::loop); + } + + private void loop() { + long min = gcinterval / 2; + long max = gcinterval + min; + while (!stop) { + try { + Thread.sleep(RANDOM.nextLong(min, max)); + } catch (InterruptedException x) { + stop = true; + break; + } + out.println(now() + "triggering gc"); + System.gc(); + } + } + + public void start() { + runner.start(); + } + + public void stop() throws InterruptedException { + stop = true; + runner.interrupt(); + runner.join(); + } + } + + static GCTrigger gcTrigger; static final String MESSAGE = "StreamingBody message body"; static final int ITERATIONS = 100; - @DataProvider(name = "positive") public Object[][] positive() { return new Object[][] { { http3URI, }, @@ -94,72 +205,118 @@ public class StreamingBody implements HttpServerAdapters { return builder; } - @Test(dataProvider = "positive") + @ParameterizedTest + @MethodSource("positive") void test(String uriString) throws Exception { - out.printf("%n---- starting (%s) ----%n", uriString); + out.printf("%n%s---- starting (%s) ----%n", now(), uriString); URI uri = URI.create(uriString); HttpRequest request = newRequestBuilder(uri).build(); for (int i=0; i< ITERATIONS; i++) { - out.println("iteration: " + i); - var builder = uriString.contains("/http3/") - ? newClientBuilderForH3() - : HttpClient.newBuilder(); - HttpResponse response = builder - .sslContext(sslContext) - .proxy(NO_PROXY) - .build() - .sendAsync(request, BodyHandlers.ofInputStream()) - .join(); + try { + out.println(now() + "iteration: " + i); + var builder = uriString.contains("/http3/") + ? newClientBuilderForH3() + : HttpClient.newBuilder(); + clientCount.incrementAndGet(); - String body = new String(response.body().readAllBytes(), UTF_8); - out.println("Got response: " + response); - out.println("Got body Path: " + body); + // we want to relinquish the reference to the HttpClient facade + // as soon as possible. We're using `ofInputStream()` because + // the HttpResponse will be returned almost immediately, before + // the response is read. Similarly we use sendAsync() because + // this will return a CompletableFuture and not wait for the + // request to complete within a method called on the client + // facade. + HttpResponse response = builder + .sslContext(sslContext) + .proxy(NO_PROXY) + .build() + .sendAsync(request, BodyHandlers.ofInputStream()) + .join(); - assertEquals(response.statusCode(), 200); - assertEquals(body, MESSAGE); + String body = new String(response.body().readAllBytes(), UTF_8); + out.println("Got response: " + response); + out.println("Got body Path: " + body); + + assertEquals(200, response.statusCode()); + assertEquals(MESSAGE, body); + } catch (Throwable t) { + String msg = "%stest(%s)[%s] failed: %s" + .formatted(now(), uriString, i, t); + out.println(msg); + throw new AssertionError(msg, t); + } } } // -- Infrastructure - @BeforeTest + @BeforeAll public void setup() throws Exception { httpTestServer = HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler(new MessageHandler(), "/http1/streamingbody/"); httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/streamingbody/w"; + serverCount.incrementAndGet(); httpsTestServer = HttpTestServer.create(HTTP_1_1, sslContext); httpsTestServer.addHandler(new MessageHandler(),"/https1/streamingbody/"); httpsURI = "https://" + httpsTestServer.serverAuthority() + "/https1/streamingbody/x"; + serverCount.incrementAndGet(); http2TestServer = HttpTestServer.create(HTTP_2); http2TestServer.addHandler(new MessageHandler(), "/http2/streamingbody/"); http2URI = "http://" + http2TestServer.serverAuthority() + "/http2/streamingbody/y"; + serverCount.incrementAndGet(); https2TestServer = HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(new MessageHandler(), "/https2/streamingbody/"); https2URI = "https://" + https2TestServer.serverAuthority() + "/https2/streamingbody/z"; + serverCount.incrementAndGet(); http3TestServer = HttpTestServer.create(HTTP_3_URI_ONLY, sslContext); http3TestServer.addHandler(new MessageHandler(), "/http3/streamingbody/"); http3URI = "https://" + http3TestServer.serverAuthority() + "/http3/streamingbody/z"; + serverCount.incrementAndGet(); + + gcTrigger = new GCTrigger(500); httpTestServer.start(); httpsTestServer.start(); http2TestServer.start(); https2TestServer.start(); http3TestServer.start(); + gcTrigger.start(); } - @AfterTest + @AfterAll public void teardown() throws Exception { - httpTestServer.stop(); - httpsTestServer.stop(); - http2TestServer.stop(); - https2TestServer.stop(); - http3TestServer.stop(); + try { + httpTestServer.stop(); + httpsTestServer.stop(); + http2TestServer.stop(); + https2TestServer.stop(); + http3TestServer.stop(); + gcTrigger.stop(); + } finally { + printFailedTests(); + } + } + + static final void printFailedTests() { + out.println("\n========================="); + try { + out.printf("%n%sCreated %s servers and %s clients%n", + now(), serverCount.get(), clientCount.get()); + if (FAILURES.isEmpty()) return; + out.println("Failed tests: "); + FAILURES.entrySet().forEach((e) -> { + out.printf("\t%s: %s%n", e.getKey(), e.getValue()); + e.getValue().printStackTrace(out); + }); + } finally { + out.println("\n=========================\n"); + } } static class MessageHandler implements HttpTestHandler { diff --git a/test/jdk/java/net/httpclient/http3/H3IdleExceedsQuicIdleTimeout.java b/test/jdk/java/net/httpclient/http3/H3IdleExceedsQuicIdleTimeout.java index 1028eefe828..8f39ea7b850 100644 --- a/test/jdk/java/net/httpclient/http3/H3IdleExceedsQuicIdleTimeout.java +++ b/test/jdk/java/net/httpclient/http3/H3IdleExceedsQuicIdleTimeout.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 @@ import java.util.concurrent.TimeUnit; import javax.net.ssl.SSLContext; +import jdk.httpclient.test.lib.common.HttpServerAdapters; import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestExchange; import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestHandler; import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestServer; @@ -63,6 +64,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; * systems * @run junit/othervm/timeout=180 -Djdk.httpclient.quic.idleTimeout=30 * -Djdk.httpclient.keepalive.timeout.h3=120 + * -Djdk.httpclient.HttpClient.log=quic:hs * ${test.main.class} */ class H3IdleExceedsQuicIdleTimeout { @@ -106,7 +108,7 @@ class H3IdleExceedsQuicIdleTimeout { assertEquals(120, Integer.parseInt(System.getProperty("jdk.httpclient.keepalive.timeout.h3")), "unexpected HTTP/3 idle timeout"); - try (final HttpClient client = HttpClient.newBuilder() + try (final HttpClient client = HttpServerAdapters.createClientBuilderForH3() .sslContext(sslCtx) .proxy(NO_PROXY) .version(HTTP_3) diff --git a/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http3/Http3ServerExchange.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http3/Http3ServerExchange.java index c127abf3c0f..1c61f00d164 100644 --- a/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http3/Http3ServerExchange.java +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http3/Http3ServerExchange.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -175,7 +175,7 @@ public final class Http3ServerExchange implements Http2TestExchange { } serverStream.writer.reset(Http3Error.H3_INTERNAL_ERROR.code()); } - is.close(io); + is.resetStream(io); os.closeInternal(); close(); } diff --git a/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http3/Http3ServerStreamImpl.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http3/Http3ServerStreamImpl.java index c5a8709346c..ebe92fa3bac 100644 --- a/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http3/Http3ServerStreamImpl.java +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http3/Http3ServerStreamImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,7 @@ import java.util.Objects; import java.util.concurrent.BlockingQueue; import java.util.concurrent.CompletableFuture; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; @@ -264,7 +265,7 @@ final class Http3ServerStreamImpl { // nothing to do - let the response be sent to the client, but throw an // exception if `is` is used again. exchangeCF.thenApply(en -> { - en.is.close(new IOException("stopSendingRequested")); + en.is.resetStream(new IOException("stopSendingRequested")); return en; }); return; @@ -292,38 +293,37 @@ final class Http3ServerStreamImpl { } class RequestBodyInputStream extends InputStream { - volatile IOException error; - volatile boolean closed; + // Non-null if the stream is terminated. + // Points to an IOException on error, or Boolean.TRUE on EOF. + private final AtomicReference closeReason = new AtomicReference<>(); // uses an unbounded blocking queue in which the readrLoop // publishes the DataFrames payload... ByteBuffer current; - // Use lock to avoid pinned threads on the blocking queue - final ReentrantLock lock = new ReentrantLock(); ByteBuffer current() throws IOException { - lock.lock(); - try { - while (true) { - if (current != null && current.hasRemaining()) { - return current; - } - if (current == QuicStreamReader.EOF) return current; - try { - if (debug.on()) - debug.log("Taking buffer from queue"); - // Blocking call - current = requestBodyQueue.take(); - } catch (InterruptedException e) { - var io = new InterruptedIOException(); - Thread.currentThread().interrupt(); - io.initCause(e); - close(io); - var error = this.error; - if (error != null) throw error; + while (true) { + Object reason = closeReason.get(); + if (reason != null) { + if (reason == Boolean.TRUE) { + throw new IOException("Stream is closed"); + } else { + throw new IOException((IOException)reason); } } - } finally { - lock.unlock(); + if (current != null && (current.hasRemaining() || current == QuicStreamReader.EOF)) { + return current; + } + try { + if (debug.on()) + debug.log("Taking buffer from queue"); + // Blocking call + current = requestBodyQueue.take(); + } catch (InterruptedException e) { + var io = new InterruptedIOException(); + Thread.currentThread().interrupt(); + io.initCause(e); + throw io; + } } } @@ -331,9 +331,7 @@ final class Http3ServerStreamImpl { public int read() throws IOException { ByteBuffer buffer = current(); if (buffer == QuicStreamReader.EOF) { - var error = this.error; - if (error == null) return -1; - throw error; + return -1; } return buffer.get() & 0xFF; } @@ -345,11 +343,7 @@ final class Http3ServerStreamImpl { while (remaining > 0) { ByteBuffer buffer = current(); if (buffer == QuicStreamReader.EOF) { - if (len == remaining) { - var error = this.error; - if (error == null) return -1; - throw error; - } else return len - remaining; + return len == remaining ? -1 : len - remaining; } int count = Math.min(buffer.remaining(), remaining); buffer.get(b, off + (len - remaining), count); @@ -360,33 +354,20 @@ final class Http3ServerStreamImpl { @Override public void close() throws IOException { - lock.lock(); - try { - if (closed) return; - closed = true; - - } finally { - lock.unlock(); - } + if (closeReason.getAndSet(Boolean.TRUE) == Boolean.TRUE) return; if (debug.on()) debug.log("Closing request body input stream"); requestBodyQueue.add(QuicStreamReader.EOF); + stream.requestStopSending(Http3Error.H3_NO_ERROR.code()); } - void close(IOException io) { - lock.lock(); - try { - if (closed) return; - closed = true; - error = io; - } finally { - lock.unlock(); - } + void resetStream(IOException io) { + if (!closeReason.compareAndSet(null, io)) return; if (debug.on()) { debug.log("Closing request body input stream: " + io); } - requestBodyQueue.clear(); requestBodyQueue.add(QuicStreamReader.EOF); + stream.requestStopSending(Http3Error.H3_NO_ERROR.code()); } } diff --git a/test/jdk/java/net/vthread/BlockingSocketOps.java b/test/jdk/java/net/vthread/BlockingSocketOps.java index ef58e06b915..d3db734f36a 100644 --- a/test/jdk/java/net/vthread/BlockingSocketOps.java +++ b/test/jdk/java/net/vthread/BlockingSocketOps.java @@ -35,6 +35,7 @@ * @library /test/lib * @run junit/othervm -Djdk.pollerMode=1 BlockingSocketOps * @run junit/othervm -Djdk.pollerMode=2 BlockingSocketOps + * @run junit/othervm -Djdk.pollerMode=3 BlockingSocketOps */ /* diff --git a/test/jdk/java/nio/channels/Selector/ConnectionRefusedMessage.java b/test/jdk/java/nio/channels/Selector/ConnectionRefusedMessage.java new file mode 100644 index 00000000000..04490f63efe --- /dev/null +++ b/test/jdk/java/nio/channels/Selector/ConnectionRefusedMessage.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.IOException; +import java.net.ConnectException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.SocketChannel; +import java.time.Duration; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assumptions.assumeFalse; +import static org.junit.jupiter.api.Assumptions.assumeTrue; + +/* + * @test + * @bug 8376290 + * @summary Verify that when a SocketChannel is registered with a Selector + * with an interest in CONNECT operation, then SocketChannel.finishConnect() + * throws the correct exception message, if the connect() fails + * @run junit ${test.main.class} + */ +class ConnectionRefusedMessage { + + /* + * On a non-blocking SocketChannel, registered with a Selector, this test method + * attempts a SocketChannel.connect() against an address that is expected to return + * Connection refused. The test then calls SocketChannel.finishConnect() when the + * Selector makes available the ready key for this connect operation and expects + * that finishConnect() throws a ConnectException with the expected exception message. + */ + @Test + void testFinishConnect() throws Exception { + // find a suitable address against which the connect() attempt + // will result in a Connection refused exception + final InetSocketAddress destAddr = findSuitableRefusedAddress(); + // skip the test if we couldn't find a port which would raise a connection refused error + assumeTrue(destAddr != null, + "couldn't find a suitable port which will generate a connection refused error"); + try (Selector selector = Selector.open(); + SocketChannel sc = SocketChannel.open()) { + + // non-blocking + sc.configureBlocking(false); + sc.register(selector, SelectionKey.OP_CONNECT); + + System.err.println("establishing connection to " + destAddr); + boolean connected; + try { + connected = sc.connect(destAddr); + } catch (ConnectException ce) { + // Connect failed immediately, which is OK. + System.err.println("SocketChannel.connect() threw ConnectException - " + ce); + assertExceptionMessage(ce); + return; // nothing more to test + } + // this test checks the exception message of a ConnectException, so it's + // OK to skip the test if something unexpectedly accepted the connection + assumeFalse(connected, "unexpectedly connected to " + destAddr); + // wait for ready ops + int numReady = selector.select(Duration.ofMinutes(10).toMillis()); + System.err.println("Num ready keys = " + numReady); + for (SelectionKey readyKey : selector.selectedKeys()) { + System.err.println("ready key: " + readyKey); + assertTrue(readyKey.isConnectable(), "unexpected key, readyOps = " + + readyKey.readyOps()); + readyKey.cancel(); + try { + boolean success = sc.finishConnect(); + // this test checks the exception message of a ConnectException, so it's + // OK to skip the test if something unexpectedly accepted the connection + assumeFalse(success, "unexpectedly connected to " + destAddr); + // this test doesn't expect finishConnect() to return normally + // with a return value of false + fail("ConnectException was not thrown"); + } catch (ConnectException ce) { + System.err.println("got (expected) ConnectException from " + + "SocketChannel.finishConnect() - " + ce); + // verify exception message + assertExceptionMessage(ce); + } + } + } + } + + private static void assertExceptionMessage(final ConnectException ce) { + if (!"Connection refused".equals(ce.getMessage())) { + // propagate the original exception + fail("unexpected exception message: " + ce.getMessage(), ce); + } + } + + // Try to find a suitable port to provoke a "Connection Refused" error. + private static InetSocketAddress findSuitableRefusedAddress() throws IOException { + final InetAddress loopbackAddr = InetAddress.getLoopbackAddress(); + // Ports 47, 51, 61 are in the IANA reserved port list, and + // are currently unassigned to any specific service. + // We use them here on the assumption that there won't be + // any service listening on them. + InetSocketAddress destAddr = new InetSocketAddress(loopbackAddr, 47); + try (SocketChannel sc1 = SocketChannel.open(destAddr)) { + // we managed to connect (unexpectedly), let's try the next reserved port + destAddr = new InetSocketAddress(loopbackAddr, 51); + try (SocketChannel sc2 = SocketChannel.open(destAddr)) { + } + // we managed to connect (unexpectedly again), let's try the next reserved port + // as a last attempt + destAddr = new InetSocketAddress(loopbackAddr, 61); + try (SocketChannel sc3 = SocketChannel.open(destAddr)) { + } + return null; + } catch (ConnectException x) { + } + // the address which will generate a connection refused, when a connection is attempted + return destAddr; + } +} diff --git a/test/jdk/java/nio/channels/vthread/BlockingChannelOps.java b/test/jdk/java/nio/channels/vthread/BlockingChannelOps.java index eb2229d927a..7e934301892 100644 --- a/test/jdk/java/nio/channels/vthread/BlockingChannelOps.java +++ b/test/jdk/java/nio/channels/vthread/BlockingChannelOps.java @@ -35,6 +35,7 @@ * @library /test/lib * @run junit/othervm/timeout=480 -Djdk.pollerMode=1 BlockingChannelOps * @run junit/othervm/timeout=480 -Djdk.pollerMode=2 BlockingChannelOps + * @run junit/othervm/timeout=480 -Djdk.pollerMode=3 BlockingChannelOps */ /* diff --git a/test/jdk/java/nio/channels/vthread/SelectorOps.java b/test/jdk/java/nio/channels/vthread/SelectorOps.java index 81821a85791..11fe98a3a01 100644 --- a/test/jdk/java/nio/channels/vthread/SelectorOps.java +++ b/test/jdk/java/nio/channels/vthread/SelectorOps.java @@ -34,6 +34,7 @@ * @library /test/lib * @run junit/othervm/native -Djdk.pollerMode=1 --enable-native-access=ALL-UNNAMED SelectorOps * @run junit/othervm/native -Djdk.pollerMode=2 --enable-native-access=ALL-UNNAMED SelectorOps + * @run junit/othervm/native -Djdk.pollerMode=3 --enable-native-access=ALL-UNNAMED SelectorOps */ /* diff --git a/test/jdk/java/nio/file/DirectoryStream/SecureDS.java b/test/jdk/java/nio/file/DirectoryStream/SecureDS.java index 21204ba980a..870a84a8927 100644 --- a/test/jdk/java/nio/file/DirectoryStream/SecureDS.java +++ b/test/jdk/java/nio/file/DirectoryStream/SecureDS.java @@ -27,7 +27,7 @@ * @requires (os.family == "linux" | os.family == "mac" | os.family == "aix") * @library .. /test/lib * @build jdk.test.lib.Platform - * @run main SecureDS + * @run junit SecureDS */ import java.nio.file.*; @@ -35,23 +35,34 @@ import static java.nio.file.Files.*; import static java.nio.file.StandardOpenOption.*; import static java.nio.file.LinkOption.*; import java.nio.file.attribute.*; -import java.nio.channels.*; import java.io.IOException; import java.util.*; import jdk.test.lib.Platform; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assumptions.assumeTrue; public class SecureDS { static boolean supportsSymbolicLinks; - public static void main(String[] args) throws IOException { - Path dir = TestUtil.createTemporaryDirectory(); + @ParameterizedTest + @ValueSource(strings = {"tmp","cwd"}) + public void testSecureDS(String mode) throws IOException { + Path dir; + if (mode.equals("cwd")) { + dir = TestUtil.createTemporaryDirectory(System.getProperty("user.dir")); + } else { + dir = TestUtil.createTemporaryDirectory(); + } try { DirectoryStream stream = newDirectoryStream(dir); stream.close(); - if (!(stream instanceof SecureDirectoryStream)) { - throw new AssertionError("SecureDirectoryStream not supported."); - } + assumeTrue(stream instanceof SecureDirectoryStream); supportsSymbolicLinks = TestUtil.supportsSymbolicLinks(dir); @@ -94,7 +105,7 @@ public class SecureDS { // Test: iterate over all entries int count = 0; for (Path entry: stream) { count++; } - assertTrue(count == (supportsSymbolicLinks ? 4 : 2)); + assertEquals((supportsSymbolicLinks ? 4 : 2), count); // Test: getFileAttributeView to access directory's attributes assertTrue(stream @@ -143,13 +154,12 @@ public class SecureDS { stream.newByteChannel(fileEntry, opts).close(); if (supportsSymbolicLinks) { stream.newByteChannel(link1Entry, opts).close(); - try { + assertThrows(IOException.class, () -> { Set mixed = new HashSet<>(); mixed.add(READ); mixed.add(NOFOLLOW_LINKS); stream.newByteChannel(link1Entry, mixed).close(); - shouldNotGetHere(); - } catch (IOException x) { } + }); } // Test: newDirectoryStream @@ -157,11 +167,10 @@ public class SecureDS { stream.newDirectoryStream(dirEntry, LinkOption.NOFOLLOW_LINKS).close(); if (supportsSymbolicLinks) { stream.newDirectoryStream(link2Entry).close(); - try { + assertThrows(IOException.class, () -> { stream.newDirectoryStream(link2Entry, LinkOption.NOFOLLOW_LINKS) .close(); - shouldNotGetHere(); - } catch (IOException x) { } + }); } // Test: delete @@ -189,10 +198,10 @@ public class SecureDS { // Test setting permission on directory with no permissions setPosixFilePermissions(aDir, noperms); - assertTrue(getPosixFilePermissions(aDir).equals(noperms)); + assertEquals(noperms, getPosixFilePermissions(aDir)); PosixFileAttributeView view = stream.getFileAttributeView(PosixFileAttributeView.class); view.setPermissions(permsDir); - assertTrue(getPosixFilePermissions(aDir).equals(permsDir)); + assertEquals(permsDir, getPosixFilePermissions(aDir)); if (supportsSymbolicLinks) { // Create a file and a link to the file @@ -206,22 +215,21 @@ public class SecureDS { // Test following link to file view = stream.getFileAttributeView(link, PosixFileAttributeView.class); view.setPermissions(noperms); - assertTrue(getPosixFilePermissions(file).equals(noperms)); - assertTrue(getPosixFilePermissions(link, NOFOLLOW_LINKS).equals(permsLink)); + assertEquals(noperms, getPosixFilePermissions(file)); + assertEquals(permsLink, getPosixFilePermissions(link, NOFOLLOW_LINKS)); view.setPermissions(permsFile); - assertTrue(getPosixFilePermissions(file).equals(permsFile)); - assertTrue(getPosixFilePermissions(link, NOFOLLOW_LINKS).equals(permsLink)); - + assertEquals(permsFile, getPosixFilePermissions(file)); + assertEquals(permsLink, getPosixFilePermissions(link, NOFOLLOW_LINKS)); // Symbolic link permissions do not apply on Linux if (!Platform.isLinux()) { // Test not following link to file view = stream.getFileAttributeView(link, PosixFileAttributeView.class, NOFOLLOW_LINKS); view.setPermissions(noperms); - assertTrue(getPosixFilePermissions(file).equals(permsFile)); - assertTrue(getPosixFilePermissions(link, NOFOLLOW_LINKS).equals(noperms)); + assertEquals(permsFile, getPosixFilePermissions(file)); + assertEquals(noperms, getPosixFilePermissions(link, NOFOLLOW_LINKS)); view.setPermissions(permsLink); - assertTrue(getPosixFilePermissions(file).equals(permsFile)); - assertTrue(getPosixFilePermissions(link, NOFOLLOW_LINKS).equals(permsLink)); + assertEquals(permsFile, getPosixFilePermissions(file)); + assertEquals(permsLink, getPosixFilePermissions(link, NOFOLLOW_LINKS)); } delete(link); @@ -283,10 +291,9 @@ public class SecureDS { SecureDirectoryStream ts = (SecureDirectoryStream)newDirectoryStream(testDir); createFile(dir1.resolve(fileEntry)); - try { + assertThrows(AtomicMoveNotSupportedException.class, () -> { stream1.move(fileEntry, ts, target); - shouldNotGetHere(); - } catch (AtomicMoveNotSupportedException x) { } + }); ts.close(); stream1.deleteFile(fileEntry); } @@ -301,21 +308,25 @@ public class SecureDS { Files.writeString(filepath, TEXT); try (DirectoryStream ds = Files.newDirectoryStream(dir);) { if (ds instanceof SecureDirectoryStream sds) { - sds.move(file, null, file); - if (!TEXT.equals(Files.readString(result))) - throw new RuntimeException(result + " content incorrect"); + try { + sds.move(file, null, file); + } catch (AtomicMoveNotSupportedException e) { + assumeTrue(Files.getFileStore(cwd).equals(Files.getFileStore(dir))); + // re-throw if move between same volume + throw e; + } + assertEquals(TEXT, Files.readString(result), result + " content incorrect"); } else { - throw new RuntimeException("Not a SecureDirectoryStream"); + fail("Not a SecureDirectoryStream"); } } finally { boolean fileDeleted = Files.deleteIfExists(filepath); if (!fileDeleted) Files.deleteIfExists(result); + // clean-up + delete(dir1); + delete(dir2); } - - // clean-up - delete(dir1); - delete(dir2); } // null and ClosedDirectoryStreamException @@ -327,82 +338,59 @@ public class SecureDS { (SecureDirectoryStream)newDirectoryStream(dir); // NullPointerException - try { + assertThrows(NullPointerException.class, () -> { stream.getFileAttributeView(null); - shouldNotGetHere(); - } catch (NullPointerException x) { } - try { + }); + assertThrows(NullPointerException.class, () -> { stream.getFileAttributeView(null, BasicFileAttributeView.class); - shouldNotGetHere(); - } catch (NullPointerException x) { } - try { + }); + assertThrows(NullPointerException.class, () -> { stream.getFileAttributeView(file, null); - shouldNotGetHere(); - } catch (NullPointerException x) { } - try { + }); + assertThrows(NullPointerException.class, () -> { stream.newByteChannel(null, EnumSet.of(CREATE,WRITE)); - shouldNotGetHere(); - } catch (NullPointerException x) { } - try { + }); + assertThrows(NullPointerException.class, () -> { stream.newByteChannel(null, EnumSet.of(CREATE,WRITE,null)); - shouldNotGetHere(); - } catch (NullPointerException x) { } - try { + }); + assertThrows(NullPointerException.class, () -> { stream.newByteChannel(file, null); - shouldNotGetHere(); - } catch (NullPointerException x) { } - try { + }); + assertThrows(NullPointerException.class, () -> { stream.move(null, stream, file); - shouldNotGetHere(); - } catch (NullPointerException x) { } - try { + }); + assertThrows(NullPointerException.class, () -> { stream.move(file, stream, null); - shouldNotGetHere(); - } catch (NullPointerException x) { } - try { + }); + assertThrows(NullPointerException.class, () -> { stream.newDirectoryStream(null); - shouldNotGetHere(); - } catch (NullPointerException x) { } - try { + }); + assertThrows(NullPointerException.class, () -> { stream.deleteFile(null); - shouldNotGetHere(); - } catch (NullPointerException x) { } - try { + }); + assertThrows(NullPointerException.class, () -> { stream.deleteDirectory(null); - shouldNotGetHere(); - } catch (NullPointerException x) { } + }); // close stream stream.close(); stream.close(); // should be no-op // ClosedDirectoryStreamException - try { + assertThrows(ClosedDirectoryStreamException.class, () -> { stream.newDirectoryStream(file); - shouldNotGetHere(); - } catch (ClosedDirectoryStreamException x) { } - try { + }); + assertThrows(ClosedDirectoryStreamException.class, () -> { stream.newByteChannel(file, EnumSet.of(READ)); - shouldNotGetHere(); - } catch (ClosedDirectoryStreamException x) { } - try { + }); + assertThrows(ClosedDirectoryStreamException.class, () -> { stream.move(file, stream, file); - shouldNotGetHere(); - } catch (ClosedDirectoryStreamException x) { } - try { + }); + assertThrows(ClosedDirectoryStreamException.class, () -> { stream.deleteFile(file); - shouldNotGetHere(); - } catch (ClosedDirectoryStreamException x) { } + }); // clean-up delete(dir.resolve(file)); } - - static void assertTrue(boolean b) { - if (!b) throw new RuntimeException("Assertion failed"); - } - - static void shouldNotGetHere() { - assertTrue(false); - } } diff --git a/test/jdk/java/nio/file/attribute/UserDefinedFileAttributeView/Basic.java b/test/jdk/java/nio/file/attribute/UserDefinedFileAttributeView/Basic.java index 4586c33521f..b729438812f 100644 --- a/test/jdk/java/nio/file/attribute/UserDefinedFileAttributeView/Basic.java +++ b/test/jdk/java/nio/file/attribute/UserDefinedFileAttributeView/Basic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2026, Oracle and/or its affiliates. All rights reserved. * 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,12 @@ /* @test * @bug 4313887 6838333 8273922 * @summary Unit test for java.nio.file.attribute.UserDefinedFileAttributeView + * (use -Dseed=X to set PRNG seed) * @library ../.. /test/lib * @key randomness * @build jdk.test.lib.Platform + * @build jdk.test.lib.RandomFactory + * @build jtreg.SkippedException * @run main Basic */ @@ -38,17 +41,20 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.LinkOption; import java.nio.file.Path; -import static java.nio.file.LinkOption.*; -import java.nio.file.attribute.*; +import java.nio.file.attribute.UserDefinedFileAttributeView; import java.util.Arrays; import java.util.Map; import java.util.Random; + import jdk.test.lib.Platform; +import jdk.test.lib.RandomFactory; + +import jtreg.SkippedException; public class Basic { // Must be indeterministic - private static final Random rand = new Random(); + private static final Random rand = RandomFactory.getRandom(); private static final String ATTR_NAME = "mime_type"; private static final String ATTR_VALUE = "text/plain"; @@ -281,10 +287,8 @@ public class Basic { // create temporary directory to run tests Path dir = TestUtil.createTemporaryDirectory(); try { - if (!Files.getFileStore(dir).supportsFileAttributeView("user")) { - System.out.println("UserDefinedFileAttributeView not supported - skip test"); - return; - } + if (!Files.getFileStore(dir).supportsFileAttributeView("user")) + throw new SkippedException("UserDefinedFileAttributeView not supported"); // test access to user defined attributes of regular file Path file = dir.resolve("foo.html"); @@ -310,7 +314,7 @@ public class Basic { Path link = dir.resolve("link"); Files.createSymbolicLink(link, target); try { - test(link, NOFOLLOW_LINKS); + test(link, LinkOption.NOFOLLOW_LINKS); } catch (IOException x) { // access to attributes of sym link may not be supported } finally { diff --git a/test/jdk/java/rmi/server/Unreferenced/leaseCheckInterval/LeaseCheckInterval.java b/test/jdk/java/rmi/server/Unreferenced/leaseCheckInterval/LeaseCheckInterval.java index 3fa349fd671..e7c990ebdbd 100644 --- a/test/jdk/java/rmi/server/Unreferenced/leaseCheckInterval/LeaseCheckInterval.java +++ b/test/jdk/java/rmi/server/Unreferenced/leaseCheckInterval/LeaseCheckInterval.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,10 +31,9 @@ * may be delayed longer than expected. While this is not a spec violation * (because there are no timeliness guarantees for any of these garbage * collection-related events), the user might expect that an unreferenced() - * invocation for an object whose last client has terminated abnorally + * invocation for an object whose last client has terminated abnormally * should occur on relatively the same time order as the lease value * granted. - * @author Peter Jones * * @library ../../../testlibrary * @modules java.rmi/sun.rmi.registry @@ -47,40 +46,39 @@ import java.rmi.Remote; import java.rmi.RemoteException; -import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.rmi.server.UnicastRemoteObject; import java.rmi.server.Unreferenced; +import java.time.Duration; +import java.time.Instant; +import java.util.concurrent.CountDownLatch; public class LeaseCheckInterval implements Remote, Unreferenced { public static final String BINDING = "LeaseCheckInterval"; + // lease expiry time (milliseconds) private static final long LEASE_VALUE = 10000; - private static final long TIMEOUT = 20000; + // the maximum allowed duration between the lease expiration and + // the Unreferenced.unreferenced() callback method to be invoked + private static final Duration EXPECTED_MAX_DURATION = Duration.ofMinutes(1); - private Object lock = new Object(); - private boolean unreferencedInvoked = false; + // will be counted down when Unreferenced.unreferenced() is invoked + private static final CountDownLatch callbackInvocationLatch = new CountDownLatch(1); + @Override public void unreferenced() { - System.err.println("unreferenced() method invoked"); - synchronized (lock) { - unreferencedInvoked = true; - lock.notify(); - } + System.err.println("[" + Instant.now() + "] unreferenced() method invoked"); + callbackInvocationLatch.countDown(); } public static void main(String[] args) throws Exception { - - System.err.println("\nRegression test for bug 4285878\n"); - /* * Set the duration of leases granted to a very small value, so that * we can test if expirations are detected in a roughly comparable * time. */ - System.setProperty("java.rmi.dgc.leaseValue", - String.valueOf(LEASE_VALUE)); - + System.setProperty("java.rmi.dgc.leaseValue", String.valueOf(LEASE_VALUE)); + System.err.println("running test with java.rmi.dgc.leaseValue set to " + LEASE_VALUE); LeaseCheckInterval obj = new LeaseCheckInterval(); JavaVM jvm = null; @@ -90,37 +88,32 @@ public class LeaseCheckInterval implements Remote, Unreferenced { Registry localRegistry = TestLibrary.createRegistryOnEphemeralPort(); int registryPort = TestLibrary.getRegistryPort(localRegistry); - System.err.println("created local registry"); + System.err.println("created local registry on port " + registryPort); localRegistry.bind(BINDING, obj); System.err.println("bound remote object in local registry"); - synchronized (obj.lock) { - System.err.println("starting remote client VM..."); - jvm = new JavaVM("SelfTerminator", "-Drmi.registry.port=" + - registryPort, ""); - jvm.start(); - - System.err.println("waiting for unreferenced() callback..."); - obj.lock.wait(TIMEOUT); - - if (obj.unreferencedInvoked) { - System.err.println("TEST PASSED: " + - "unreferenced() invoked in timely fashion"); - } else { - throw new RuntimeException( - "TEST FAILED: unreferenced() not invoked after " + - ((double) TIMEOUT / 1000.0) + " seconds"); - } - } - - } catch (Exception e) { - if (e instanceof RuntimeException) { - throw (RuntimeException) e; - } else { - throw new RuntimeException( - "TEST FAILED: unexpected exception: " + e.toString()); + System.err.println("starting remote client VM..."); + jvm = new JavaVM("SelfTerminator", "-Drmi.registry.port=" + registryPort, ""); + // launch the self terminating java application which will lookup + // the bound object (thus creating a lease) and then terminate itself (thus + // creating the condition for a lease expiry). + jvm.start(); + final Instant startTime = Instant.now(); + System.err.println("waiting for SelfTerminator process to complete"); + final int exitCode = jvm.waitFor(); + if (exitCode != 0) { + throw new AssertionError("SelfTerminator process exited with" + + " a non-zero exit code: " + exitCode); } + System.err.println("SelfTerminator process completed in " + + Duration.between(startTime, Instant.now()) + + ", now waiting for Unreferenced.unreferenced() callback to be invoked"); + callbackInvocationLatch.await(); + final Instant waitEndedAt = Instant.now(); + final Duration waitDuration = assertWithinExpectedTimeLimit(waitEndedAt, startTime); + System.err.println("TEST PASSED: unreferenced() invoked in timely" + + " fashion (duration=" + waitDuration + ")"); } finally { if (jvm != null) { jvm.destroy(); @@ -135,4 +128,22 @@ public class LeaseCheckInterval implements Remote, Unreferenced { } } } + + /* + * Verifies that the duration between the lease expiration and the callback + * invocation is within the expected limit. Throws an exception if the wait + * duration is larger than expected limit, else returns the actual wait duration. + */ + private static Duration assertWithinExpectedTimeLimit(final Instant waitEndedAt, + final Instant terminationStartedAt) { + + final Duration waitDuration = Duration.between(terminationStartedAt, waitEndedAt); + System.out.println("wait completed in " + waitDuration); + if (waitDuration.compareTo(EXPECTED_MAX_DURATION) > 0) { + throw new RuntimeException("Took unexpectedly long (duration=" + + waitDuration + ") to invoke Unreferenced.unreferenced()," + + " expected max duration=" + EXPECTED_MAX_DURATION); + } + return waitDuration; + } } diff --git a/test/jdk/java/rmi/server/Unreferenced/leaseCheckInterval/SelfTerminator.java b/test/jdk/java/rmi/server/Unreferenced/leaseCheckInterval/SelfTerminator.java index 4875634dbb3..36ebbf05bf1 100644 --- a/test/jdk/java/rmi/server/Unreferenced/leaseCheckInterval/SelfTerminator.java +++ b/test/jdk/java/rmi/server/Unreferenced/leaseCheckInterval/SelfTerminator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,26 +21,32 @@ * questions. */ -/* - * - */ - import java.rmi.Remote; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; +import java.time.Instant; public class SelfTerminator { - public static void main(String[] args) { + public static void main(String[] args) throws Exception { try { + log("main() invoked"); int registryPort = Integer.parseInt(System.getProperty("rmi.registry.port")); Registry registry = LocateRegistry.getRegistry("", registryPort); Remote stub = registry.lookup(LeaseCheckInterval.BINDING); + log("looked up binding, now terminating the process"); Runtime.getRuntime().halt(0); - } catch (Exception e) { - e.printStackTrace(); + } catch (Throwable t) { + log("failure: " + t); + t.printStackTrace(); + throw t; // propagate any failures and fail the process } } + + private static void log(final String message) { + final Instant now = Instant.now(); + System.err.println("[" + now + "] " + SelfTerminator.class.getName() + " - " + message); + } } diff --git a/test/jdk/java/sql/JavatimeTest.java b/test/jdk/java/sql/JavatimeTest.java deleted file mode 100644 index 89344d7cdc6..00000000000 --- a/test/jdk/java/sql/JavatimeTest.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - *@test - *@bug 8007520 - *@summary Test those bridge methods to/from java.time date/time classes - * @key randomness - */ - -import java.util.Random; -import java.sql.Date; -import java.sql.Time; -import java.sql.Timestamp; -import java.time.Instant; -import java.time.LocalDateTime; -import java.time.LocalDate; -import java.time.LocalTime; -import java.time.ZoneId; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; - -public class JavatimeTest { - - static final int NANOS_PER_SECOND = 1000000000; - - public static void main(String[] args) throws Throwable { - int N = 10000; - long t1970 = new java.util.Date(70, 0, 01).getTime(); - Random r = new Random(); - for (int i = 0; i < N; i++) { - int days = r.nextInt(50) * 365 + r.nextInt(365); - long secs = t1970 + days * 86400 + r.nextInt(86400); - int nanos = r.nextInt(NANOS_PER_SECOND); - int nanos_ms = nanos / 1000000 * 1000000; // millis precision - long millis = secs * 1000 + r.nextInt(1000); - - LocalDateTime ldt = LocalDateTime.ofEpochSecond(secs, nanos, ZoneOffset.UTC); - LocalDateTime ldt_ms = LocalDateTime.ofEpochSecond(secs, nanos_ms, ZoneOffset.UTC); - Instant inst = Instant.ofEpochSecond(secs, nanos); - Instant inst_ms = Instant.ofEpochSecond(secs, nanos_ms); - //System.out.printf("ms: %16d ns: %10d ldt:[%s]%n", millis, nanos, ldt); - - /////////// Timestamp //////////////////////////////// - Timestamp ta = new Timestamp(millis); - ta.setNanos(nanos); - if (!isEqual(ta.toLocalDateTime(), ta)) { - System.out.printf("ms: %16d ns: %10d ldt:[%s]%n", millis, nanos, ldt); - print(ta.toLocalDateTime(), ta); - throw new RuntimeException("FAILED: j.s.ts -> ldt"); - } - if (!isEqual(ldt, Timestamp.valueOf(ldt))) { - System.out.printf("ms: %16d ns: %10d ldt:[%s]%n", millis, nanos, ldt); - print(ldt, Timestamp.valueOf(ldt)); - throw new RuntimeException("FAILED: ldt -> j.s.ts"); - } - Instant inst0 = ta.toInstant(); - if (ta.getTime() != inst0.toEpochMilli() || - ta.getNanos() != inst0.getNano() || - !ta.equals(Timestamp.from(inst0))) { - System.out.printf("ms: %16d ns: %10d ldt:[%s]%n", millis, nanos, ldt); - throw new RuntimeException("FAILED: j.s.ts -> instant -> j.s.ts"); - } - inst = Instant.ofEpochSecond(secs, nanos); - Timestamp ta0 = Timestamp.from(inst); - if (ta0.getTime() != inst.toEpochMilli() || - ta0.getNanos() != inst.getNano() || - !inst.equals(ta0.toInstant())) { - System.out.printf("ms: %16d ns: %10d ldt:[%s]%n", millis, nanos, ldt); - throw new RuntimeException("FAILED: instant -> timestamp -> instant"); - } - - ////////// java.sql.Date ///////////////////////////// - // j.s.d/t uses j.u.d.equals() !!!!!!!! - java.sql.Date jsd = new java.sql.Date(millis); - if (!isEqual(jsd.toLocalDate(), jsd)) { - System.out.printf("ms: %16d ns: %10d ldt:[%s]%n", millis, nanos, ldt); - print(jsd.toLocalDate(), jsd); - throw new RuntimeException("FAILED: j.s.d -> ld"); - } - LocalDate ld = ldt.toLocalDate(); - if (!isEqual(ld, java.sql.Date.valueOf(ld))) { - System.out.printf("ms: %16d ns: %10d ldt:[%s]%n", millis, nanos, ldt); - print(ld, java.sql.Date.valueOf(ld)); - throw new RuntimeException("FAILED: ld -> j.s.d"); - } - ////////// java.sql.Time ///////////////////////////// - java.sql.Time jst = new java.sql.Time(millis); - if (!isEqual(jst.toLocalTime(), jst)) { - System.out.printf("ms: %16d ns: %10d ldt:[%s]%n", millis, nanos, ldt); - print(jst.toLocalTime(), jst); - throw new RuntimeException("FAILED: j.s.t -> lt"); - } - // millis precision - LocalTime lt = ldt_ms.toLocalTime(); - if (!isEqual(lt, java.sql.Time.valueOf(lt))) { - System.out.printf("ms: %16d ns: %10d ldt:[%s]%n", millis, nanos, ldt); - print(lt, java.sql.Time.valueOf(lt)); - throw new RuntimeException("FAILED: lt -> j.s.t"); - } - } - System.out.println("Passed!"); - } - - private static boolean isEqual(LocalDateTime ldt, Timestamp ts) { - ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.systemDefault()); - return zdt.getYear() == ts.getYear() + 1900 && - zdt.getMonthValue() == ts.getMonth() + 1 && - zdt.getDayOfMonth() == ts.getDate() && - zdt.getHour() == ts.getHours() && - zdt.getMinute() == ts.getMinutes() && - zdt.getSecond() == ts.getSeconds() && - zdt.getNano() == ts.getNanos(); - } - - private static void print(LocalDateTime ldt, Timestamp ts) { - ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.systemDefault()); - System.out.printf("ldt:ts %d/%d, %d/%d, %d/%d, %d/%d, %d/%d, %d/%d, nano:[%d/%d]%n", - zdt.getYear(), ts.getYear() + 1900, - zdt.getMonthValue(), ts.getMonth() + 1, - zdt.getDayOfMonth(), ts.getDate(), - zdt.getHour(), ts.getHours(), - zdt.getMinute(), ts.getMinutes(), - zdt.getSecond(), ts.getSeconds(), - zdt.getNano(), ts.getNanos()); - } - - private static boolean isEqual(LocalDate ld, java.sql.Date d) { - return ld.getYear() == d.getYear() + 1900 && - ld.getMonthValue() == d.getMonth() + 1 && - ld.getDayOfMonth() == d.getDate(); - } - - private static void print(LocalDate ld, java.sql.Date d) { - System.out.printf("%d/%d, %d/%d, %d/%d%n", - ld.getYear(), d.getYear() + 1900, - ld.getMonthValue(), d.getMonth() + 1, - ld.getDayOfMonth(), d.getDate()); - } - - private static boolean isEqual(LocalTime lt, java.sql.Time t) { - return lt.getHour() == t.getHours() && - lt.getMinute() == t.getMinutes() && - lt.getSecond() == t.getSeconds(); - } - - private static void print(LocalTime lt, java.sql.Time t) { - System.out.printf("%d/%d, %d/%d, %d/%d%n", - lt.getHour(), t.getHours(), - lt.getMinute(), t.getMinutes(), - lt.getSecond(), t.getSeconds()); - } -} diff --git a/test/jdk/java/sql/test/TEST.properties b/test/jdk/java/sql/test/TEST.properties new file mode 100644 index 00000000000..97c9e7bbe18 --- /dev/null +++ b/test/jdk/java/sql/test/TEST.properties @@ -0,0 +1,3 @@ +# JDBC unit tests uses JUnit +JUnit.dirs= . +lib.dirs = /java/sql/util diff --git a/test/jdk/java/sql/testng/test/sql/BatchUpdateExceptionTests.java b/test/jdk/java/sql/test/sql/BatchUpdateExceptionTests.java similarity index 98% rename from test/jdk/java/sql/testng/test/sql/BatchUpdateExceptionTests.java rename to test/jdk/java/sql/test/sql/BatchUpdateExceptionTests.java index 2b1111b7526..2d010b50e41 100644 --- a/test/jdk/java/sql/testng/test/sql/BatchUpdateExceptionTests.java +++ b/test/jdk/java/sql/test/sql/BatchUpdateExceptionTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package test.sql; +package sql; import java.io.ByteArrayInputStream; import java.io.File; @@ -28,8 +28,10 @@ import java.io.ObjectInputStream; import java.sql.BatchUpdateException; import java.sql.SQLException; import java.util.Arrays; -import static org.testng.Assert.*; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + import util.SerializedBatchUpdateException; import util.BaseTest; diff --git a/test/jdk/java/sql/testng/test/sql/CallableStatementTests.java b/test/jdk/java/sql/test/sql/CallableStatementTests.java similarity index 62% rename from test/jdk/java/sql/testng/test/sql/CallableStatementTests.java rename to test/jdk/java/sql/test/sql/CallableStatementTests.java index 7a4fe15ecac..dc5c347ef50 100644 --- a/test/jdk/java/sql/testng/test/sql/CallableStatementTests.java +++ b/test/jdk/java/sql/test/sql/CallableStatementTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,28 +20,33 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package test.sql; +package sql; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; +import org.junit.jupiter.params.provider.ValueSource; import util.BaseTest; import util.StubConnection; import java.sql.CallableStatement; import java.sql.SQLException; -import static org.testng.Assert.assertEquals; +import org.junit.jupiter.api.AfterEach; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; public class CallableStatementTests extends BaseTest { private CallableStatement cstmt; - @BeforeMethod + @BeforeEach public void setUpMethod() throws Exception { cstmt = new StubConnection().prepareCall("{call SuperHero_Proc(?)}"); } - @AfterMethod + @AfterEach public void tearDownMethod() throws Exception { cstmt.close(); } @@ -50,80 +55,84 @@ public class CallableStatementTests extends BaseTest { * Verify that enquoteLiteral creates a valid literal and converts every * single quote to two single quotes */ - @Test(dataProvider = "validEnquotedLiteralValues") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("validEnquotedLiteralValues") public void test00(String s, String expected) throws SQLException { - assertEquals(cstmt.enquoteLiteral(s), expected); + assertEquals(expected, cstmt.enquoteLiteral(s)); } /* * Validate a NullPointerException is thrown if the string passed to * enquoteLiteral is null */ - @Test(expectedExceptions = NullPointerException.class) + @Test public void test01() throws SQLException { - cstmt.enquoteLiteral(null); + assertThrows(NullPointerException.class, () -> cstmt.enquoteLiteral(null)); } /* * Validate that enquoteIdentifier returns the expected value */ - @Test(dataProvider = "validIdentifierValues") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("validEnquotedIdentifierValues") public void test02(String s, boolean alwaysQuote, String expected) throws SQLException { - assertEquals(cstmt.enquoteIdentifier(s, alwaysQuote), expected); + assertEquals(expected, cstmt.enquoteIdentifier(s, alwaysQuote)); } /* * Validate that a SQLException is thrown for values that are not valid * for a SQL identifier */ - @Test(dataProvider = "invalidIdentifierValues", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidEnquotedIdentifierValues") public void test03(String s, boolean alwaysQuote) throws SQLException { - cstmt.enquoteIdentifier(s, alwaysQuote); + assertThrows(SQLException.class, () -> cstmt.enquoteIdentifier(s, alwaysQuote)); } /* * Validate a NullPointerException is thrown is the string passed to * enquoteIdentiifer is null */ - @Test(dataProvider = "trueFalse", - expectedExceptions = NullPointerException.class) + @ParameterizedTest(autoCloseArguments = false) + @ValueSource(booleans = {true, false}) public void test04(boolean alwaysQuote) throws SQLException { - cstmt.enquoteIdentifier(null, alwaysQuote); + assertThrows(NullPointerException.class, () -> cstmt.enquoteIdentifier(null, alwaysQuote)); } /* * Validate that isSimpleIdentifier returns the expected value */ - @Test(dataProvider = "simpleIdentifierValues") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("simpleIdentifierValues") public void test05(String s, boolean expected) throws SQLException { - assertEquals(cstmt.isSimpleIdentifier(s), expected); + assertEquals(expected, cstmt.isSimpleIdentifier(s)); } /* * Validate a NullPointerException is thrown if the string passed to * isSimpleIdentifier is null */ - @Test(expectedExceptions = NullPointerException.class) + @Test public void test06() throws SQLException { - cstmt.isSimpleIdentifier(null); + assertThrows(NullPointerException.class, () -> cstmt.isSimpleIdentifier(null)); } /* * Verify that enquoteLiteral creates a valid literal and converts every * single quote to two single quotes */ - @Test(dataProvider = "validEnquotedNCharLiteralValues") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("validEnquotedNCharLiteralValues") public void test07(String s, String expected) throws SQLException { - assertEquals(cstmt.enquoteNCharLiteral(s), expected); + assertEquals(expected, cstmt.enquoteNCharLiteral(s)); } /* * Validate a NullPointerException is thrown if the string passed to * enquoteNCharLiteral is null */ - @Test(expectedExceptions = NullPointerException.class) + @Test public void test08() throws SQLException { - cstmt.enquoteNCharLiteral(null); + assertThrows(NullPointerException.class, () -> cstmt.enquoteNCharLiteral(null)); } } diff --git a/test/jdk/java/sql/testng/test/sql/ConnectionTests.java b/test/jdk/java/sql/test/sql/ConnectionTests.java similarity index 63% rename from test/jdk/java/sql/testng/test/sql/ConnectionTests.java rename to test/jdk/java/sql/test/sql/ConnectionTests.java index f40c2784e4a..534b5d7d96a 100644 --- a/test/jdk/java/sql/testng/test/sql/ConnectionTests.java +++ b/test/jdk/java/sql/test/sql/ConnectionTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,22 +20,25 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package test.sql; +package sql; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; +import org.junit.jupiter.params.provider.ValueSource; import util.BaseTest; import util.StubConnection; import java.sql.SQLException; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; public class ConnectionTests extends BaseTest { protected StubConnection conn; - @BeforeMethod + @BeforeEach public void setUpMethod() throws Exception { conn = new StubConnection(); } @@ -44,80 +47,84 @@ public class ConnectionTests extends BaseTest { * Verify that enquoteLiteral creates a valid literal and converts every * single quote to two single quotes */ - @Test(dataProvider = "validEnquotedLiteralValues") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("validEnquotedLiteralValues") public void test00(String s, String expected) throws SQLException { - assertEquals(conn.enquoteLiteral(s), expected); + assertEquals(expected, conn.enquoteLiteral(s)); } /* * Validate a NullPointerException is thrown if the string passed to * enquoteLiteral is null */ - @Test(expectedExceptions = NullPointerException.class) + @Test public void test01() throws SQLException { - conn.enquoteLiteral(null); + assertThrows(NullPointerException.class, () -> conn.enquoteLiteral(null)); } /* * Validate that enquoteIdentifier returns the expected value */ - @Test(dataProvider = "validIdentifierValues") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("validEnquotedIdentifierValues") public void test02(String s, boolean alwaysQuote, String expected) throws SQLException { - assertEquals(conn.enquoteIdentifier(s, alwaysQuote), expected); + assertEquals(expected, conn.enquoteIdentifier(s, alwaysQuote)); } /* * Validate that a SQLException is thrown for values that are not valid * for a SQL identifier */ - @Test(dataProvider = "invalidIdentifierValues", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidEnquotedIdentifierValues") public void test03(String s, boolean alwaysQuote) throws SQLException { - conn.enquoteIdentifier(s, alwaysQuote); + assertThrows(SQLException.class, () -> conn.enquoteIdentifier(s, alwaysQuote)); } /* * Validate a NullPointerException is thrown is the string passed to * enquoteIdentiifer is null */ - @Test(dataProvider = "trueFalse", - expectedExceptions = NullPointerException.class) + @ParameterizedTest(autoCloseArguments = false) + @ValueSource(booleans = {true, false}) public void test04(boolean alwaysQuote) throws SQLException { - conn.enquoteIdentifier(null, alwaysQuote); + assertThrows(NullPointerException.class, () -> conn.enquoteIdentifier(null, alwaysQuote)); } /* * Validate that isSimpleIdentifier returns the expected value */ - @Test(dataProvider = "simpleIdentifierValues") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("simpleIdentifierValues") public void test05(String s, boolean expected) throws SQLException { - assertEquals(conn.isSimpleIdentifier(s), expected); + assertEquals(expected, conn.isSimpleIdentifier(s)); } /* * Validate a NullPointerException is thrown if the string passed to * isSimpleIdentifier is null */ - @Test(expectedExceptions = NullPointerException.class) + @Test public void test06() throws SQLException { - conn.isSimpleIdentifier(null); + assertThrows(NullPointerException.class, () -> conn.isSimpleIdentifier(null)); } /* * Verify that enquoteLiteral creates a valid literal and converts every * single quote to two single quotes */ - @Test(dataProvider = "validEnquotedNCharLiteralValues") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("validEnquotedNCharLiteralValues") public void test07(String s, String expected) throws SQLException { - assertEquals(conn.enquoteNCharLiteral(s), expected); + assertEquals(expected, conn.enquoteNCharLiteral(s)); } /* * Validate a NullPointerException is thrown if the string passed to * enquoteNCharLiteral is null */ - @Test(expectedExceptions = NullPointerException.class) + @Test public void test08() throws SQLException { - conn.enquoteNCharLiteral(null); + assertThrows(NullPointerException.class, () -> conn.enquoteNCharLiteral(null)); } } diff --git a/test/jdk/java/sql/testng/test/sql/DataTruncationTests.java b/test/jdk/java/sql/test/sql/DataTruncationTests.java similarity index 97% rename from test/jdk/java/sql/testng/test/sql/DataTruncationTests.java rename to test/jdk/java/sql/test/sql/DataTruncationTests.java index fbf7eebe90a..9d221b4a037 100644 --- a/test/jdk/java/sql/testng/test/sql/DataTruncationTests.java +++ b/test/jdk/java/sql/test/sql/DataTruncationTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,12 +20,14 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package test.sql; +package sql; import java.sql.DataTruncation; import java.sql.SQLException; -import static org.testng.Assert.*; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + import util.BaseTest; public class DataTruncationTests extends BaseTest { diff --git a/test/jdk/java/sql/testng/test/sql/DateTests.java b/test/jdk/java/sql/test/sql/DateTests.java similarity index 80% rename from test/jdk/java/sql/testng/test/sql/DateTests.java rename to test/jdk/java/sql/test/sql/DateTests.java index ae6c276c4f6..0c66dd15c98 100644 --- a/test/jdk/java/sql/testng/test/sql/DateTests.java +++ b/test/jdk/java/sql/test/sql/DateTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,14 +20,18 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package test.sql; +package sql; import java.sql.Date; -import java.time.Instant; import java.time.LocalDate; -import static org.testng.Assert.*; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + import util.BaseTest; public class DateTests extends BaseTest { @@ -35,17 +39,18 @@ public class DateTests extends BaseTest { /* * Validate an IllegalArgumentException is thrown for an invalid Date string */ - @Test(dataProvider = "invalidDateValues", - expectedExceptions = IllegalArgumentException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidDateValues") public void test(String d) throws Exception { - Date.valueOf(d); + assertThrows(IllegalArgumentException.class, () -> Date.valueOf(d)); } /* * Test that a date created from a date string is equal to the value * returned from toString() */ - @Test(dataProvider = "validDateValues") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("validDateValues") public void test00(String d, String expectedD) { Date d1 = Date.valueOf(d); Date d2 = Date.valueOf(expectedD); @@ -207,20 +212,20 @@ public class DateTests extends BaseTest { /* * Validate an NPE occurs when a null LocalDate is passed to valueOf */ - @Test(expectedExceptions = NullPointerException.class) + @Test public void test15() throws Exception { LocalDate ld = null; - Date.valueOf(ld); + assertThrows(NullPointerException.class, () -> Date.valueOf(ld)); } /* * Validate an UnsupportedOperationException occurs when toInstant() is * called */ - @Test(expectedExceptions = UnsupportedOperationException.class) + @Test public void test16() throws Exception { Date d = Date.valueOf("1961-08-30"); - Instant instant = d.toInstant(); + assertThrows(UnsupportedOperationException.class, d::toInstant); } /* @@ -271,55 +276,55 @@ public class DateTests extends BaseTest { /* * Validate an IllegalArgumentException is thrown for calling getHours */ - @Test(expectedExceptions = IllegalArgumentException.class) + @Test public void test21() throws Exception { Date d = Date.valueOf("1961-08-30"); - d.getHours(); + assertThrows(IllegalArgumentException.class, d::getHours); } /* * Validate an IllegalArgumentException is thrown for calling getMinutes */ - @Test(expectedExceptions = IllegalArgumentException.class) + @Test public void test22() throws Exception { Date d = Date.valueOf("1961-08-30"); - d.getMinutes(); + assertThrows(IllegalArgumentException.class, d::getMinutes); } /* * Validate an IllegalArgumentException is thrown for calling getSeconds */ - @Test(expectedExceptions = IllegalArgumentException.class) + @Test public void test23() throws Exception { Date d = Date.valueOf("1961-08-30"); - d.getSeconds(); + assertThrows(IllegalArgumentException.class, d::getSeconds); } /* * Validate an IllegalArgumentException is thrown for calling setHours */ - @Test(expectedExceptions = IllegalArgumentException.class) + @Test public void test24() throws Exception { Date d = Date.valueOf("1961-08-30"); - d.setHours(8); + assertThrows(IllegalArgumentException.class, () -> d.setHours(8)); } /* * Validate an IllegalArgumentException is thrown for calling setMinutes */ - @Test(expectedExceptions = IllegalArgumentException.class) + @Test public void test25() throws Exception { Date d = Date.valueOf("1961-08-30"); - d.setMinutes(0); + assertThrows(IllegalArgumentException.class, () -> d.setMinutes(0)); } /* * Validate an IllegalArgumentException is thrown for calling setSeconds */ - @Test(expectedExceptions = IllegalArgumentException.class) + @Test public void test26() throws Exception { Date d = Date.valueOf("1961-08-30"); - d.setSeconds(0); + assertThrows(IllegalArgumentException.class, () -> d.setSeconds(0)); } /* @@ -327,32 +332,31 @@ public class DateTests extends BaseTest { * to validate that an IllegalArgumentException will be thrown from the * valueOf method */ - @DataProvider(name = "invalidDateValues") - private Object[][] invalidDateValues() { - return new Object[][]{ - {"20009-11-01"}, - {"09-11-01"}, - {"-11-01"}, - {"2009-111-01"}, - {"2009--01"}, - {"2009-13-01"}, - {"2009-11-011"}, - {"2009-11-"}, - {"2009-11-00"}, - {"2009-11-33"}, - {"--"}, - {""}, - {null}, - {"-"}, - {"2009"}, - {"2009-01"}, - {"---"}, - {"2009-13--1"}, - {"1900-1-0"}, - {"2009-01-01 10:50:01"}, - {"1996-12-10 12:26:19.1"}, - {"10:50:01"} - }; + private Stream invalidDateValues() { + return Stream.of( + "20009-11-01", + "09-11-01", + "-11-01", + "2009-111-01", + "2009--01", + "2009-13-01", + "2009-11-011", + "2009-11-", + "2009-11-00", + "2009-11-33", + "--", + "", + null, + "-", + "2009", + "2009-01", + "---", + "2009-13--1", + "1900-1-0", + "2009-01-01 10:50:01", + "1996-12-10 12:26:19.1", + "10:50:01" + ); } /* @@ -360,14 +364,12 @@ public class DateTests extends BaseTest { * to validate that an IllegalArgumentException will not be thrown from the * valueOf method and the corect value from toString() is returned */ - @DataProvider(name = "validDateValues") - private Object[][] validDateValues() { - return new Object[][]{ - {"2009-08-30", "2009-08-30"}, - {"2009-01-8", "2009-01-08"}, - {"2009-1-01", "2009-01-01"}, - {"2009-1-1", "2009-01-01"} - - }; + private Stream validDateValues() { + return Stream.of( + Arguments.of("2009-08-30", "2009-08-30"), + Arguments.of("2009-01-8", "2009-01-08"), + Arguments.of("2009-1-01", "2009-01-01"), + Arguments.of("2009-1-1", "2009-01-01") + ); } } diff --git a/test/jdk/java/sql/testng/test/sql/DriverManagerTests.java b/test/jdk/java/sql/test/sql/DriverManagerTests.java similarity index 84% rename from test/jdk/java/sql/testng/test/sql/DriverManagerTests.java rename to test/jdk/java/sql/test/sql/DriverManagerTests.java index 6b6e8386835..3797b625d21 100644 --- a/test/jdk/java/sql/testng/test/sql/DriverManagerTests.java +++ b/test/jdk/java/sql/test/sql/DriverManagerTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package test.sql; +package sql; import java.io.BufferedReader; import java.io.ByteArrayInputStream; @@ -39,12 +39,10 @@ import java.util.Collections; import java.util.Properties; import java.util.stream.Collectors; -import static org.testng.Assert.*; -import org.testng.annotations.AfterClass; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + import util.StubDriver; public class DriverManagerTests { @@ -58,23 +56,11 @@ public class DriverManagerTests { public DriverManagerTests() { } - @BeforeClass - public static void setUpClass() throws Exception { - } - - @AfterClass - public static void tearDownClass() throws Exception { - } - - @BeforeMethod + @BeforeEach public void setUpMethod() throws Exception { removeAllDrivers(); } - @AfterMethod - public void tearDownMethod() throws Exception { - } - /** * Utility method to remove all registered drivers */ @@ -113,7 +99,7 @@ public class DriverManagerTests { int[] vals = {-1, 0, 5}; for (int val : vals) { DriverManager.setLoginTimeout(val); - assertEquals(val, DriverManager.getLoginTimeout()); + assertEquals(DriverManager.getLoginTimeout(), val); } } @@ -121,20 +107,22 @@ public class DriverManagerTests { * Validate that NullPointerException is thrown when null is passed to * registerDriver */ - @Test(expectedExceptions = NullPointerException.class) + @Test public void test1() throws Exception { Driver d = null; - DriverManager.registerDriver(d); + assertThrows(NullPointerException.class, + () -> DriverManager.registerDriver(d)); } /** * Validate that NullPointerException is thrown when null is passed to * registerDriver */ - @Test(expectedExceptions = NullPointerException.class) + @Test public void test2() throws Exception { Driver d = null; - DriverManager.registerDriver(d, null); + assertThrows(NullPointerException.class, () -> + DriverManager.registerDriver(d, null)); } /** @@ -150,68 +138,68 @@ public class DriverManagerTests { * Validate that SQLException is thrown when there is no Driver to service * the URL */ - @Test(expectedExceptions = SQLException.class) + @Test public void test4() throws Exception { - DriverManager.getConnection(InvalidURL); + assertThrows(SQLException.class, () -> DriverManager.getConnection(InvalidURL)); } /** * Validate that SQLException is thrown when there is no Driver to service * the URL */ - @Test(expectedExceptions = SQLException.class) + @Test public void test5() throws Exception { - DriverManager.getConnection(InvalidURL, new Properties()); + assertThrows(SQLException.class, () -> DriverManager.getConnection(InvalidURL, new Properties())); } /** * Validate that SQLException is thrown when there is no Driver to service * the URL */ - @Test(expectedExceptions = SQLException.class) + @Test public void test6() throws Exception { - DriverManager.getConnection(InvalidURL, "LuckyDog", "tennisanyone"); + assertThrows(SQLException.class, () -> DriverManager.getConnection(InvalidURL, "LuckyDog", "tennisanyone")); } /** * Validate that SQLException is thrown when null is passed for the URL */ - @Test(expectedExceptions = SQLException.class) + @Test public void test7() throws Exception { - DriverManager.getConnection(null); + assertThrows(SQLException.class, () -> DriverManager.getConnection(null)); } /** * Validate that SQLException is thrown when null is passed for the URL */ - @Test(expectedExceptions = SQLException.class) + @Test public void test8() throws Exception { - DriverManager.getConnection(null, new Properties()); + assertThrows(SQLException.class, () -> DriverManager.getConnection(null, new Properties())); } /** * Validate that SQLException is thrown when null is passed for the URL */ - @Test(expectedExceptions = SQLException.class) + @Test public void test9() throws Exception { - DriverManager.getConnection(null, "LuckyDog", "tennisanyone"); + assertThrows(SQLException.class, () -> DriverManager.getConnection(null, "LuckyDog", "tennisanyone")); } /** * Validate that SQLException is thrown when there is no Driver to service * the URL */ - @Test(expectedExceptions = SQLException.class) + @Test public void test10() throws Exception { - DriverManager.getDriver(InvalidURL); + assertThrows(SQLException.class, () -> DriverManager.getDriver(InvalidURL)); } /** * Validate that SQLException is thrown when null is passed for the URL */ - @Test(expectedExceptions = SQLException.class) + @Test public void test11() throws Exception { - DriverManager.getDriver(null); + assertThrows(SQLException.class, () -> DriverManager.getDriver(null)); } /** @@ -229,10 +217,10 @@ public class DriverManagerTests { * Validate that SQLException is thrown when the URL is not valid for any of * the registered drivers */ - @Test(expectedExceptions = SQLException.class) + @Test public void test13() throws Exception { DriverManager.registerDriver(new StubDriver()); - DriverManager.getDriver(InvalidURL); + assertThrows(SQLException.class, () -> DriverManager.getDriver(InvalidURL)); } /** @@ -370,9 +358,9 @@ public class DriverManagerTests { } Collection expectedDrivers = Collections.list(DriverManager.getDrivers()); - assertEquals(expectedDrivers.size(), n); + assertEquals(n, expectedDrivers.size()); Collection drivers = DriverManager.drivers().collect(Collectors.toList()); - assertEquals(drivers, expectedDrivers); + assertEquals(expectedDrivers, drivers); } } diff --git a/test/jdk/java/sql/test/sql/JavatimeTest.java b/test/jdk/java/sql/test/sql/JavatimeTest.java new file mode 100644 index 00000000000..acc0ac3e841 --- /dev/null +++ b/test/jdk/java/sql/test/sql/JavatimeTest.java @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2013, 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package sql; + +/* + * @test + * @bug 8007520 + * @summary Test those bridge methods to/from java.time date/time classes + * @key randomness + */ + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.FieldSource; + +import java.util.List; +import java.util.Random; +import java.sql.Timestamp; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.util.stream.IntStream; + +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class JavatimeTest { + + private static final int NANOS_PER_SECOND = 1000000000; + private static final long t1970 = new java.util.Date(70, 0, 01).getTime(); + private static final Random R = new Random(); + // Data provider contains 10,000 randomized arguments + // which are used as the dates and times for the tests + private static final List DATE_TIME_ARGS = IntStream.range(0, 10_000) + .mapToObj(i -> { + int days = R.nextInt(50) * 365 + R.nextInt(365); + long secs = t1970 + days * 86400 + R.nextInt(86400); + int nanos = R.nextInt(NANOS_PER_SECOND); + int nanos_ms = nanos / 1000000 * 1000000; // millis precision + long millis = secs * 1000 + R.nextInt(1000); + LocalDateTime ldt = LocalDateTime.ofEpochSecond(secs, nanos, ZoneOffset.UTC); + return Arguments.of(millis, nanos, ldt, secs, nanos_ms); + }).toList(); + + @ParameterizedTest(autoCloseArguments = false) + @FieldSource("DATE_TIME_ARGS") + void timestampTest(long millis, int nanos, LocalDateTime ldt, long secs) { + Timestamp ta = new Timestamp(millis); + ta.setNanos(nanos); + assertTrue(isEqual(ta.toLocalDateTime(), ta), + errMsg("j.s.ts -> ldt", millis, nanos, ldt, results(ta.toLocalDateTime(), ta))); + + assertTrue(isEqual(ldt, Timestamp.valueOf(ldt)), + errMsg("ldt -> j.s.ts", millis, nanos, ldt, results(ldt, Timestamp.valueOf(ldt)))); + + Instant inst0 = ta.toInstant(); + assertAll(errMsg("j.s.ts -> instant -> j.s.ts", millis, nanos, ldt), + () -> assertEquals(ta.getTime(), inst0.toEpochMilli()), + () -> assertEquals(ta.getNanos(), inst0.getNano()), + () -> assertEquals(ta, Timestamp.from(inst0)) + ); + + Instant inst = Instant.ofEpochSecond(secs, nanos); + Timestamp ta0 = Timestamp.from(inst); + assertAll(errMsg("instant -> timestamp -> instant", millis, nanos, ldt), + () -> assertEquals(ta0.getTime(), inst.toEpochMilli()), + () -> assertEquals(ta0.getNanos(), inst.getNano()), + () -> assertEquals(inst, ta0.toInstant()) + ); + } + + @ParameterizedTest(autoCloseArguments = false) + @FieldSource("DATE_TIME_ARGS") + void sqlDateTest(long millis, int nanos, LocalDateTime ldt) { + // j.s.d/t uses j.u.d.equals() !!!!!!!! + java.sql.Date jsd = new java.sql.Date(millis); + assertTrue(isEqual(jsd.toLocalDate(), jsd), + errMsg("j.s.d -> ld", millis, nanos, ldt, results(jsd.toLocalDate(), jsd))); + + LocalDate ld = ldt.toLocalDate(); + assertTrue(isEqual(ld, java.sql.Date.valueOf(ld)), + errMsg("ld -> j.s.d", millis, nanos, ldt, results(ld, java.sql.Date.valueOf(ld)))); + } + + @ParameterizedTest(autoCloseArguments = false) + @FieldSource("DATE_TIME_ARGS") + void sqlTimeTest(long millis, int nanos, LocalDateTime ldt, long secs, int nanos_ms) { + java.sql.Time jst = new java.sql.Time(millis); + assertTrue(isEqual(jst.toLocalTime(), jst), + errMsg("j.s.t -> lt", millis, nanos, ldt, results(jst.toLocalTime(), jst))); + + // millis precision + LocalDateTime ldt_ms = LocalDateTime.ofEpochSecond(secs, nanos_ms, ZoneOffset.UTC); + LocalTime lt = ldt_ms.toLocalTime(); + assertTrue(isEqual(lt, java.sql.Time.valueOf(lt)), + errMsg("lt -> j.s.t", millis, nanos, ldt, results(lt, java.sql.Time.valueOf(lt)))); + } + + private static boolean isEqual(LocalDateTime ldt, Timestamp ts) { + ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.systemDefault()); + return zdt.getYear() == ts.getYear() + 1900 && + zdt.getMonthValue() == ts.getMonth() + 1 && + zdt.getDayOfMonth() == ts.getDate() && + zdt.getHour() == ts.getHours() && + zdt.getMinute() == ts.getMinutes() && + zdt.getSecond() == ts.getSeconds() && + zdt.getNano() == ts.getNanos(); + } + + private static String results(LocalDateTime ldt, Timestamp ts) { + ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.systemDefault()); + return "ldt:ts %d/%d, %d/%d, %d/%d, %d/%d, %d/%d, %d/%d, nano:[%d/%d]%n".formatted( + zdt.getYear(), ts.getYear() + 1900, + zdt.getMonthValue(), ts.getMonth() + 1, + zdt.getDayOfMonth(), ts.getDate(), + zdt.getHour(), ts.getHours(), + zdt.getMinute(), ts.getMinutes(), + zdt.getSecond(), ts.getSeconds(), + zdt.getNano(), ts.getNanos()); + } + + private static boolean isEqual(LocalDate ld, java.sql.Date d) { + return ld.getYear() == d.getYear() + 1900 && + ld.getMonthValue() == d.getMonth() + 1 && + ld.getDayOfMonth() == d.getDate(); + } + + private static String results(LocalDate ld, java.sql.Date d) { + return "%d/%d, %d/%d, %d/%d%n".formatted( + ld.getYear(), d.getYear() + 1900, + ld.getMonthValue(), d.getMonth() + 1, + ld.getDayOfMonth(), d.getDate()); + } + + private static boolean isEqual(LocalTime lt, java.sql.Time t) { + return lt.getHour() == t.getHours() && + lt.getMinute() == t.getMinutes() && + lt.getSecond() == t.getSeconds(); + } + + private static String results(LocalTime lt, java.sql.Time t) { + return "%d/%d, %d/%d, %d/%d%n".formatted( + lt.getHour(), t.getHours(), + lt.getMinute(), t.getMinutes(), + lt.getSecond(), t.getSeconds()); + } + + private static String errMsg(String testCase, long millis, int nanos, + LocalDateTime ldt, String results) { + return "FAILED: %s%n INPUTS: ms: %16d ns: %10d ldt:[%s]%n ACTUAL: %s" + .formatted(testCase, millis, nanos, ldt, results); + } + + private static String errMsg(String testCase, long millis, int nanos, + LocalDateTime ldt) { + return "FAILED: %s%n INPUTS: ms: %16d ns: %10d ldt:[%s]%n" + .formatted(testCase, millis, nanos, ldt); + } +} \ No newline at end of file diff --git a/test/jdk/java/sql/testng/test/sql/PreparedStatementTests.java b/test/jdk/java/sql/test/sql/PreparedStatementTests.java similarity index 62% rename from test/jdk/java/sql/testng/test/sql/PreparedStatementTests.java rename to test/jdk/java/sql/test/sql/PreparedStatementTests.java index 7813038361d..574b0369b4e 100644 --- a/test/jdk/java/sql/testng/test/sql/PreparedStatementTests.java +++ b/test/jdk/java/sql/test/sql/PreparedStatementTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,29 +20,34 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package test.sql; +package sql; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; +import org.junit.jupiter.params.provider.ValueSource; import util.BaseTest; import util.StubConnection; import java.sql.PreparedStatement; import java.sql.SQLException; -import static org.testng.Assert.assertEquals; +import org.junit.jupiter.api.AfterEach; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; public class PreparedStatementTests extends BaseTest { private PreparedStatement pstmt; - @BeforeMethod + @BeforeEach public void setUpMethod() throws Exception { pstmt = new StubConnection().prepareStatement("Select * from foo were bar = ?"); } - @AfterMethod + @AfterEach public void tearDownMethod() throws Exception { pstmt.close(); } @@ -51,80 +56,84 @@ public class PreparedStatementTests extends BaseTest { * Verify that enquoteLiteral creates a valid literal and converts every * single quote to two single quotes */ - @Test(dataProvider = "validEnquotedLiteralValues") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("validEnquotedLiteralValues") public void test00(String s, String expected) throws SQLException { - assertEquals(pstmt.enquoteLiteral(s), expected); + assertEquals(expected, pstmt.enquoteLiteral(s)); } /* * Validate a NullPointerException is thrown if the string passed to * enquoteLiteral is null */ - @Test(expectedExceptions = NullPointerException.class) + @Test public void test01() throws SQLException { - pstmt.enquoteLiteral(null); + assertThrows(NullPointerException.class, () -> pstmt.enquoteLiteral(null)); } /* * Validate that enquoteIdentifier returns the expected value */ - @Test(dataProvider = "validIdentifierValues") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("validEnquotedIdentifierValues") public void test02(String s, boolean alwaysQuote, String expected) throws SQLException { - assertEquals(pstmt.enquoteIdentifier(s, alwaysQuote), expected); + assertEquals(expected, pstmt.enquoteIdentifier(s, alwaysQuote)); } /* * Validate that a SQLException is thrown for values that are not valid * for a SQL identifier */ - @Test(dataProvider = "invalidIdentifierValues", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidEnquotedIdentifierValues") public void test03(String s, boolean alwaysQuote) throws SQLException { - pstmt.enquoteIdentifier(s, alwaysQuote); + assertThrows(SQLException.class, () -> pstmt.enquoteIdentifier(s, alwaysQuote)); } /* * Validate a NullPointerException is thrown is the string passed to * enquoteIdentiifer is null */ - @Test(dataProvider = "trueFalse", - expectedExceptions = NullPointerException.class) + @ParameterizedTest(autoCloseArguments = false) + @ValueSource(booleans = {true, false}) public void test04(boolean alwaysQuote) throws SQLException { - pstmt.enquoteIdentifier(null, alwaysQuote); + assertThrows(NullPointerException.class, () -> pstmt.enquoteIdentifier(null, alwaysQuote)); } /* * Validate that isSimpleIdentifier returns the expected value */ - @Test(dataProvider = "simpleIdentifierValues") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("simpleIdentifierValues") public void test05(String s, boolean expected) throws SQLException { - assertEquals(pstmt.isSimpleIdentifier(s), expected); + assertEquals(expected, pstmt.isSimpleIdentifier(s)); } /* * Validate a NullPointerException is thrown if the string passed to * isSimpleIdentifier is null */ - @Test(expectedExceptions = NullPointerException.class) + @Test public void test06() throws SQLException { - pstmt.isSimpleIdentifier(null); + assertThrows(NullPointerException.class, () -> pstmt.isSimpleIdentifier(null)); } /* * Verify that enquoteLiteral creates a valid literal and converts every * single quote to two single quotes */ - @Test(dataProvider = "validEnquotedNCharLiteralValues") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("validEnquotedNCharLiteralValues") public void test07(String s, String expected) throws SQLException { - assertEquals(pstmt.enquoteNCharLiteral(s), expected); + assertEquals(expected, pstmt.enquoteNCharLiteral(s)); } /* * Validate a NullPointerException is thrown if the string passed to * enquoteNCharLiteral is null */ - @Test(expectedExceptions = NullPointerException.class) + @Test public void test08() throws SQLException { - pstmt.enquoteNCharLiteral(null); + assertThrows(NullPointerException.class, () -> pstmt.enquoteNCharLiteral(null)); } } diff --git a/test/jdk/java/sql/testng/test/sql/SQLClientInfoExceptionTests.java b/test/jdk/java/sql/test/sql/SQLClientInfoExceptionTests.java similarity index 97% rename from test/jdk/java/sql/testng/test/sql/SQLClientInfoExceptionTests.java rename to test/jdk/java/sql/test/sql/SQLClientInfoExceptionTests.java index 84230b86758..bea35d95c1c 100644 --- a/test/jdk/java/sql/testng/test/sql/SQLClientInfoExceptionTests.java +++ b/test/jdk/java/sql/test/sql/SQLClientInfoExceptionTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,14 +20,16 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package test.sql; +package sql; import java.sql.ClientInfoStatus; import java.sql.SQLClientInfoException; import java.sql.SQLException; import java.util.HashMap; -import static org.testng.Assert.*; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + import util.BaseTest; public class SQLClientInfoExceptionTests extends BaseTest { diff --git a/test/jdk/java/sql/testng/test/sql/SQLDataExceptionTests.java b/test/jdk/java/sql/test/sql/SQLDataExceptionTests.java similarity index 97% rename from test/jdk/java/sql/testng/test/sql/SQLDataExceptionTests.java rename to test/jdk/java/sql/test/sql/SQLDataExceptionTests.java index 8a5f8d1a2c1..a18f6406e66 100644 --- a/test/jdk/java/sql/testng/test/sql/SQLDataExceptionTests.java +++ b/test/jdk/java/sql/test/sql/SQLDataExceptionTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,13 +20,15 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package test.sql; +package sql; import java.sql.SQLDataException; import java.sql.SQLException; import java.sql.SQLNonTransientException; -import static org.testng.Assert.*; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + import util.BaseTest; public class SQLDataExceptionTests extends BaseTest { diff --git a/test/jdk/java/sql/testng/test/sql/SQLExceptionTests.java b/test/jdk/java/sql/test/sql/SQLExceptionTests.java similarity index 97% rename from test/jdk/java/sql/testng/test/sql/SQLExceptionTests.java rename to test/jdk/java/sql/test/sql/SQLExceptionTests.java index e3643ef119c..8a7850d8fd9 100644 --- a/test/jdk/java/sql/testng/test/sql/SQLExceptionTests.java +++ b/test/jdk/java/sql/test/sql/SQLExceptionTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,11 +20,13 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package test.sql; +package sql; import java.sql.SQLException; -import static org.testng.Assert.*; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + import util.BaseTest; public class SQLExceptionTests extends BaseTest { diff --git a/test/jdk/java/sql/testng/test/sql/SQLFeatureNotSupportedExceptionTests.java b/test/jdk/java/sql/test/sql/SQLFeatureNotSupportedExceptionTests.java similarity index 97% rename from test/jdk/java/sql/testng/test/sql/SQLFeatureNotSupportedExceptionTests.java rename to test/jdk/java/sql/test/sql/SQLFeatureNotSupportedExceptionTests.java index 5b95894412c..24049addfa1 100644 --- a/test/jdk/java/sql/testng/test/sql/SQLFeatureNotSupportedExceptionTests.java +++ b/test/jdk/java/sql/test/sql/SQLFeatureNotSupportedExceptionTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,13 +20,15 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package test.sql; +package sql; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.sql.SQLNonTransientException; -import static org.testng.Assert.*; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + import util.BaseTest; public class SQLFeatureNotSupportedExceptionTests extends BaseTest { diff --git a/test/jdk/java/sql/testng/test/sql/SQLIntegrityConstraintViolationExceptionTests.java b/test/jdk/java/sql/test/sql/SQLIntegrityConstraintViolationExceptionTests.java similarity index 97% rename from test/jdk/java/sql/testng/test/sql/SQLIntegrityConstraintViolationExceptionTests.java rename to test/jdk/java/sql/test/sql/SQLIntegrityConstraintViolationExceptionTests.java index 082e0af15c8..c8c0958e3f3 100644 --- a/test/jdk/java/sql/testng/test/sql/SQLIntegrityConstraintViolationExceptionTests.java +++ b/test/jdk/java/sql/test/sql/SQLIntegrityConstraintViolationExceptionTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,13 +20,15 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package test.sql; +package sql; import java.sql.SQLException; import java.sql.SQLIntegrityConstraintViolationException; import java.sql.SQLNonTransientException; -import static org.testng.Assert.*; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + import util.BaseTest; public class SQLIntegrityConstraintViolationExceptionTests extends BaseTest { diff --git a/test/jdk/java/sql/testng/test/sql/SQLInvalidAuthorizationSpecExceptionTests.java b/test/jdk/java/sql/test/sql/SQLInvalidAuthorizationSpecExceptionTests.java similarity index 97% rename from test/jdk/java/sql/testng/test/sql/SQLInvalidAuthorizationSpecExceptionTests.java rename to test/jdk/java/sql/test/sql/SQLInvalidAuthorizationSpecExceptionTests.java index 6e4eaa567ee..82a9a345a0e 100644 --- a/test/jdk/java/sql/testng/test/sql/SQLInvalidAuthorizationSpecExceptionTests.java +++ b/test/jdk/java/sql/test/sql/SQLInvalidAuthorizationSpecExceptionTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,13 +20,15 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package test.sql; +package sql; import java.sql.SQLException; import java.sql.SQLInvalidAuthorizationSpecException; import java.sql.SQLNonTransientException; -import static org.testng.Assert.*; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + import util.BaseTest; public class SQLInvalidAuthorizationSpecExceptionTests extends BaseTest { diff --git a/test/jdk/java/sql/testng/test/sql/SQLNonTransientConnectionExceptionTests.java b/test/jdk/java/sql/test/sql/SQLNonTransientConnectionExceptionTests.java similarity index 97% rename from test/jdk/java/sql/testng/test/sql/SQLNonTransientConnectionExceptionTests.java rename to test/jdk/java/sql/test/sql/SQLNonTransientConnectionExceptionTests.java index dbd8b685844..fa4c75ed672 100644 --- a/test/jdk/java/sql/testng/test/sql/SQLNonTransientConnectionExceptionTests.java +++ b/test/jdk/java/sql/test/sql/SQLNonTransientConnectionExceptionTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,13 +20,15 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package test.sql; +package sql; import java.sql.SQLException; import java.sql.SQLNonTransientConnectionException; import java.sql.SQLNonTransientException; -import static org.testng.Assert.*; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + import util.BaseTest; public class SQLNonTransientConnectionExceptionTests extends BaseTest { diff --git a/test/jdk/java/sql/testng/test/sql/SQLNonTransientExceptionTests.java b/test/jdk/java/sql/test/sql/SQLNonTransientExceptionTests.java similarity index 97% rename from test/jdk/java/sql/testng/test/sql/SQLNonTransientExceptionTests.java rename to test/jdk/java/sql/test/sql/SQLNonTransientExceptionTests.java index 061ffe20840..0f37f905fa7 100644 --- a/test/jdk/java/sql/testng/test/sql/SQLNonTransientExceptionTests.java +++ b/test/jdk/java/sql/test/sql/SQLNonTransientExceptionTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,12 +20,14 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package test.sql; +package sql; import java.sql.SQLException; import java.sql.SQLNonTransientException; -import static org.testng.Assert.*; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + import util.BaseTest; public class SQLNonTransientExceptionTests extends BaseTest { diff --git a/test/jdk/java/sql/testng/test/sql/SQLRecoverableExceptionTests.java b/test/jdk/java/sql/test/sql/SQLRecoverableExceptionTests.java similarity index 97% rename from test/jdk/java/sql/testng/test/sql/SQLRecoverableExceptionTests.java rename to test/jdk/java/sql/test/sql/SQLRecoverableExceptionTests.java index d23a131dbcd..d447e08593c 100644 --- a/test/jdk/java/sql/testng/test/sql/SQLRecoverableExceptionTests.java +++ b/test/jdk/java/sql/test/sql/SQLRecoverableExceptionTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,12 +20,14 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package test.sql; +package sql; import java.sql.SQLException; import java.sql.SQLRecoverableException; -import static org.testng.Assert.*; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + import util.BaseTest; public class SQLRecoverableExceptionTests extends BaseTest { diff --git a/test/jdk/java/sql/testng/test/sql/SQLSyntaxErrorExceptionTests.java b/test/jdk/java/sql/test/sql/SQLSyntaxErrorExceptionTests.java similarity index 97% rename from test/jdk/java/sql/testng/test/sql/SQLSyntaxErrorExceptionTests.java rename to test/jdk/java/sql/test/sql/SQLSyntaxErrorExceptionTests.java index 863213cfcb8..c859f5aa0d2 100644 --- a/test/jdk/java/sql/testng/test/sql/SQLSyntaxErrorExceptionTests.java +++ b/test/jdk/java/sql/test/sql/SQLSyntaxErrorExceptionTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,13 +20,15 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package test.sql; +package sql; import java.sql.SQLException; import java.sql.SQLNonTransientException; import java.sql.SQLSyntaxErrorException; -import static org.testng.Assert.*; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + import util.BaseTest; public class SQLSyntaxErrorExceptionTests extends BaseTest { diff --git a/test/jdk/java/sql/testng/test/sql/SQLTimeoutExceptionTests.java b/test/jdk/java/sql/test/sql/SQLTimeoutExceptionTests.java similarity index 97% rename from test/jdk/java/sql/testng/test/sql/SQLTimeoutExceptionTests.java rename to test/jdk/java/sql/test/sql/SQLTimeoutExceptionTests.java index dfe341545e4..a4e249658d9 100644 --- a/test/jdk/java/sql/testng/test/sql/SQLTimeoutExceptionTests.java +++ b/test/jdk/java/sql/test/sql/SQLTimeoutExceptionTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,13 +20,15 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package test.sql; +package sql; import java.sql.SQLException; import java.sql.SQLTimeoutException; import java.sql.SQLTransientException; -import static org.testng.Assert.*; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + import util.BaseTest; public class SQLTimeoutExceptionTests extends BaseTest { diff --git a/test/jdk/java/sql/testng/test/sql/SQLTransactionRollbackExceptionTests.java b/test/jdk/java/sql/test/sql/SQLTransactionRollbackExceptionTests.java similarity index 97% rename from test/jdk/java/sql/testng/test/sql/SQLTransactionRollbackExceptionTests.java rename to test/jdk/java/sql/test/sql/SQLTransactionRollbackExceptionTests.java index 8453ebe1364..7a7d94cd060 100644 --- a/test/jdk/java/sql/testng/test/sql/SQLTransactionRollbackExceptionTests.java +++ b/test/jdk/java/sql/test/sql/SQLTransactionRollbackExceptionTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,13 +20,15 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package test.sql; +package sql; import java.sql.SQLException; import java.sql.SQLTransactionRollbackException; import java.sql.SQLTransientException; -import static org.testng.Assert.*; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + import util.BaseTest; public class SQLTransactionRollbackExceptionTests extends BaseTest { diff --git a/test/jdk/java/sql/testng/test/sql/SQLTransientConnectionExceptionTests.java b/test/jdk/java/sql/test/sql/SQLTransientConnectionExceptionTests.java similarity index 97% rename from test/jdk/java/sql/testng/test/sql/SQLTransientConnectionExceptionTests.java rename to test/jdk/java/sql/test/sql/SQLTransientConnectionExceptionTests.java index 7999253b1fa..8ac6ef98222 100644 --- a/test/jdk/java/sql/testng/test/sql/SQLTransientConnectionExceptionTests.java +++ b/test/jdk/java/sql/test/sql/SQLTransientConnectionExceptionTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,13 +20,15 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package test.sql; +package sql; import java.sql.SQLException; import java.sql.SQLTransientConnectionException; import java.sql.SQLTransientException; -import static org.testng.Assert.*; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + import util.BaseTest; public class SQLTransientConnectionExceptionTests extends BaseTest { diff --git a/test/jdk/java/sql/testng/test/sql/SQLTransientExceptionTests.java b/test/jdk/java/sql/test/sql/SQLTransientExceptionTests.java similarity index 97% rename from test/jdk/java/sql/testng/test/sql/SQLTransientExceptionTests.java rename to test/jdk/java/sql/test/sql/SQLTransientExceptionTests.java index d86f86b8fc6..4c43b6c693e 100644 --- a/test/jdk/java/sql/testng/test/sql/SQLTransientExceptionTests.java +++ b/test/jdk/java/sql/test/sql/SQLTransientExceptionTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,12 +20,14 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package test.sql; +package sql; import java.sql.SQLException; import java.sql.SQLTransientException; -import static org.testng.Assert.*; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + import util.BaseTest; public class SQLTransientExceptionTests extends BaseTest { diff --git a/test/jdk/java/sql/testng/test/sql/SQLWarningTests.java b/test/jdk/java/sql/test/sql/SQLWarningTests.java similarity index 97% rename from test/jdk/java/sql/testng/test/sql/SQLWarningTests.java rename to test/jdk/java/sql/test/sql/SQLWarningTests.java index 2856742dc5c..ab15a877dbd 100644 --- a/test/jdk/java/sql/testng/test/sql/SQLWarningTests.java +++ b/test/jdk/java/sql/test/sql/SQLWarningTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,12 +20,14 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package test.sql; +package sql; import java.sql.SQLException; import java.sql.SQLWarning; -import static org.testng.Assert.*; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + import util.BaseTest; public class SQLWarningTests extends BaseTest { diff --git a/test/jdk/java/sql/testng/test/sql/StatementTests.java b/test/jdk/java/sql/test/sql/StatementTests.java similarity index 62% rename from test/jdk/java/sql/testng/test/sql/StatementTests.java rename to test/jdk/java/sql/test/sql/StatementTests.java index f2bfe712eb5..42e971cc971 100644 --- a/test/jdk/java/sql/testng/test/sql/StatementTests.java +++ b/test/jdk/java/sql/test/sql/StatementTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,14 +20,21 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package test.sql; +package sql; import java.sql.SQLException; import java.sql.Statement; -import static org.testng.Assert.assertEquals; +import org.junit.jupiter.api.AfterEach; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; -import org.testng.annotations.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import org.junit.jupiter.params.provider.ValueSource; import util.BaseTest; import util.StubConnection; @@ -35,12 +42,12 @@ public class StatementTests extends BaseTest { private Statement stmt; - @BeforeMethod + @BeforeEach public void setUpMethod() throws Exception { stmt = new StubConnection().createStatement(); } - @AfterMethod + @AfterEach public void tearDownMethod() throws Exception { stmt.close(); } @@ -48,80 +55,84 @@ public class StatementTests extends BaseTest { * Verify that enquoteLiteral creates a valid literal and converts every * single quote to two single quotes */ - @Test(dataProvider = "validEnquotedLiteralValues") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("validEnquotedLiteralValues") public void test00(String s, String expected) throws SQLException { - assertEquals(stmt.enquoteLiteral(s), expected); + assertEquals(expected, stmt.enquoteLiteral(s)); } /* * Validate a NullPointerException is thrown if the string passed to * enquoteLiteral is null */ - @Test(expectedExceptions = NullPointerException.class) + @Test public void test01() throws SQLException { - stmt.enquoteLiteral(null); + assertThrows(NullPointerException.class, () -> stmt.enquoteLiteral(null)); } /* * Validate that enquoteIdentifier returns the expected value */ - @Test(dataProvider = "validIdentifierValues") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("validEnquotedIdentifierValues") public void test02(String s, boolean alwaysQuote, String expected) throws SQLException { - assertEquals(stmt.enquoteIdentifier(s, alwaysQuote), expected); + assertEquals(expected, stmt.enquoteIdentifier(s, alwaysQuote)); } /* * Validate that a SQLException is thrown for values that are not valid * for a SQL identifier */ - @Test(dataProvider = "invalidIdentifierValues", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidEnquotedIdentifierValues") public void test03(String s, boolean alwaysQuote) throws SQLException { - stmt.enquoteIdentifier(s, alwaysQuote); + assertThrows(SQLException.class, () -> stmt.enquoteIdentifier(s, alwaysQuote)); } /* * Validate a NullPointerException is thrown is the string passed to * enquoteIdentiifer is null */ - @Test(dataProvider = "trueFalse", - expectedExceptions = NullPointerException.class) + @ParameterizedTest(autoCloseArguments = false) + @ValueSource(booleans = {true, false}) public void test04(boolean alwaysQuote) throws SQLException { - stmt.enquoteIdentifier(null, alwaysQuote); + assertThrows(NullPointerException.class, () -> stmt.enquoteIdentifier(null, alwaysQuote)); } /* * Validate that isSimpleIdentifier returns the expected value */ - @Test(dataProvider = "simpleIdentifierValues") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("simpleIdentifierValues") public void test05(String s, boolean expected) throws SQLException { - assertEquals(stmt.isSimpleIdentifier(s), expected); + assertEquals(expected, stmt.isSimpleIdentifier(s)); } /* * Validate a NullPointerException is thrown if the string passed to * isSimpleIdentifier is null */ - @Test(expectedExceptions = NullPointerException.class) + @Test public void test06() throws SQLException { - stmt.isSimpleIdentifier(null); + assertThrows(NullPointerException.class, () -> stmt.isSimpleIdentifier(null)); } /* * Verify that enquoteLiteral creates a valid literal and converts every * single quote to two single quotes */ - @Test(dataProvider = "validEnquotedNCharLiteralValues") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("validEnquotedNCharLiteralValues") public void test07(String s, String expected) throws SQLException { - assertEquals(stmt.enquoteNCharLiteral(s), expected); + assertEquals(expected, stmt.enquoteNCharLiteral(s)); } /* * Validate a NullPointerException is thrown if the string passed to * enquoteNCharLiteral is null */ - @Test(expectedExceptions = NullPointerException.class) + @Test public void test08() throws SQLException { - stmt.enquoteNCharLiteral(null); + assertThrows(NullPointerException.class, () -> stmt.enquoteNCharLiteral(null)); } } diff --git a/test/jdk/java/sql/testng/test/sql/TimeTests.java b/test/jdk/java/sql/test/sql/TimeTests.java similarity index 76% rename from test/jdk/java/sql/testng/test/sql/TimeTests.java rename to test/jdk/java/sql/test/sql/TimeTests.java index 7b99679754b..71208f03222 100644 --- a/test/jdk/java/sql/testng/test/sql/TimeTests.java +++ b/test/jdk/java/sql/test/sql/TimeTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,13 +20,18 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package test.sql; +package sql; import java.sql.Time; import java.time.LocalTime; -import static org.testng.Assert.*; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + import util.BaseTest; public class TimeTests extends BaseTest { @@ -34,73 +39,73 @@ public class TimeTests extends BaseTest { /* * Validate an IllegalArgumentException is thrown for calling getYear */ - @Test(expectedExceptions = IllegalArgumentException.class) + @Test public void test01() { Time t = Time.valueOf("08:30:59"); - t.getYear(); + assertThrows(IllegalArgumentException.class, t::getYear); } /* * Validate an IllegalArgumentException is thrown for calling getMonth */ - @Test(expectedExceptions = IllegalArgumentException.class) + @Test public void test02() { Time t = Time.valueOf("08:30:59"); - t.getMonth(); + assertThrows(IllegalArgumentException.class, t::getMonth); } /* * Validate an IllegalArgumentException is thrown for calling getDay */ - @Test(expectedExceptions = IllegalArgumentException.class) + @Test public void test03() { Time t = Time.valueOf("08:30:59"); - t.getDay(); + assertThrows(IllegalArgumentException.class, t::getDay); } /** * Validate an IllegalArgumentException is thrown for calling getDate */ - @Test(expectedExceptions = IllegalArgumentException.class) + @Test public void test04() { Time t = Time.valueOf("08:30:59"); - t.getDate(); + assertThrows(IllegalArgumentException.class, t::getDate); } /* * Validate an IllegalArgumentException is thrown for calling setYear */ - @Test(expectedExceptions = IllegalArgumentException.class) + @Test public void test05() { Time t = Time.valueOf("08:30:59"); - t.setYear(8); + assertThrows(IllegalArgumentException.class, () -> t.setYear(8)); } /* * Validate an IllegalArgumentException is thrown for calling setMonth */ - @Test(expectedExceptions = IllegalArgumentException.class) + @Test public void test06() { Time t = Time.valueOf("08:30:59"); - t.setMonth(8); + assertThrows(IllegalArgumentException.class, () -> t.setMonth(8)); } /* * Validate an IllegalArgumentException is thrown for calling setDate */ - @Test(expectedExceptions = IllegalArgumentException.class) + @Test public void test07() { Time t = Time.valueOf("08:30:59"); - t.setDate(30); + assertThrows(IllegalArgumentException.class, () -> t.setDate(30)); } /* * Validate an IllegalArgumentException is thrown for calling getDate */ - @Test(expectedExceptions = IllegalArgumentException.class) + @Test public void test08() { Time t = Time.valueOf("08:30:59"); - t.getDate(); + assertThrows(IllegalArgumentException.class, t::getDate); } /* @@ -128,20 +133,20 @@ public class TimeTests extends BaseTest { /* * Validate an NPE occurs when a null LocalDate is passed to valueOf */ - @Test(expectedExceptions = NullPointerException.class) + @Test public void test11() throws Exception { LocalTime ld = null; - Time.valueOf(ld); + assertThrows(NullPointerException.class, () -> Time.valueOf(ld)); } /* * Validate an UnsupportedOperationException occurs when toInstant() is * called */ - @Test(expectedExceptions = UnsupportedOperationException.class) + @Test public void test12() throws Exception { Time t = new Time(System.currentTimeMillis()); - t.toInstant(); + assertThrows(UnsupportedOperationException.class, t::toInstant); } /* @@ -149,7 +154,8 @@ public class TimeTests extends BaseTest { * toString() of the other and that the correct value is returned from * toString() */ - @Test(dataProvider = "validTimeValues") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("validTimeValues") public void test13(String time, String expected) { Time t1 = Time.valueOf(time); Time t2 = Time.valueOf(t1.toString()); @@ -182,10 +188,10 @@ public class TimeTests extends BaseTest { /* * Validate an IllegalArgumentException is thrown for an invalid Time string */ - @Test(dataProvider = "invalidTimeValues", - expectedExceptions = IllegalArgumentException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidTimeValues") public void test16(String time) throws Exception { - Time.valueOf(time); + assertThrows(IllegalArgumentException.class, () -> Time.valueOf(time)); } /* @@ -299,29 +305,28 @@ public class TimeTests extends BaseTest { * to validate that an IllegalArgumentException will be thrown from the * valueOf method */ - @DataProvider(name = "invalidTimeValues") - private Object[][] invalidTimeValues() { - return new Object[][]{ - {"2009-11-01 10:50:01"}, - {"1961-08-30 10:50:01.1"}, - {"1961-08-30"}, - {"00:00:00."}, - {"10:50:0.1"}, - {":00:00"}, - {"00::00"}, - {"00:00:"}, - {"::"}, - {" : : "}, - {"0a:00:00"}, - {"00:bb:00"}, - {"00:01:cc"}, - {"08:10:Batman"}, - {"08:10:10:10"}, - {"08:10"}, - {"a:b:c"}, - {null}, - {"8:"} - }; + private Stream invalidTimeValues() { + return Stream.of( + "2009-11-01 10:50:01", + "1961-08-30 10:50:01.1", + "1961-08-30", + "00:00:00.", + "10:50:0.1", + ":00:00", + "00::00", + "00:00:", + "::", + " : : ", + "0a:00:00", + "00:bb:00", + "00:01:cc", + "08:10:Batman", + "08:10:10:10", + "08:10", + "a:b:c", + null, + "8:" + ); } /* @@ -330,19 +335,18 @@ public class TimeTests extends BaseTest { * valueOf method. It also contains the expected return value from * toString() */ - @DataProvider(name = "validTimeValues") - private Object[][] validTimeValues() { - return new Object[][]{ - {"10:50:01", "10:50:01"}, - {"01:1:1", "01:01:01"}, - {"01:01:1", "01:01:01"}, - {"1:01:1", "01:01:01"}, - {"2:02:02", "02:02:02"}, - {"2:02:2", "02:02:02"}, - {"10:50:1", "10:50:01"}, - {"00:00:00", "00:00:00"}, - {"08:30:59", "08:30:59"}, - {"9:0:1", "09:00:01"} - }; + private Stream validTimeValues() { + return Stream.of( + Arguments.of("10:50:01", "10:50:01"), + Arguments.of("01:1:1", "01:01:01"), + Arguments.of("01:01:1", "01:01:01"), + Arguments.of("1:01:1", "01:01:01"), + Arguments.of("2:02:02", "02:02:02"), + Arguments.of("2:02:2", "02:02:02"), + Arguments.of("10:50:1", "10:50:01"), + Arguments.of("00:00:00", "00:00:00"), + Arguments.of("08:30:59", "08:30:59"), + Arguments.of("9:0:1", "09:00:01") + ); } } diff --git a/test/jdk/java/sql/testng/test/sql/TimestampTests.java b/test/jdk/java/sql/test/sql/TimestampTests.java similarity index 73% rename from test/jdk/java/sql/testng/test/sql/TimestampTests.java rename to test/jdk/java/sql/test/sql/TimestampTests.java index 6baea9fa26f..33a58c8d857 100644 --- a/test/jdk/java/sql/testng/test/sql/TimestampTests.java +++ b/test/jdk/java/sql/test/sql/TimestampTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package test.sql; +package sql; import java.sql.Date; import java.sql.Time; @@ -30,11 +30,16 @@ import java.time.LocalDateTime; import java.time.ZoneId; import java.util.Calendar; import java.util.TimeZone; -import static org.testng.Assert.*; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; +import java.util.stream.Stream; + +import org.junit.jupiter.api.AfterAll; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + import util.BaseTest; public class TimestampTests extends BaseTest { @@ -45,7 +50,7 @@ public class TimestampTests extends BaseTest { * Need to set and use a custom TimeZone which does not * observe daylight savings time for this test. */ - @BeforeClass + @BeforeAll public static void setUpClass() throws Exception { defaultTimeZone = TimeZone.getDefault(); TimeZone tzone = TimeZone.getTimeZone("GMT+01"); @@ -56,7 +61,7 @@ public class TimestampTests extends BaseTest { /* * Conservatively reset the default time zone after test. */ - @AfterClass + @AfterAll public static void tearDownClass() throws Exception { TimeZone.setDefault(defaultTimeZone); } @@ -64,10 +69,10 @@ public class TimestampTests extends BaseTest { /* * Validate an IllegalArgumentException is thrown for an invalid Timestamp */ - @Test(dataProvider = "invalidTimestampValues", - expectedExceptions = IllegalArgumentException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidTimestampValues") public void test(String ts) throws Exception { - Timestamp.valueOf(ts); + assertThrows(IllegalArgumentException.class, () -> Timestamp.valueOf(ts)); } /* @@ -80,7 +85,7 @@ public class TimestampTests extends BaseTest { String ExpectedTS = "2009-01-01 10:50:0"; Timestamp ts = Timestamp.valueOf(testTS); Timestamp ts2 = Timestamp.valueOf(ExpectedTS); - assertEquals(ts, ts2, "Error ts1 != ts2"); + assertEquals(ts2, ts, "Error ts1 != ts2"); } /* @@ -91,7 +96,7 @@ public class TimestampTests extends BaseTest { String testTS = "2009-01-01 10:50:0"; Timestamp ts = Timestamp.valueOf(testTS); Timestamp ts2 = Timestamp.valueOf(testTS); - assertEquals(ts, ts2, "Error ts1 != ts2"); + assertEquals(ts2, ts, "Error ts1 != ts2"); } /* @@ -104,7 +109,7 @@ public class TimestampTests extends BaseTest { String ExpectedTS = "2009-01-01 10:50:0"; Timestamp ts = Timestamp.valueOf(testTS); Timestamp ts2 = Timestamp.valueOf(ExpectedTS); - assertEquals(ts, ts2, "Error ts1 != ts2"); + assertEquals(ts2, ts, "Error ts1 != ts2"); } /* @@ -117,7 +122,7 @@ public class TimestampTests extends BaseTest { String ExpectedTS = "2009-01-01 10:50:0"; Timestamp ts = Timestamp.valueOf(testTS); Timestamp ts2 = Timestamp.valueOf(ExpectedTS); - assertEquals(ts, ts2, "Error ts1 != ts2"); + assertEquals(ts2, ts, "Error ts1 != ts2"); } /* @@ -130,7 +135,7 @@ public class TimestampTests extends BaseTest { String ExpectedTS = "2009-01-01 10:50:0"; Timestamp ts = Timestamp.valueOf(testTS); Timestamp ts2 = Timestamp.valueOf(ExpectedTS); - assertEquals(ts, ts2, "Error ts1 != ts2"); + assertEquals(ts2, ts, "Error ts1 != ts2"); } /* @@ -142,7 +147,7 @@ public class TimestampTests extends BaseTest { String ExpectedTS = "2005-01-01 10:20:50.00"; Timestamp ts = Timestamp.valueOf(testTS); Timestamp ts2 = Timestamp.valueOf(ExpectedTS); - assertEquals(ts, ts2, "Error ts1 != ts2"); + assertEquals(ts2, ts, "Error ts1 != ts2"); } /* @@ -219,7 +224,8 @@ public class TimestampTests extends BaseTest { * Validate that two Timestamps are equal when one is created from the * toString() of the other */ - @Test(dataProvider = "validTimestampValues") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("validTimestampValues") public void test13(String ts, String expectedTS) { Timestamp ts1 = Timestamp.valueOf(ts); Timestamp ts2 = Timestamp.valueOf(ts1.toString()); @@ -263,10 +269,10 @@ public class TimestampTests extends BaseTest { * Validate that a NullPointerException is thrown if a null is passed to * the before method */ - @Test(expectedExceptions = NullPointerException.class) + @Test public void test17() throws Exception { Timestamp ts1 = Timestamp.valueOf("1996-12-13 14:15:25.745634"); - ts1.before(null); + assertThrows(NullPointerException.class, () -> ts1.before(null)); } /* @@ -316,10 +322,10 @@ public class TimestampTests extends BaseTest { * Validate that a NullPointerException is thrown if a null is passed to the * after method */ - @Test(expectedExceptions = NullPointerException.class) + @Test public void test22() throws Exception { Timestamp ts1 = Timestamp.valueOf("1966-08-30 08:08:08"); - ts1.after(null); + assertThrows(NullPointerException.class, () -> ts1.after(null)); } /* @@ -476,21 +482,21 @@ public class TimestampTests extends BaseTest { /* * Validate an IllegalArgumentException is thrown for an invalid nanos value */ - @Test(expectedExceptions = IllegalArgumentException.class) + @Test public void test38() throws Exception { Timestamp ts1 = Timestamp.valueOf("1961-08-30 00:00:00"); - ts1.setNanos(-1); + assertThrows(IllegalArgumentException.class, () -> ts1.setNanos(-1)); } /* * Validate an IllegalArgumentException is thrown for an invalid nanos value */ - @Test(expectedExceptions = IllegalArgumentException.class) + @Test public void test39() throws Exception { int nanos = 999999999; Timestamp ts1 = Timestamp.valueOf("1961-08-30 00:00:00"); - ts1.setNanos(nanos + 1); + assertThrows(IllegalArgumentException.class, () -> ts1.setNanos(nanos + 1)); } /* @@ -541,10 +547,10 @@ public class TimestampTests extends BaseTest { /* * Validate an NPE occurs when a null LocalDateTime is passed to valueOF */ - @Test(expectedExceptions = NullPointerException.class) + @Test public void test44() throws Exception { LocalDateTime ldt = null; - Timestamp.valueOf(ldt); + assertThrows(NullPointerException.class, () -> Timestamp.valueOf(ldt)); } /* @@ -572,10 +578,10 @@ public class TimestampTests extends BaseTest { /* * Validate an NPE occurs when a null instant is passed to from */ - @Test(expectedExceptions = NullPointerException.class) + @Test public void test47() throws Exception { Instant instant = null; - Timestamp.from(instant); + assertThrows(NullPointerException.class, () -> Timestamp.from(instant)); } // Added SQE tests @@ -628,7 +634,8 @@ public class TimestampTests extends BaseTest { * Validate that two Timestamps are equal when one is created from the * toString() of the other */ - @Test(dataProvider = "validateNanos") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("validateNanos") public void test51(String ts, int nanos) { Timestamp ts1 = Timestamp.valueOf(ts); Timestamp ts2 = Timestamp.valueOf(ts1.toString()); @@ -636,35 +643,36 @@ public class TimestampTests extends BaseTest { "Error with Nanos"); } - @Test(dataProvider = "validTimestampLongValues") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("validTimestampLongValues") public void test52(long value, String ts) { Timestamp ts1 = new Timestamp(value); - assertEquals(ts1.toString(), ts, "ts1.toString() != ts"); + assertEquals(ts, ts1.toString(), "ts1.toString() != ts"); } @Test public void test53() { // The latest Instant that can be converted to a Timestamp. Instant instant1 = Instant.ofEpochSecond(Long.MAX_VALUE / 1000, 999_999_999); - assertEquals(Timestamp.from(instant1).toInstant(), instant1); + assertEquals(instant1, Timestamp.from(instant1).toInstant()); // One nanosecond more, and converting it gets an overflow. Instant instant2 = instant1.plusNanos(1); - expectThrows(IllegalArgumentException.class, () -> Timestamp.from(instant2)); + assertThrows(IllegalArgumentException.class, () -> Timestamp.from(instant2)); // The earliest Instant that can be converted to a Timestamp. Instant instant3 = Instant.ofEpochSecond(Long.MIN_VALUE / 1000, 0); - assertEquals(Timestamp.from(instant3).toInstant(), instant3); + assertEquals(instant3, Timestamp.from(instant3).toInstant()); // One nanosecond less, and converting it gets an overflow. Instant instant4 = instant3.minusNanos(1); - expectThrows(IllegalArgumentException.class, () -> Timestamp.from(instant4)); + assertThrows(IllegalArgumentException.class, () -> Timestamp.from(instant4)); // The latest possible Instant will certainly overflow. - expectThrows(IllegalArgumentException.class, () -> Timestamp.from(Instant.MAX)); + assertThrows(IllegalArgumentException.class, () -> Timestamp.from(Instant.MAX)); // The earliest possible Instant will certainly overflow. - expectThrows(IllegalArgumentException.class, () -> Timestamp.from(Instant.MIN)); + assertThrows(IllegalArgumentException.class, () -> Timestamp.from(Instant.MIN)); } /* @@ -683,7 +691,7 @@ public class TimestampTests extends BaseTest { assertTrue(ts1.equals(ts2)); // As the Timestamp values, including the nanos are the same, the hashCode's // should be equal - assertEquals(ts1.hashCode(), ts2.hashCode()); + assertEquals(ts2.hashCode(), ts1.hashCode()); } /* @@ -702,7 +710,7 @@ public class TimestampTests extends BaseTest { assertTrue(ts2.equals(ts2)); assertFalse(ts1.equals(ts2)); // As the nanos differ, the hashCode values should differ - assertNotEquals(ts1.hashCode(), ts2.hashCode()); + assertNotEquals(ts2.hashCode(), ts1.hashCode()); } /* @@ -710,33 +718,32 @@ public class TimestampTests extends BaseTest { * to validate that an IllegalArgumentException will be thrown from the * valueOf method */ - @DataProvider(name = "invalidTimestampValues") - private Object[][] invalidTimestampValues() { - return new Object[][]{ - {"2009-11-01-01 10:50:01"}, - {"aaaa-11-01-01 10:50"}, - {"aaaa-11-01 10:50"}, - {"1961--30 00:00:00"}, - {"--30 00:00:00"}, - {"-- 00:00:00"}, - {"1961-1- 00:00:00"}, - {"2009-11-01"}, - {"10:50:01"}, - {"1961-a-30 00:00:00"}, - {"1961-01-bb 00:00:00"}, - {"1961-08-30 00:00:00."}, - {"1961-08-30 :00:00"}, - {"1961-08-30 00::00"}, - {"1961-08-30 00:00:"}, - {"1961-08-30 ::"}, - {"1961-08-30 0a:00:00"}, - {"1961-08-30 00:bb:00"}, - {"1961-08-30 00:01:cc"}, - {"1961-08-30 00:00:00.01a"}, - {"1961-08-30 00:00:00.a"}, - {"1996-12-10 12:26:19.1234567890"}, - {null} - }; + private Stream invalidTimestampValues() { + return Stream.of( + "2009-11-01-01 10:50:01", + "aaaa-11-01-01 10:50", + "aaaa-11-01 10:50", + "1961--30 00:00:00", + "--30 00:00:00", + "-- 00:00:00", + "1961-1- 00:00:00", + "2009-11-01", + "10:50:01", + "1961-a-30 00:00:00", + "1961-01-bb 00:00:00", + "1961-08-30 00:00:00.", + "1961-08-30 :00:00", + "1961-08-30 00::00", + "1961-08-30 00:00:", + "1961-08-30 ::", + "1961-08-30 0a:00:00", + "1961-08-30 00:bb:00", + "1961-08-30 00:01:cc", + "1961-08-30 00:00:00.01a", + "1961-08-30 00:00:00.a", + "1996-12-10 12:26:19.1234567890", + null + ); } /* @@ -744,67 +751,65 @@ public class TimestampTests extends BaseTest { * to validate that an IllegalArgumentException will not be thrown from the * valueOf method and the corect value from toString() is returned */ - @DataProvider(name = "validTimestampValues") - private Object[][] validTimestampValues() { - return new Object[][]{ - {"1961-08-30 00:00:00", "1961-08-30 00:00:00.0"}, - {"1961-08-30 11:22:33", "1961-08-30 11:22:33.0"}, - {"1961-8-30 00:00:00", "1961-08-30 00:00:00.0"}, - {"1966-08-1 00:00:00", "1966-08-01 00:00:00.0"}, - {"1996-12-10 12:26:19.1", "1996-12-10 12:26:19.1"}, - {"1996-12-10 12:26:19.12", "1996-12-10 12:26:19.12"}, - {"1996-12-10 12:26:19.123", "1996-12-10 12:26:19.123"}, - {"1996-12-10 12:26:19.1234", "1996-12-10 12:26:19.1234"}, - {"1996-12-10 12:26:19.12345", "1996-12-10 12:26:19.12345"}, - {"1996-12-10 12:26:19.123456", "1996-12-10 12:26:19.123456"}, - {"1996-12-10 12:26:19.1234567", "1996-12-10 12:26:19.1234567"}, - {"1996-12-10 12:26:19.12345678", "1996-12-10 12:26:19.12345678"}, - {"1996-12-10 12:26:19.123456789", "1996-12-10 12:26:19.123456789"}, - {"1996-12-10 12:26:19.000000001", "1996-12-10 12:26:19.000000001"}, - {"1996-12-10 12:26:19.000000012", "1996-12-10 12:26:19.000000012"}, - {"1996-12-10 12:26:19.000000123", "1996-12-10 12:26:19.000000123"}, - {"1996-12-10 12:26:19.000001234", "1996-12-10 12:26:19.000001234"}, - {"1996-12-10 12:26:19.000012345", "1996-12-10 12:26:19.000012345"}, - {"1996-12-10 12:26:19.000123456", "1996-12-10 12:26:19.000123456"}, - {"1996-12-10 12:26:19.001234567", "1996-12-10 12:26:19.001234567"}, - {"1996-12-10 12:26:19.12345678", "1996-12-10 12:26:19.12345678"}, - {"1996-12-10 12:26:19.0", "1996-12-10 12:26:19.0"}, - {"1996-12-10 12:26:19.01230", "1996-12-10 12:26:19.0123"} - }; + private Stream validTimestampValues() { + return Stream.of( + Arguments.of("1961-08-30 00:00:00", "1961-08-30 00:00:00.0"), + Arguments.of("1961-08-30 11:22:33", "1961-08-30 11:22:33.0"), + Arguments.of("1961-8-30 00:00:00", "1961-08-30 00:00:00.0"), + Arguments.of("1966-08-1 00:00:00", "1966-08-01 00:00:00.0"), + Arguments.of("1996-12-10 12:26:19.1", "1996-12-10 12:26:19.1"), + Arguments.of("1996-12-10 12:26:19.12", "1996-12-10 12:26:19.12"), + Arguments.of("1996-12-10 12:26:19.123", "1996-12-10 12:26:19.123"), + Arguments.of("1996-12-10 12:26:19.1234", "1996-12-10 12:26:19.1234"), + Arguments.of("1996-12-10 12:26:19.12345", "1996-12-10 12:26:19.12345"), + Arguments.of("1996-12-10 12:26:19.123456", "1996-12-10 12:26:19.123456"), + Arguments.of("1996-12-10 12:26:19.1234567", "1996-12-10 12:26:19.1234567"), + Arguments.of("1996-12-10 12:26:19.12345678", "1996-12-10 12:26:19.12345678"), + Arguments.of("1996-12-10 12:26:19.123456789", "1996-12-10 12:26:19.123456789"), + Arguments.of("1996-12-10 12:26:19.000000001", "1996-12-10 12:26:19.000000001"), + Arguments.of("1996-12-10 12:26:19.000000012", "1996-12-10 12:26:19.000000012"), + Arguments.of("1996-12-10 12:26:19.000000123", "1996-12-10 12:26:19.000000123"), + Arguments.of("1996-12-10 12:26:19.000001234", "1996-12-10 12:26:19.000001234"), + Arguments.of("1996-12-10 12:26:19.000012345", "1996-12-10 12:26:19.000012345"), + Arguments.of("1996-12-10 12:26:19.000123456", "1996-12-10 12:26:19.000123456"), + Arguments.of("1996-12-10 12:26:19.001234567", "1996-12-10 12:26:19.001234567"), + Arguments.of("1996-12-10 12:26:19.12345678", "1996-12-10 12:26:19.12345678"), + Arguments.of("1996-12-10 12:26:19.0", "1996-12-10 12:26:19.0"), + Arguments.of("1996-12-10 12:26:19.01230", "1996-12-10 12:26:19.0123") + ); } - @DataProvider(name = "validTimestampLongValues") - private Object[][] validTimestampLongValues() { - return new Object[][]{ - {1L, "1970-01-01 01:00:00.001"}, - {-3600*1000L - 1, "1969-12-31 23:59:59.999"}, - {-(20000L*365*24*60*60*1000), "18018-08-28 01:00:00.0"}, - {Timestamp.valueOf("1961-08-30 11:22:33").getTime(), "1961-08-30 11:22:33.0"}, - {Timestamp.valueOf("1961-08-30 11:22:33.54321000").getTime(), "1961-08-30 11:22:33.543"}, // nanoprecision lost - {new Timestamp(114, 10, 10, 10, 10, 10, 100000000).getTime(), "2014-11-10 10:10:10.1"}, - {new Timestamp(0, 10, 10, 10, 10, 10, 100000).getTime(), "1900-11-10 10:10:10.0"}, // nanoprecision lost - {new Date(114, 10, 10).getTime(), "2014-11-10 00:00:00.0"}, - {new Date(0, 10, 10).getTime(), "1900-11-10 00:00:00.0"}, - {LocalDateTime.of(1960, 10, 10, 10, 10, 10, 50000).atZone(ZoneId.of("America/Los_Angeles")) - .toInstant().toEpochMilli(), "1960-10-10 19:10:10.0"}, + private Stream validTimestampLongValues() { + return Stream.of( + Arguments.of(1L, "1970-01-01 01:00:00.001"), + Arguments.of(-3600*1000L - 1, "1969-12-31 23:59:59.999"), + Arguments.of(-(20000L*365*24*60*60*1000), "18018-08-28 01:00:00.0"), + Arguments.of(Timestamp.valueOf("1961-08-30 11:22:33").getTime(), "1961-08-30 11:22:33.0"), + Arguments.of(Timestamp.valueOf("1961-08-30 11:22:33.54321000").getTime(), "1961-08-30 11:22:33.543"), // nanoprecision lost + Arguments.of(new Timestamp(114, 10, 10, 10, 10, 10, 100000000).getTime(), "2014-11-10 10:10:10.1"), + Arguments.of(new Timestamp(0, 10, 10, 10, 10, 10, 100000).getTime(), "1900-11-10 10:10:10.0"), // nanoprecision lost + Arguments.of(new Date(114, 10, 10).getTime(), "2014-11-10 00:00:00.0"), + Arguments.of(new Date(0, 10, 10).getTime(), "1900-11-10 00:00:00.0"), + Arguments.of(LocalDateTime.of(1960, 10, 10, 10, 10, 10, 50000).atZone(ZoneId.of("America/Los_Angeles")) + .toInstant().toEpochMilli(), "1960-10-10 19:10:10.0"), // millisecond timestamps wraps around at year 1, so Long.MIN_VALUE looks similar // Long.MAX_VALUE, while actually representing 292278994 BCE - {Long.MIN_VALUE, "292278994-08-17 08:12:55.192"}, - {Long.MAX_VALUE + 1, "292278994-08-17 08:12:55.192"}, - {Long.MAX_VALUE, "292278994-08-17 08:12:55.807"}, - {Long.MIN_VALUE - 1, "292278994-08-17 08:12:55.807"}, + Arguments.of(Long.MIN_VALUE, "292278994-08-17 08:12:55.192"), + Arguments.of(Long.MAX_VALUE + 1, "292278994-08-17 08:12:55.192"), + Arguments.of(Long.MAX_VALUE, "292278994-08-17 08:12:55.807"), + Arguments.of(Long.MIN_VALUE - 1, "292278994-08-17 08:12:55.807"), // wrap around point near 0001-01-01, test that we never get a negative year: - {-(1970L*365*24*60*60*1000), "0001-04-25 01:00:00.0"}, - {-(1970L*365*24*60*60*1000 + 115*24*60*60*1000L), "0001-12-31 01:00:00.0"}, - {-(1970L*365*24*60*60*1000 + 115*24*60*60*1000L - 23*60*60*1000L), "0001-01-01 00:00:00.0"}, + Arguments.of(-(1970L*365*24*60*60*1000), "0001-04-25 01:00:00.0"), + Arguments.of(-(1970L*365*24*60*60*1000 + 115*24*60*60*1000L), "0001-12-31 01:00:00.0"), + Arguments.of(-(1970L*365*24*60*60*1000 + 115*24*60*60*1000L - 23*60*60*1000L), "0001-01-01 00:00:00.0"), - {LocalDateTime.of(0, 1, 1, 10, 10, 10, 50000).atZone(ZoneId.of("America/Los_Angeles")) - .toInstant().toEpochMilli() - 2*24*60*60*1000L, "0001-01-01 19:03:08.0"}, // 1 BCE - {LocalDateTime.of(0, 1, 1, 10, 10, 10, 50000).atZone(ZoneId.of("America/Los_Angeles")) - .toInstant().toEpochMilli() - 3*24*60*60*1000L, "0002-12-31 19:03:08.0"} // 2 BCE - }; + Arguments.of(LocalDateTime.of(0, 1, 1, 10, 10, 10, 50000).atZone(ZoneId.of("America/Los_Angeles")) + .toInstant().toEpochMilli() - 2*24*60*60*1000L, "0001-01-01 19:03:08.0"), // 1 BCE + Arguments.of(LocalDateTime.of(0, 1, 1, 10, 10, 10, 50000).atZone(ZoneId.of("America/Los_Angeles")) + .toInstant().toEpochMilli() - 3*24*60*60*1000L, "0002-12-31 19:03:08.0") // 2 BCE + ); } /* @@ -812,29 +817,28 @@ public class TimestampTests extends BaseTest { * validate that the correct Nanos value is generated from the specified * Timestamp */ - @DataProvider(name = "validateNanos") - private Object[][] validateNanos() { - return new Object[][]{ - {"1961-08-30 00:00:00", 0}, - {"1996-12-10 12:26:19.1", 100000000}, - {"1996-12-10 12:26:19.12", 120000000}, - {"1996-12-10 12:26:19.123", 123000000}, - {"1996-12-10 12:26:19.1234", 123400000}, - {"1996-12-10 12:26:19.12345", 123450000}, - {"1996-12-10 12:26:19.123456", 123456000}, - {"1996-12-10 12:26:19.1234567", 123456700}, - {"1996-12-10 12:26:19.12345678", 123456780}, - {"1996-12-10 12:26:19.123456789", 123456789}, - {"1996-12-10 12:26:19.000000001", 1}, - {"1996-12-10 12:26:19.000000012", 12}, - {"1996-12-10 12:26:19.000000123", 123}, - {"1996-12-10 12:26:19.000001234", 1234}, - {"1996-12-10 12:26:19.000012345", 12345}, - {"1996-12-10 12:26:19.000123456", 123456}, - {"1996-12-10 12:26:19.001234567", 1234567}, - {"1996-12-10 12:26:19.012345678", 12345678}, - {"1996-12-10 12:26:19.0", 0}, - {"1996-12-10 12:26:19.01230", 12300000} - }; + private Stream validateNanos() { + return Stream.of( + Arguments.of("1961-08-30 00:00:00", 0), + Arguments.of("1996-12-10 12:26:19.1", 100000000), + Arguments.of("1996-12-10 12:26:19.12", 120000000), + Arguments.of("1996-12-10 12:26:19.123", 123000000), + Arguments.of("1996-12-10 12:26:19.1234", 123400000), + Arguments.of("1996-12-10 12:26:19.12345", 123450000), + Arguments.of("1996-12-10 12:26:19.123456", 123456000), + Arguments.of("1996-12-10 12:26:19.1234567", 123456700), + Arguments.of("1996-12-10 12:26:19.12345678", 123456780), + Arguments.of("1996-12-10 12:26:19.123456789", 123456789), + Arguments.of("1996-12-10 12:26:19.000000001", 1), + Arguments.of("1996-12-10 12:26:19.000000012", 12), + Arguments.of("1996-12-10 12:26:19.000000123", 123), + Arguments.of("1996-12-10 12:26:19.000001234", 1234), + Arguments.of("1996-12-10 12:26:19.000012345", 12345), + Arguments.of("1996-12-10 12:26:19.000123456", 123456), + Arguments.of("1996-12-10 12:26:19.001234567", 1234567), + Arguments.of("1996-12-10 12:26:19.012345678", 12345678), + Arguments.of("1996-12-10 12:26:19.0", 0), + Arguments.of("1996-12-10 12:26:19.01230", 12300000) + ); } } diff --git a/test/jdk/java/sql/testng/test/sql/othervm/DriverManagerInitTests.java b/test/jdk/java/sql/test/sql/drivermanager/DriverManagerInitTests.java similarity index 93% rename from test/jdk/java/sql/testng/test/sql/othervm/DriverManagerInitTests.java rename to test/jdk/java/sql/test/sql/drivermanager/DriverManagerInitTests.java index d2570993533..f77fde4b166 100644 --- a/test/jdk/java/sql/testng/test/sql/othervm/DriverManagerInitTests.java +++ b/test/jdk/java/sql/test/sql/drivermanager/DriverManagerInitTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package test.sql.othervm; +package sql.drivermanager; import java.io.BufferedReader; import java.io.CharArrayReader; @@ -33,8 +33,8 @@ import java.util.Enumeration; import java.util.logging.Level; import java.util.logging.Logger; -import static org.testng.Assert.*; -import org.testng.annotations.Test; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; public class DriverManagerInitTests { diff --git a/test/jdk/java/sql/driverModuleTests/DriverManagerModuleTests.java b/test/jdk/java/sql/test/sql/drivermanager/DriverManagerModuleTests.java similarity index 84% rename from test/jdk/java/sql/driverModuleTests/DriverManagerModuleTests.java rename to test/jdk/java/sql/test/sql/drivermanager/DriverManagerModuleTests.java index aad39cdb1dd..083153ac38f 100644 --- a/test/jdk/java/sql/driverModuleTests/DriverManagerModuleTests.java +++ b/test/jdk/java/sql/test/sql/drivermanager/DriverManagerModuleTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,23 +20,19 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ +package sql.drivermanager; import java.sql.Connection; import java.sql.Driver; import java.sql.DriverManager; import java.sql.SQLException; -import static org.testng.Assert.*; -import org.testng.annotations.AfterClass; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; /* * @test - * @library /java/sql/modules * @build luckydogdriver/* mystubdriver/* - * @run testng/othervm DriverManagerModuleTests * @summary Tests that a JDBC Driver that is a module can be loaded * via the service-provider loading mechanism. */ @@ -46,28 +42,12 @@ public class DriverManagerModuleTests { private static final String STUBDRIVERURL = "jdbc:stub:myDB"; private static final String CONNECTION_CLASS_NAME = "com.luckydogtennis.StubConnection"; - @BeforeClass - public static void setUpClass() throws Exception { - } - - @AfterClass - public static void tearDownClass() throws Exception { - } - - @BeforeMethod - public void setUpMethod() throws Exception { - } - - @AfterMethod - public void tearDownMethod() throws Exception { - } - /** * Validate JDBC drivers as modules will be accessible. One driver will be * loaded and registered via the service-provider loading mechanism. The * other driver will need to be explictly loaded * - * @throws java.lang.Exception + * @throws Exception */ @Test public void test() throws Exception { @@ -101,7 +81,7 @@ public class DriverManagerModuleTests { * Validate that a Connection can be obtained from a JDBC driver which is a * module and loaded via the service-provider loading mechanism. * - * @throws java.lang.Exception + * @throws Exception */ @Test public void test00() throws Exception { diff --git a/test/jdk/java/sql/test/sql/drivermanager/TEST.properties b/test/jdk/java/sql/test/sql/drivermanager/TEST.properties new file mode 100644 index 00000000000..0fed686adad --- /dev/null +++ b/test/jdk/java/sql/test/sql/drivermanager/TEST.properties @@ -0,0 +1,4 @@ +# drivermanager tests are run in othervm +othervm.dirs = . +# Required by DriverManagerModuleTests.java +lib.dirs = /java/sql/modules diff --git a/test/jdk/java/sql/testng/TEST.properties b/test/jdk/java/sql/testng/TEST.properties deleted file mode 100644 index 66b1566374a..00000000000 --- a/test/jdk/java/sql/testng/TEST.properties +++ /dev/null @@ -1,4 +0,0 @@ -# JDBC unit tests uses TestNG -TestNG.dirs = . -othervm.dirs = test/sql/othervm - diff --git a/test/jdk/java/sql/testng/util/BaseTest.java b/test/jdk/java/sql/util/BaseTest.java similarity index 54% rename from test/jdk/java/sql/testng/util/BaseTest.java rename to test/jdk/java/sql/util/BaseTest.java index 8751183726d..1a1b14e795a 100644 --- a/test/jdk/java/sql/testng/util/BaseTest.java +++ b/test/jdk/java/sql/util/BaseTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * 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,9 +29,12 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.sql.JDBCType; import java.sql.SQLException; +import java.util.stream.Stream; -import org.testng.annotations.DataProvider; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.provider.Arguments; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class BaseTest { protected final String reason = "reason"; @@ -73,29 +76,11 @@ public class BaseTest { return o1; } - /* - * DataProvider used to specify the value to set and check for - * methods using boolean values - */ - @DataProvider(name = "trueFalse") - protected Object[][] trueFalse() { - return new Object[][]{ - {true}, - {false} - }; - } - /* * DataProvider used to specify the standard JDBC Types */ - @DataProvider(name = "jdbcTypes") - protected Object[][] jdbcTypes() { - Object[][] o = new Object[JDBCType.values().length][1]; - int pos = 0; - for (JDBCType c : JDBCType.values()) { - o[pos++][0] = c.getVendorTypeNumber(); - } - return o; + protected Stream jdbcTypes() { + return Stream.of(JDBCType.values()).map(JDBCType::getVendorTypeNumber); } /* @@ -103,15 +88,14 @@ public class BaseTest { * that enquoteLiteral converts a string to a literal and every instance of * a single quote will be converted into two single quotes in the literal. */ - @DataProvider(name = "validEnquotedLiteralValues") - protected Object[][] validEnquotedLiteralValues() { - return new Object[][]{ - {"Hello", "'Hello'"}, - {"G'Day", "'G''Day'"}, - {"'G''Day'", "'''G''''Day'''"}, - {"I'''M", "'I''''''M'"}, - {"The Dark Knight", "'The Dark Knight'"}, - }; + protected Stream validEnquotedLiteralValues() { + return Stream.of( + Arguments.of("Hello", "'Hello'"), + Arguments.of("G'Day", "'G''Day'"), + Arguments.of("'G''Day'", "'''G''''Day'''"), + Arguments.of("I'''M", "'I''''''M'"), + Arguments.of("The Dark Knight", "'The Dark Knight'") + ); } /* @@ -119,37 +103,37 @@ public class BaseTest { * that enqouteIdentifier returns a simple SQL Identifier or a * quoted identifier */ - @DataProvider(name = "validIdentifierValues") - protected Object[][] validEnquotedIdentifierValues() { - return new Object[][]{ - {"b", false, "b"}, - {"b", true, "\"b\""}, - {MAX_LENGTH_IDENTIFIER, false, MAX_LENGTH_IDENTIFIER}, - {MAX_LENGTH_IDENTIFIER, true, "\"" + MAX_LENGTH_IDENTIFIER + "\""}, - {"Hello", false, "Hello"}, - {"Hello", true, "\"Hello\""}, - {"G'Day", false, "\"G'Day\""}, - {"G'Day", true, "\"G'Day\""}, - {"Bruce Wayne", false, "\"Bruce Wayne\""}, - {"Bruce Wayne", true, "\"Bruce Wayne\""}, - {"select", false, "\"select\""}, - {"table", true, "\"table\""}, - {"GoodDay$", false, "\"GoodDay$\""}, - {"GoodDay$", true, "\"GoodDay$\""},}; + protected Stream validEnquotedIdentifierValues() { + return Stream.of( + Arguments.of("b", false, "b"), + Arguments.of("b", true, "\"b\""), + Arguments.of(MAX_LENGTH_IDENTIFIER, false, MAX_LENGTH_IDENTIFIER), + Arguments.of(MAX_LENGTH_IDENTIFIER, true, "\"" + MAX_LENGTH_IDENTIFIER + "\""), + Arguments.of("Hello", false, "Hello"), + Arguments.of("Hello", true, "\"Hello\""), + Arguments.of("G'Day", false, "\"G'Day\""), + Arguments.of("G'Day", true, "\"G'Day\""), + Arguments.of("Bruce Wayne", false, "\"Bruce Wayne\""), + Arguments.of("Bruce Wayne", true, "\"Bruce Wayne\""), + Arguments.of("select", false, "\"select\""), + Arguments.of("table", true, "\"table\""), + Arguments.of("GoodDay$", false, "\"GoodDay$\""), + Arguments.of("GoodDay$", true, "\"GoodDay$\"") + ); } /* * DataProvider used to provide strings are invalid for enquoteIdentifier * resulting in a SQLException being thrown */ - @DataProvider(name = "invalidIdentifierValues") - protected Object[][] invalidEnquotedIdentifierValues() { - return new Object[][]{ - {"Hel\"lo", false}, - {"\"Hel\"lo\"", true}, - {"Hello" + '\0', false}, - {"", false}, - {MAX_LENGTH_IDENTIFIER + 'a', false},}; + protected Stream invalidEnquotedIdentifierValues() { + return Stream.of( + Arguments.of("Hel\"lo", false), + Arguments.of("\"Hel\"lo\"", true), + Arguments.of("Hello" + '\0', false), + Arguments.of("", false), + Arguments.of(MAX_LENGTH_IDENTIFIER + 'a', false) + ); } /* @@ -157,22 +141,21 @@ public class BaseTest { * that isSimpleIdentifier returns the correct value based on the * identifier specified. */ - @DataProvider(name = "simpleIdentifierValues") - protected Object[][] simpleIdentifierValues() { - return new Object[][]{ - {"b", true}, - {"Hello", true}, - {"\"Gotham\"", false}, - {"G'Day", false}, - {"Bruce Wayne", false}, - {"GoodDay$", false}, - {"Dick_Grayson", true}, - {"Batmobile1966", true}, - {MAX_LENGTH_IDENTIFIER, true}, - {MAX_LENGTH_IDENTIFIER + 'a', false}, - {"", false}, - {"select", false} - }; + protected Stream simpleIdentifierValues() { + return Stream.of( + Arguments.of("b", true), + Arguments.of("Hello", true), + Arguments.of("\"Gotham\"", false), + Arguments.of("G'Day", false), + Arguments.of("Bruce Wayne", false), + Arguments.of("GoodDay$", false), + Arguments.of("Dick_Grayson", true), + Arguments.of("Batmobile1966", true), + Arguments.of(MAX_LENGTH_IDENTIFIER, true), + Arguments.of(MAX_LENGTH_IDENTIFIER + 'a', false), + Arguments.of("", false), + Arguments.of("select", false) + ); } /* @@ -181,15 +164,14 @@ public class BaseTest { * literal and every instance of * a single quote will be converted into two single quotes in the literal. */ - @DataProvider(name = "validEnquotedNCharLiteralValues") - protected Object[][] validEnquotedNCharLiteralValues() { - return new Object[][]{ - {"Hello", "N'Hello'"}, - {"G'Day", "N'G''Day'"}, - {"'G''Day'", "N'''G''''Day'''"}, - {"I'''M", "N'I''''''M'"}, - {"N'Hello'", "N'N''Hello'''"}, - {"The Dark Knight", "N'The Dark Knight'"} - }; + protected Stream validEnquotedNCharLiteralValues() { + return Stream.of( + Arguments.of("Hello", "N'Hello'"), + Arguments.of("G'Day", "N'G''Day'"), + Arguments.of("'G''Day'", "N'''G''''Day'''"), + Arguments.of("I'''M", "N'I''''''M'"), + Arguments.of("N'Hello'", "N'N''Hello'''"), + Arguments.of("The Dark Knight", "N'The Dark Knight'") + ); } } diff --git a/test/jdk/java/sql/testng/util/DriverActionImpl.java b/test/jdk/java/sql/util/DriverActionImpl.java similarity index 94% rename from test/jdk/java/sql/testng/util/DriverActionImpl.java rename to test/jdk/java/sql/util/DriverActionImpl.java index 4a286ad8f3c..48fed8086a7 100644 --- a/test/jdk/java/sql/testng/util/DriverActionImpl.java +++ b/test/jdk/java/sql/util/DriverActionImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/java/sql/testng/util/SerializedBatchUpdateException.java b/test/jdk/java/sql/util/SerializedBatchUpdateException.java similarity index 99% rename from test/jdk/java/sql/testng/util/SerializedBatchUpdateException.java rename to test/jdk/java/sql/util/SerializedBatchUpdateException.java index 00efc5275a7..08473e6a184 100644 --- a/test/jdk/java/sql/testng/util/SerializedBatchUpdateException.java +++ b/test/jdk/java/sql/util/SerializedBatchUpdateException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/java/sql/testng/util/StubCallableStatement.java b/test/jdk/java/sql/util/StubCallableStatement.java similarity index 99% rename from test/jdk/java/sql/testng/util/StubCallableStatement.java rename to test/jdk/java/sql/util/StubCallableStatement.java index 4a7c27314bb..4700699c4ba 100644 --- a/test/jdk/java/sql/testng/util/StubCallableStatement.java +++ b/test/jdk/java/sql/util/StubCallableStatement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/java/sql/testng/util/StubConnection.java b/test/jdk/java/sql/util/StubConnection.java similarity index 99% rename from test/jdk/java/sql/testng/util/StubConnection.java rename to test/jdk/java/sql/util/StubConnection.java index cd013572adc..e1a60efc323 100644 --- a/test/jdk/java/sql/testng/util/StubConnection.java +++ b/test/jdk/java/sql/util/StubConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/java/sql/testng/util/StubDatabaseMetaData.java b/test/jdk/java/sql/util/StubDatabaseMetaData.java similarity index 99% rename from test/jdk/java/sql/testng/util/StubDatabaseMetaData.java rename to test/jdk/java/sql/util/StubDatabaseMetaData.java index 3bf70afaa8f..3c95ac94793 100644 --- a/test/jdk/java/sql/testng/util/StubDatabaseMetaData.java +++ b/test/jdk/java/sql/util/StubDatabaseMetaData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/java/sql/testng/util/StubDriver.java b/test/jdk/java/sql/util/StubDriver.java similarity index 96% rename from test/jdk/java/sql/testng/util/StubDriver.java rename to test/jdk/java/sql/util/StubDriver.java index 12253080377..c45b9ec9919 100644 --- a/test/jdk/java/sql/testng/util/StubDriver.java +++ b/test/jdk/java/sql/util/StubDriver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/java/sql/testng/util/StubDriverDA.java b/test/jdk/java/sql/util/StubDriverDA.java similarity index 96% rename from test/jdk/java/sql/testng/util/StubDriverDA.java rename to test/jdk/java/sql/util/StubDriverDA.java index 5b23f0846d8..f134a9d28cf 100644 --- a/test/jdk/java/sql/testng/util/StubDriverDA.java +++ b/test/jdk/java/sql/util/StubDriverDA.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/java/sql/testng/util/StubPreparedStatement.java b/test/jdk/java/sql/util/StubPreparedStatement.java similarity index 99% rename from test/jdk/java/sql/testng/util/StubPreparedStatement.java rename to test/jdk/java/sql/util/StubPreparedStatement.java index a3b95a65f4e..fdb90df4797 100644 --- a/test/jdk/java/sql/testng/util/StubPreparedStatement.java +++ b/test/jdk/java/sql/util/StubPreparedStatement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/java/sql/testng/util/StubStatement.java b/test/jdk/java/sql/util/StubStatement.java similarity index 99% rename from test/jdk/java/sql/testng/util/StubStatement.java rename to test/jdk/java/sql/util/StubStatement.java index c8f6a3ac071..00ed6268856 100644 --- a/test/jdk/java/sql/testng/util/StubStatement.java +++ b/test/jdk/java/sql/util/StubStatement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/java/time/tck/java/time/TCKOffsetTime.java b/test/jdk/java/time/tck/java/time/TCKOffsetTime.java index 7ea9504edbc..8aab9f53977 100644 --- a/test/jdk/java/time/tck/java/time/TCKOffsetTime.java +++ b/test/jdk/java/time/tck/java/time/TCKOffsetTime.java @@ -421,7 +421,6 @@ public class TCKOffsetTime extends AbstractDateTimeTest { {"00;00"}, {"12-00"}, {"-01:00"}, - {"00:00:00-09"}, {"00:00:00,09"}, {"00:00:abs"}, {"11"}, @@ -436,6 +435,11 @@ public class TCKOffsetTime extends AbstractDateTimeTest { Assertions.assertThrows(DateTimeParseException.class, () -> OffsetTime.parse(unparsable)); } + @Test + public void factory_parse_hourOnlyOffset() { + Assertions.assertDoesNotThrow(() -> OffsetTime.parse("00:00:00-09")); + } + //-----------------------------------------------------------------------s @Test public void factory_parse_illegalHour() { diff --git a/test/jdk/java/time/test/java/time/format/TestDateTimeFormatter.java b/test/jdk/java/time/test/java/time/format/TestDateTimeFormatter.java index 2ccc0da8f58..d6c73f6bc74 100644 --- a/test/jdk/java/time/test/java/time/format/TestDateTimeFormatter.java +++ b/test/jdk/java/time/test/java/time/format/TestDateTimeFormatter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,6 +59,7 @@ */ package test.java.time.format; +import static java.time.format.DateTimeFormatter.*; import static java.time.temporal.ChronoField.DAY_OF_MONTH; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -93,15 +94,19 @@ import java.time.temporal.Temporal; import java.time.temporal.TemporalAccessor; import java.util.Locale; import java.util.function.Function; +import java.util.stream.Stream; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import static org.junit.jupiter.api.Assertions.assertEquals; + /** * Test DateTimeFormatter. - * @bug 8085887 8293146 + * @bug 8085887 8293146 8210336 */ @TestInstance(TestInstance.Lifecycle.PER_CLASS) public class TestDateTimeFormatter { @@ -333,4 +338,49 @@ public class TestDateTimeFormatter { assertThrows(DateTimeException.class, () -> LocalDate.parse(weekDate, f)); } } + + private static Stream data_iso_short_offset_parse() { + return Stream.of( + Arguments.of("20260123-01", BASIC_ISO_DATE, "20260123-0100"), + Arguments.of("20260123+00", BASIC_ISO_DATE, "20260123Z"), + Arguments.of("20260123-00", BASIC_ISO_DATE, "20260123Z"), + Arguments.of("2026-01-23-01", ISO_DATE, "2026-01-23-01:00"), + Arguments.of("2026-01-23+00", ISO_DATE, "2026-01-23Z"), + Arguments.of("2026-01-23-00", ISO_DATE, "2026-01-23Z"), + Arguments.of("2026-01-23T11:30:59-01", ISO_DATE_TIME, "2026-01-23T11:30:59-01:00"), + Arguments.of("2026-01-23T11:30:59+00", ISO_DATE_TIME, "2026-01-23T11:30:59Z"), + Arguments.of("2026-01-23T11:30:59-00", ISO_DATE_TIME, "2026-01-23T11:30:59Z"), + Arguments.of("11:30:59-01", ISO_TIME, "11:30:59-01:00"), + Arguments.of("11:30:59+00", ISO_TIME, "11:30:59Z"), + Arguments.of("11:30:59-00", ISO_TIME, "11:30:59Z"), + Arguments.of("2026-01-23-01", ISO_OFFSET_DATE, "2026-01-23-01:00"), + Arguments.of("2026-01-23+00", ISO_OFFSET_DATE, "2026-01-23Z"), + Arguments.of("2026-01-23-00", ISO_OFFSET_DATE, "2026-01-23Z"), + Arguments.of("2026-01-23T11:30:59-01", ISO_OFFSET_DATE_TIME, "2026-01-23T11:30:59-01:00"), + Arguments.of("2026-01-23T11:30:59+00", ISO_OFFSET_DATE_TIME, "2026-01-23T11:30:59Z"), + Arguments.of("2026-01-23T11:30:59-00", ISO_OFFSET_DATE_TIME, "2026-01-23T11:30:59Z"), + Arguments.of("11:30:59-01", ISO_OFFSET_TIME, "11:30:59-01:00"), + Arguments.of("11:30:59+00", ISO_OFFSET_TIME, "11:30:59Z"), + Arguments.of("11:30:59-00", ISO_OFFSET_TIME, "11:30:59Z"), + Arguments.of("2026-023-01", ISO_ORDINAL_DATE, "2026-023-01:00"), + Arguments.of("2026-023+00", ISO_ORDINAL_DATE, "2026-023Z"), + Arguments.of("2026-023-00", ISO_ORDINAL_DATE, "2026-023Z"), + Arguments.of("2026-W04-5-01", ISO_WEEK_DATE, "2026-W04-5-01:00"), + Arguments.of("2026-W04-5+00", ISO_WEEK_DATE, "2026-W04-5Z"), + Arguments.of("2026-W04-5-00", ISO_WEEK_DATE, "2026-W04-5Z"), + Arguments.of("2026-01-23T11:30:59-01", ISO_ZONED_DATE_TIME, "2026-01-23T11:30:59-01:00"), + Arguments.of("2026-01-23T11:30:59+00", ISO_ZONED_DATE_TIME, "2026-01-23T11:30:59Z"), + Arguments.of("2026-01-23T11:30:59-00", ISO_ZONED_DATE_TIME, "2026-01-23T11:30:59Z"), + Arguments.of("2026-01-23T11:30:59-01", ISO_INSTANT, "2026-01-23T12:30:59Z"), + Arguments.of("2026-01-23T11:30:59+00", ISO_INSTANT, "2026-01-23T11:30:59Z"), + Arguments.of("2026-01-23T11:30:59-00", ISO_INSTANT, "2026-01-23T11:30:59Z") + ); + } + + // Checks if predefined ISO formatters can parse hour-only offsets + @ParameterizedTest + @MethodSource("data_iso_short_offset_parse") + public void test_iso_short_offset_parse(String text, DateTimeFormatter formatter, String expected) { + assertEquals(expected, formatter.format(formatter.parse(text))); + } } diff --git a/test/jdk/java/util/concurrent/ConcurrentHashMap/ConcurrentAssociateTest.java b/test/jdk/java/util/concurrent/ConcurrentHashMap/ConcurrentAssociateTest.java index e6afff5b329..014272a8f96 100644 --- a/test/jdk/java/util/concurrent/ConcurrentHashMap/ConcurrentAssociateTest.java +++ b/test/jdk/java/util/concurrent/ConcurrentHashMap/ConcurrentAssociateTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -171,13 +171,9 @@ public class ConcurrentAssociateTest { String lockName; if ("Signal Dispatcher".equals(name)) continue; - if ("Reference Handler".equals(name) - && (lockName = info.getLockName()) != null - && lockName.startsWith("java.lang.ref.Reference$Lock")) + if ("Reference Handler".equals(name)) continue; - if ("Finalizer".equals(name) - && (lockName = info.getLockName()) != null - && lockName.startsWith("java.lang.ref.ReferenceQueue$Lock")) + if ("Finalizer".equals(name)) continue; System.err.print(info); } diff --git a/test/jdk/java/util/concurrent/Phaser/Basic.java b/test/jdk/java/util/concurrent/Phaser/Basic.java index 2ea09dced99..500e106891b 100644 --- a/test/jdk/java/util/concurrent/Phaser/Basic.java +++ b/test/jdk/java/util/concurrent/Phaser/Basic.java @@ -434,11 +434,9 @@ public class Basic { String name = info.getThreadName(); if ("Signal Dispatcher".equals(name)) continue; - if ("Reference Handler".equals(name) - && info.getLockName().startsWith("java.lang.ref.Reference$Lock")) + if ("Reference Handler".equals(name)) continue; - if ("Finalizer".equals(name) - && info.getLockName().startsWith("java.lang.ref.ReferenceQueue$Lock")) + if ("Finalizer".equals(name)) continue; if (name.startsWith("process reaper")) continue; diff --git a/test/jdk/java/util/zip/CloseInflaterDeflaterTest.java b/test/jdk/java/util/zip/CloseInflaterDeflaterTest.java index af314581a9e..992d5b98fb9 100644 --- a/test/jdk/java/util/zip/CloseInflaterDeflaterTest.java +++ b/test/jdk/java/util/zip/CloseInflaterDeflaterTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,23 +25,29 @@ * @test * @bug 8193682 8278794 8284771 * @summary Test Infinite loop while writing on closed Deflater and Inflater. - * @run testng CloseInflaterDeflaterTest + * @run junit CloseInflaterDeflaterTest */ -import java.io.*; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.util.Random; import java.util.jar.JarOutputStream; +import java.util.stream.Stream; import java.util.zip.DeflaterInputStream; import java.util.zip.DeflaterOutputStream; import java.util.zip.GZIPOutputStream; import java.util.zip.InflaterOutputStream; -import java.util.zip.ZipOutputStream; import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; -import static org.testng.Assert.assertThrows; - +import static org.junit.jupiter.api.Assertions.assertThrows; public class CloseInflaterDeflaterTest { @@ -75,36 +81,28 @@ public class CloseInflaterDeflaterTest { private static Random rand = new Random(); /** - * DataProvider to specify whether to use close() or finish() of OutputStream + * MethodSource to specify whether to use close() or finish() of OutputStream * - * @return Entry object indicating which method to use for closing OutputStream + * @return Stream indicating which method to use for closing OutputStream */ - @DataProvider - public Object[][] testOutputStreams() { - return new Object[][] { - { true }, - { false }, - }; + public static Stream testOutputStreams() { + return Stream.of(true, false); } /** - * DataProvider to specify on which outputstream closeEntry() has to be called + * MethodSource to specify on which outputstream closeEntry() has to be called * - * @return Entry object returning either JarOutputStream or ZipOutputStream + * @return Stream consisting of either a JarOutputStream or ZipOutputStream */ - @DataProvider - public Object[][] testZipAndJar() throws IOException{ - return new Object[][] { - { new JarOutputStream(outStream)}, - { new ZipOutputStream(outStream)}, - }; + public static Stream testZipAndJar() throws IOException{ + return Stream.of(new JarOutputStream(outStream), new ZipOutputStream(outStream)); } /** * Add inputBytes array with random bytes to write into OutputStream */ - @BeforeTest - public void before_test() + @BeforeAll + public static void before_test() { rand.nextBytes(inputBytes); } @@ -115,7 +113,8 @@ public class CloseInflaterDeflaterTest { * @param useCloseMethod indicates whether to use Close() or finish() method * @throws IOException if an error occurs */ - @Test(dataProvider = "testOutputStreams") + @ParameterizedTest + @MethodSource("testOutputStreams") public void testGZip(boolean useCloseMethod) throws IOException { GZIPOutputStream gzip = new GZIPOutputStream(outStream); gzip.write(inputBytes, 0, INPUT_LENGTH); @@ -137,7 +136,8 @@ public class CloseInflaterDeflaterTest { * @param useCloseMethod indicates whether to use Close() or finish() method * @throws IOException if an error occurs */ - @Test(dataProvider = "testOutputStreams") + @ParameterizedTest + @MethodSource("testOutputStreams") public void testDeflaterOutputStream(boolean useCloseMethod) throws IOException { DeflaterOutputStream def = new DeflaterOutputStream(outStream); assertThrows(IOException.class , () -> def.write(inputBytes, 0, INPUT_LENGTH)); @@ -175,7 +175,9 @@ public class CloseInflaterDeflaterTest { * @param useCloseMethod indicates whether to use Close() or finish() method * @throws IOException if an error occurs */ - @Test(dataProvider = "testOutputStreams",enabled=false) + @Disabled + @ParameterizedTest + @MethodSource("testOutputStreams") public void testInflaterOutputStream(boolean useCloseMethod) throws IOException { InflaterOutputStream inf = new InflaterOutputStream(outStream); assertThrows(IOException.class , () -> inf.write(inputBytes, 0, INPUT_LENGTH)); @@ -197,7 +199,8 @@ public class CloseInflaterDeflaterTest { * @param zip will be the instance of either JarOutputStream or ZipOutputStream * @throws IOException if an error occurs */ - @Test(dataProvider = "testZipAndJar") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("testZipAndJar") public void testZipCloseEntry(ZipOutputStream zip) throws IOException { assertThrows(IOException.class , () -> zip.putNextEntry(new ZipEntry(""))); zip.write(inputBytes, 0, INPUT_LENGTH); diff --git a/test/jdk/java/util/zip/DeflaterDictionaryTests.java b/test/jdk/java/util/zip/DeflaterDictionaryTests.java index 570de5408ee..56d5ef24200 100644 --- a/test/jdk/java/util/zip/DeflaterDictionaryTests.java +++ b/test/jdk/java/util/zip/DeflaterDictionaryTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,23 +21,26 @@ * questions. */ -import org.testng.Assert; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; import java.nio.ByteBuffer; import java.util.Arrays; +import java.util.stream.IntStream; import java.util.zip.Deflater; import java.util.zip.Inflater; import static java.nio.charset.StandardCharsets.UTF_8; -import static org.testng.Assert.assertThrows; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; /** * @test * @bug 8252739 * @summary Verify Deflater.setDictionary(dictionary, offset, length) uses the offset - * @run testng/othervm DeflaterDictionaryTests + * @run junit/othervm DeflaterDictionaryTests */ public class DeflaterDictionaryTests { // Output buffer size @@ -50,31 +53,21 @@ public class DeflaterDictionaryTests { private static final int DICTIONARY_LENGTH = 3; /** - * DataProvider with offsets which should be valid for setDictionary + * MethodSource with offsets which should be valid for setDictionary * - * @return valid offset values + * @return Stream of valid offset values */ - @DataProvider(name = "validDictionaryOffsets") - protected Object[][] validDictionaryOffsets() { - return new Object[][]{ - {0}, - {DICTIONARY_OFFSET}, - {DICTIONARY_LENGTH} - }; + protected static IntStream validDictionaryOffsets() { + return IntStream.of(0, DICTIONARY_OFFSET, DICTIONARY_LENGTH); } /** - * DataProvider with invalid offsets for setDictionary + * MethodSource with invalid offsets for setDictionary * - * @return invalid offset values + * @return Stream of invalid offset values */ - @DataProvider(name = "invalidDictionaryOffsets") - protected Object[][] invalidDictionaryOffsets() { - return new Object[][]{ - {-1}, - {DICTIONARY_LENGTH + 2}, - {DICTIONARY.length()} - }; + protected static IntStream invalidDictionaryOffsets() { + return IntStream.of(-1, DICTIONARY_LENGTH + 2, DICTIONARY.length()); } /** @@ -83,7 +76,8 @@ public class DeflaterDictionaryTests { * @param dictionary_offset offset value to be used * @throws Exception if an error occurs */ - @Test(dataProvider = "validDictionaryOffsets") + @ParameterizedTest + @MethodSource("validDictionaryOffsets") public void testByteArray(int dictionary_offset) throws Exception { byte[] input = SRC_DATA.getBytes(UTF_8); byte[] output = new byte[RESULT_SIZE]; @@ -115,8 +109,8 @@ public class DeflaterDictionaryTests { System.out.printf("Inflater::getAdler:%d, length: %d%n", inflater.getAdler(), resultLength); - Assert.assertEquals(SRC_DATA.length(), resultLength); - Assert.assertEquals(input, Arrays.copyOf(result, resultLength)); + assertEquals(SRC_DATA.length(), resultLength); + assertArrayEquals(input, Arrays.copyOf(result, resultLength)); } finally { // Release Resources deflater.end(); @@ -163,8 +157,8 @@ public class DeflaterDictionaryTests { System.out.printf("Inflater::getAdler:%d, length: %d%n", inflater.getAdler(), resultLength); - Assert.assertEquals(SRC_DATA.length(), resultLength); - Assert.assertEquals(input, Arrays.copyOf(result, resultLength)); + assertEquals(resultLength, SRC_DATA.length()); + assertArrayEquals(Arrays.copyOf(result, resultLength), input); } finally { // Release Resources deflater.end(); @@ -217,8 +211,8 @@ public class DeflaterDictionaryTests { System.out.printf("Inflater::getAdler:%d, length: %d%n", inflater.getAdler(), resultLength); - Assert.assertEquals(SRC_DATA.length(), resultLength); - Assert.assertEquals(input, Arrays.copyOf(result, resultLength)); + assertEquals(resultLength, SRC_DATA.length()); + assertArrayEquals(Arrays.copyOf(result, resultLength), input); } finally { // Release Resources deflater.end(); @@ -232,7 +226,8 @@ public class DeflaterDictionaryTests { * * @param dictionary_offset offset value to be used */ - @Test(dataProvider = "invalidDictionaryOffsets") + @ParameterizedTest + @MethodSource("invalidDictionaryOffsets") public void testInvalidOffsets(int dictionary_offset) { byte[] dictionary = DICTIONARY.getBytes(UTF_8); diff --git a/test/jdk/java/util/zip/GZIP/GZIPOutputStreamHeaderTest.java b/test/jdk/java/util/zip/GZIP/GZIPOutputStreamHeaderTest.java index 93c2e91fea8..5fdad3d3b07 100644 --- a/test/jdk/java/util/zip/GZIP/GZIPOutputStreamHeaderTest.java +++ b/test/jdk/java/util/zip/GZIP/GZIPOutputStreamHeaderTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,8 +21,7 @@ * questions. */ -import org.testng.Assert; -import org.testng.annotations.Test; +import org.junit.jupiter.api.Test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -30,12 +29,15 @@ import java.nio.charset.StandardCharsets; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + /** * @test * @bug 8244706 * @summary Verify that the OS header flag in the stream written out by java.util.zip.GZIPOutputStream * has the correct expected value - * @run testng GZIPOutputStreamHeaderTest + * @run junit GZIPOutputStreamHeaderTest */ public class GZIPOutputStreamHeaderTest { @@ -54,8 +56,8 @@ public class GZIPOutputStreamHeaderTest { gzipOutputStream.write(data.getBytes(StandardCharsets.UTF_8)); } final byte[] compressed = baos.toByteArray(); - Assert.assertNotNull(compressed, "Compressed data is null"); - Assert.assertEquals(toUnsignedByte(compressed[OS_HEADER_INDEX]), HEADER_VALUE_OS_UNKNOWN, + assertNotNull(compressed, "Compressed data is null"); + assertEquals(HEADER_VALUE_OS_UNKNOWN, toUnsignedByte(compressed[OS_HEADER_INDEX]), "Unexpected value for OS header"); // finally verify that the compressed data is readable back to the original final String uncompressed; @@ -65,7 +67,7 @@ public class GZIPOutputStreamHeaderTest { gzipInputStream.transferTo(os); uncompressed = new String(os.toByteArray(), StandardCharsets.UTF_8); } - Assert.assertEquals(uncompressed, data, "Unexpected data read from GZIPInputStream"); + assertEquals(data, uncompressed, "Unexpected data read from GZIPInputStream"); } private static int toUnsignedByte(final byte b) { diff --git a/test/jdk/java/util/zip/ZipFile/GetInputStreamNPETest.java b/test/jdk/java/util/zip/ZipFile/GetInputStreamNPETest.java index ec7f0fc7d45..a4111ecef35 100644 --- a/test/jdk/java/util/zip/ZipFile/GetInputStreamNPETest.java +++ b/test/jdk/java/util/zip/ZipFile/GetInputStreamNPETest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,10 +22,12 @@ * */ -import org.testng.annotations.AfterTest; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import java.io.IOException; import java.nio.file.Files; @@ -34,16 +36,20 @@ import java.util.Arrays; import java.util.Formatter; import java.util.jar.JarEntry; import java.util.jar.JarFile; +import java.util.stream.Stream; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * @test * @bug 8280409 * @summary Validate that Zip/JarFile::getInputStream will throw a NullPointerException - * @run testng/othervm GetInputStreamNPETest + * @run junit/othervm GetInputStreamNPETest */ public class GetInputStreamNPETest { // Name used to create a JAR with an invalid entry name @@ -750,33 +756,31 @@ public class GetInputStreamNPETest { }; /** - * DataProvider used to specify valid jars and whether to verify them + * MethodSource used to specify valid jars and whether to verify them * - * @return Entry object indicating the jar file and whether it will be verified + * @return Stream of Arguments which indicate the jar file and whether it will be verified */ - @DataProvider - public Object[][] validJars() { - return new Object[][]{ - {SIGNED_VALID_ENTRY_NAME_JAR, true}, - {SIGNED_VALID_ENTRY_NAME_JAR, false}, - {VALID_ENTRY_NAME_JAR, true}, - {VALID_ENTRY_NAME_JAR, false}, - }; + public static Stream validJars() { + return Stream.of( + Arguments.of(SIGNED_VALID_ENTRY_NAME_JAR, true), + Arguments.of(SIGNED_VALID_ENTRY_NAME_JAR, false), + Arguments.of(VALID_ENTRY_NAME_JAR, true), + Arguments.of(VALID_ENTRY_NAME_JAR, false) + ); } /** - * DataProvider used to specify invalid jars and whether to verify them + * MethodSource used to specify invalid jars and whether to verify them * - * @return Entry object indicating the jar file and whether it will be verified + * @return Stream of Arguments which indicate the jar file and whether it will be verified */ - @DataProvider - public Object[][] inValidJars() { - return new Object[][]{ - {SIGNED_INVALID_ENTRY_NAME_JAR, true}, - {SIGNED_INVALID_ENTRY_NAME_JAR, false}, - {INVALID_ENTRY_NAME_JAR, true}, - {INVALID_ENTRY_NAME_JAR, false}, - }; + public static Stream inValidJars() { + return Stream.of( + Arguments.of(SIGNED_INVALID_ENTRY_NAME_JAR, true), + Arguments.of(SIGNED_INVALID_ENTRY_NAME_JAR, false), + Arguments.of(INVALID_ENTRY_NAME_JAR, true), + Arguments.of(INVALID_ENTRY_NAME_JAR, false) + ); } /** @@ -796,7 +800,7 @@ public class GetInputStreamNPETest { * @throws IOException If an error occurs * */ - @BeforeTest + @BeforeAll public static void setup() throws IOException { // Create valid jar @@ -832,7 +836,7 @@ public class GetInputStreamNPETest { * * @throws IOException If an error occurs */ - @AfterTest + @AfterAll public static void cleanup() throws IOException { Files.deleteIfExists(VALID_ENTRY_NAME_JAR); Files.deleteIfExists(SIGNED_VALID_ENTRY_NAME_JAR); @@ -849,8 +853,9 @@ public class GetInputStreamNPETest { * @param verify indicates whether the jar should be verified * @throws Exception if an error occurs */ - @Test(dataProvider = "validJars") - public static void validJarFileZipEntryTest(Path jar, boolean verify) throws Exception { + @ParameterizedTest + @MethodSource("validJars") + public void validJarFileZipEntryTest(Path jar, boolean verify) throws Exception { try (JarFile jf = new JarFile(jar.toFile(), verify)) { ZipEntry ze = jf.getEntry(CEN_FILENAME_TO_MODIFY); var is = jf.getInputStream(ze); @@ -868,8 +873,9 @@ public class GetInputStreamNPETest { * @param verify indicates whether the jar should be verified * @throws Exception if an error occurs */ - @Test(dataProvider = "validJars") - public static void validJarFileJarEntryTest(Path jar, boolean verify) throws Exception { + @ParameterizedTest + @MethodSource("validJars") + public void validJarFileJarEntryTest(Path jar, boolean verify) throws Exception { try (JarFile jf = new JarFile(jar.toFile(), verify)) { ZipEntry ze = jf.getEntry(CEN_FILENAME_TO_MODIFY); var is = jf.getInputStream(ze); @@ -886,8 +892,9 @@ public class GetInputStreamNPETest { * @param verify indicates whether the jar should be verified(not used) * @throws Exception if an error occurs */ - @Test(dataProvider = "validJars") - public static void validZipFileZipEntryTest(Path jar, boolean verify) throws Exception { + @ParameterizedTest + @MethodSource("validJars") + public void validZipFileZipEntryTest(Path jar, boolean verify) throws Exception { try (ZipFile jf = new ZipFile(jar.toFile())) { ZipEntry ze = jf.getEntry(CEN_FILENAME_TO_MODIFY); var is = jf.getInputStream(ze); @@ -904,12 +911,13 @@ public class GetInputStreamNPETest { * @param verify indicates whether the jar should be verified(not used) * @throws Exception if an error occurs */ - @Test(dataProvider = "inValidJars") - public static void invalidJarFileZipEntry(Path jar, boolean verify) throws Exception { + @ParameterizedTest + @MethodSource("inValidJars") + public void invalidJarFileZipEntry(Path jar, boolean verify) throws Exception { try (JarFile jf = new JarFile(jar.toFile(), verify)) { // The entry will not be found resulting in the ZipEntry being null ZipEntry ze = jf.getEntry(CEN_FILENAME_TO_MODIFY); - var ex= expectThrows(NullPointerException.class, + var ex= assertThrows(NullPointerException.class, () -> jf.getInputStream(ze) ); // Validate that we receive the expected message from Objects.requireNonNull assertTrue( ex != null && ex.getMessage().equals("ze")); @@ -923,12 +931,13 @@ public class GetInputStreamNPETest { * @param verify indicates whether the jar should be verified(not used) * @throws IOException if an error occurs */ - @Test(dataProvider = "inValidJars") - public static void invalidZipFileZipEntry(Path jar, boolean verify) throws Exception { + @ParameterizedTest + @MethodSource("inValidJars") + public void invalidZipFileZipEntry(Path jar, boolean verify) throws Exception { try (ZipFile jf = new ZipFile(jar.toFile())) { // The entry will not be found resulting in the ZipEntry being null ZipEntry ze = jf.getEntry(CEN_FILENAME_TO_MODIFY); - var ex= expectThrows(NullPointerException.class, + var ex= assertThrows(NullPointerException.class, () -> jf.getInputStream(ze) ); // Validate that we receive the expected message from Objects.requireNonNull assertTrue( ex != null && ex.getMessage().equals("entry")); @@ -943,8 +952,9 @@ public class GetInputStreamNPETest { * @param verify indicates whether the jar should be verified * @throws Exception if an error occurs */ - @Test(dataProvider = "validJars") - public static void JarFileZipEntryDoesNotExistGetInputStreamTest( + @ParameterizedTest + @MethodSource("validJars") + public void JarFileZipEntryDoesNotExistGetInputStreamTest( Path jar, boolean verify) throws Exception { try (JarFile jf = new JarFile(jar.toFile(), verify)) { @@ -962,8 +972,9 @@ public class GetInputStreamNPETest { * @param verify indicates whether the jar should be verified(not used) * @throws Exception if an error occurs */ - @Test(dataProvider = "validJars") - public static void ZipFileZipEntryDoesNotExistGetInputStreamTest( + @ParameterizedTest + @MethodSource("validJars") + public void ZipFileZipEntryDoesNotExistGetInputStreamTest( Path jar, boolean verify) throws Exception { try (ZipFile jf = new ZipFile(jar.toFile())) { var ze = new ZipEntry(ZIP_ENTRY_THAT_DOES_NOT_EXIST); @@ -980,8 +991,9 @@ public class GetInputStreamNPETest { * @param verify indicates whether the jar should be verified * @throws Exception if an error occurs */ - @Test(dataProvider = "validJars") - public static void JarFileJarEntryEntryDoesNotExistGetInputStreamTest ( + @ParameterizedTest + @MethodSource("validJars") + public void JarFileJarEntryEntryDoesNotExistGetInputStreamTest ( Path jar, boolean verify) throws Exception { try (JarFile jf = new JarFile(jar.toFile(), verify)) { var je = new JarEntry(ZIP_ENTRY_THAT_DOES_NOT_EXIST); @@ -999,8 +1011,9 @@ public class GetInputStreamNPETest { * @param verify indicates whether the jar should be verified * @throws Exception if an error occurs */ - @Test(dataProvider = "validJars") - public static void JarFileZipEntryGetNameNullTest(Path jar, boolean verify) throws Exception { + @ParameterizedTest + @MethodSource("validJars") + public void JarFileZipEntryGetNameNullTest(Path jar, boolean verify) throws Exception { // Signed Jar is used for the next checks try (JarFile jf = new JarFile(jar.toFile(), verify)) { diff --git a/test/jdk/java/util/zip/ZipFile/InvalidBytesInEntryNameOrComment.java b/test/jdk/java/util/zip/ZipFile/InvalidBytesInEntryNameOrComment.java index c43157248f4..71086abb325 100644 --- a/test/jdk/java/util/zip/ZipFile/InvalidBytesInEntryNameOrComment.java +++ b/test/jdk/java/util/zip/ZipFile/InvalidBytesInEntryNameOrComment.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -169,7 +169,7 @@ public class InvalidBytesInEntryNameOrComment { } /** - * The DataProvider of CEN offsets to modify with an invalid UTF-8 byte + * The MethodSource of CEN offsets to modify with an invalid UTF-8 byte * sequence * * @return Arguments used in each test run diff --git a/test/jdk/java/util/zip/ZipFile/InvalidCommentLengthTest.java b/test/jdk/java/util/zip/ZipFile/InvalidCommentLengthTest.java index 1910107f0d3..7ba33bee740 100644 --- a/test/jdk/java/util/zip/ZipFile/InvalidCommentLengthTest.java +++ b/test/jdk/java/util/zip/ZipFile/InvalidCommentLengthTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,9 +22,10 @@ * */ -import org.testng.annotations.AfterTest; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import java.io.IOException; import java.nio.file.Files; @@ -35,14 +36,16 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipException; import java.util.zip.ZipFile; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; /** * @test * @bug 8280404 * @summary Validate that Zip/JarFile will throw a ZipException when the CEN * comment length field contains an incorrect value - * @run testng/othervm InvalidCommentLengthTest + * @run junit/othervm InvalidCommentLengthTest */ public class InvalidCommentLengthTest { @@ -264,8 +267,8 @@ public class InvalidCommentLengthTest { * * @throws IOException If an error occurs */ - @BeforeTest - public void setup() throws IOException { + @BeforeAll + public static void setup() throws IOException { Files.deleteIfExists(VALID_CEN_COMMENT_LENGTH_JAR); Files.deleteIfExists(INVALID_CEN_COMMENT_LENGTH_JAR); // Create the valid jar @@ -285,7 +288,7 @@ public class InvalidCommentLengthTest { * * @throws IOException If an error occurs */ - @AfterTest + @AfterAll public static void cleanup() throws IOException { Files.deleteIfExists(VALID_CEN_COMMENT_LENGTH_JAR); Files.deleteIfExists(INVALID_CEN_COMMENT_LENGTH_JAR); @@ -297,11 +300,11 @@ public class InvalidCommentLengthTest { * @throws IOException If an error occurs */ @Test - public static void ZipFileValidCommentLengthTest() throws IOException { + public void ZipFileValidCommentLengthTest() throws IOException { try (ZipFile jf = new ZipFile(VALID_CEN_COMMENT_LENGTH_JAR.toFile())) { ZipEntry ze = jf.getEntry(META_INF_MANIFEST_MF); assertNotNull(ze); - assertEquals(ze.getName(), META_INF_MANIFEST_MF); + assertEquals(META_INF_MANIFEST_MF, ze.getName()); } } @@ -311,11 +314,11 @@ public class InvalidCommentLengthTest { * @throws IOException If an error occurs */ @Test - public static void JarFileValidCommentLengthTest() throws IOException { + public void JarFileValidCommentLengthTest() throws IOException { try (JarFile jf = new JarFile(VALID_CEN_COMMENT_LENGTH_JAR.toFile())) { ZipEntry ze = jf.getEntry(META_INF_MANIFEST_MF); assertNotNull(ze); - assertEquals(ze.getName(), META_INF_MANIFEST_MF); + assertEquals(META_INF_MANIFEST_MF, ze.getName()); } } @@ -325,10 +328,10 @@ public class InvalidCommentLengthTest { * the Jar file is opened by {@code ZipFile} */ @Test - public static void ZipFileInValidCommentLengthTest() { - var ex= expectThrows(ZipException.class, + public void ZipFileInValidCommentLengthTest() { + var ex= assertThrows(ZipException.class, () -> new ZipFile(INVALID_CEN_COMMENT_LENGTH_JAR.toFile())); - assertEquals(ex.getMessage(), INVALID_CEN_HEADER_BAD_ENTRY_NAME_OR_COMMENT); + assertEquals(INVALID_CEN_HEADER_BAD_ENTRY_NAME_OR_COMMENT, ex.getMessage()); } /** @@ -337,9 +340,9 @@ public class InvalidCommentLengthTest { * the Jar file is opened by {@code JarFile} */ @Test - public static void JarFileInValidCommentLengthTest() { - var ex= expectThrows(ZipException.class, + public void JarFileInValidCommentLengthTest() { + var ex= assertThrows(ZipException.class, () -> new JarFile(INVALID_CEN_COMMENT_LENGTH_JAR.toFile())); - assertEquals(ex.getMessage(), INVALID_CEN_HEADER_BAD_ENTRY_NAME_OR_COMMENT); + assertEquals(INVALID_CEN_HEADER_BAD_ENTRY_NAME_OR_COMMENT, ex.getMessage()); } } diff --git a/test/jdk/java/util/zip/ZipFile/MissingZIP64EntriesTest.java b/test/jdk/java/util/zip/ZipFile/MissingZIP64EntriesTest.java index 51a6d0b58ee..4920fa724ce 100644 --- a/test/jdk/java/util/zip/ZipFile/MissingZIP64EntriesTest.java +++ b/test/jdk/java/util/zip/ZipFile/MissingZIP64EntriesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -480,7 +480,7 @@ public class MissingZIP64EntriesTest { private ByteBuffer buffer; /** - * The DataProvider returning a byte array representing the Zip file, + * The MethodSource returning a byte array representing the Zip file, * CEN offsets to set to 0xFFFFFFFF and the expected * ZipException error message when there are missing Zip64 Extra header fields * @return Arguments used in each test run @@ -501,7 +501,7 @@ public class MissingZIP64EntriesTest { } /** - * The DataProvider of CEN offsets to set to 0xFFFFFFFF or 0xFFFF when the Extra Length + * The MethodSource of CEN offsets to set to 0xFFFFFFFF or 0xFFFF when the Extra Length * size is 0 for the Zip file created using ZIP_WITH_NO_EXTRA_LEN_BYTEARRAY * @return Arguments used in each test run */ @@ -519,7 +519,7 @@ public class MissingZIP64EntriesTest { } /** - * The DataProvider of CEN offsets to set to 0xFFFFFFFF when the ZIP64 extra header + * The MethodSource of CEN offsets to set to 0xFFFFFFFF when the ZIP64 extra header * Length size is 0 for the Zip file created using * ZIP_WITH_ZEROLEN_ZIP64_EXTRAHDR_BYTEARRAY * @return Arguments used in each test run @@ -536,7 +536,7 @@ public class MissingZIP64EntriesTest { } /** - * The DataProvider which will return a byte array representing a + * The MethodSource which will return a byte array representing a * valid Zip file and the expected content for the Zip file entry 'Hello.txt'. * @return Arguments used in each test run */ diff --git a/test/jdk/java/util/zip/ZipFile/TestZipFileEncodings.java b/test/jdk/java/util/zip/ZipFile/TestZipFileEncodings.java index 4e271912345..d8692ee3261 100644 --- a/test/jdk/java/util/zip/ZipFile/TestZipFileEncodings.java +++ b/test/jdk/java/util/zip/ZipFile/TestZipFileEncodings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. * 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,11 +26,13 @@ * @bug 8243254 * @summary Tests a simple set of operations on Zip files in various encodings * focusing on ensuring metadata is properly encoded and read. - * @run testng/timeout=480 TestZipFileEncodings + * @run junit/timeout=480 TestZipFileEncodings */ -import org.testng.annotations.AfterClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; import java.io.BufferedOutputStream; import java.io.File; @@ -38,7 +40,6 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -50,8 +51,6 @@ import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Stream; @@ -60,7 +59,10 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; public class TestZipFileEncodings { @@ -76,50 +78,49 @@ public class TestZipFileEncodings { return ThreadLocalRandom.current(); } - @DataProvider(name = "non-unicode-charsets") - public Object[][] nonUnicodeCharsets() { - return new Object[][] { - { "ISO-8859-1" }, - { "IBM01149" }, - { "IBM037" }, - { "IBM-Thai" } - }; + public static Stream nonUnicodeCharsets() { + return Stream.of( + "ISO-8859-1", + "IBM01149", + "IBM037", + "IBM-Thai" + ); } - @DataProvider(name = "unicode-charsets") - public Object[][] unicodeCharsets() { - return new Object[][] { - { "UTF-8" }, - { "UTF-16" }, - { "UTF-16LE" }, - { "UTF-16BE" }, - { "UTF-32" } - }; + public static Stream unicodeCharsets() { + return Stream.of( + "UTF-8", + "UTF-16", + "UTF-16LE", + "UTF-16BE", + "UTF-32" + ); } - @DataProvider(name = "all-charsets") - public Object[][] allCharsets() { - return Stream.concat(Stream.of(nonUnicodeCharsets()), - Stream.of(unicodeCharsets())) - .toArray(Object[][]::new); + public static Stream allCharsets() { + return Stream.concat(nonUnicodeCharsets(), unicodeCharsets()); } - @Test(dataProvider = "non-unicode-charsets") + @ParameterizedTest + @MethodSource("nonUnicodeCharsets") public void testNonUnicode(String charsetName) throws Throwable { test(NUM_ENTRIES, 100 + random().nextInt(ENTRY_SIZE), false, Charset.forName(charsetName)); } - @Test(dataProvider = "unicode-charsets") + @ParameterizedTest + @MethodSource("unicodeCharsets") public void testUnicode(String charsetName) throws Throwable { test(NUM_ENTRIES, 100 + random().nextInt(ENTRY_SIZE), true, Charset.forName(charsetName)); } - @Test(dataProvider = "non-unicode-charsets") + @ParameterizedTest + @MethodSource("nonUnicodeCharsets") public void testNonUnicodeManyEntries(String charsetName) throws Throwable { test(70000, 10, false, Charset.forName(charsetName)); } - @Test(dataProvider = "unicode-charsets") + @ParameterizedTest + @MethodSource("unicodeCharsets") public void testUnicodeManyEntries(String charsetName) throws Throwable { test(70000, 10, true, Charset.forName(charsetName)); } @@ -160,7 +161,8 @@ public class TestZipFileEncodings { * since it explicity provokes this rare condition. * */ - @Test(dataProvider = "all-charsets") + @ParameterizedTest + @MethodSource("allCharsets") public void sameHashAndLengthDirLookup(String charsetName) throws IOException { // Two directory names with colliding hash codes and same length // (found in a brute force search) @@ -187,15 +189,15 @@ public class TestZipFileEncodings { try (ZipFile z = new ZipFile(zip.toFile(), charset)) { ZipEntry second = z.getEntry("_____-408231241"); - assertEquals(second.getComment(), "Entry two"); + assertEquals("Entry two", second.getComment()); ZipEntry first = z.getEntry("_____1637461950"); - assertEquals(first.getComment(), "Entry one"); + assertEquals("Entry one", first.getComment()); } } - @AfterClass - public void tearDown() { + @AfterAll + public static void tearDown() { for (Path path : paths) { path.toFile().deleteOnExit(); } @@ -208,14 +210,14 @@ public class TestZipFileEncodings { } static void checkEqual(ZipEntry x, ZipEntry y) { - assertEquals(x.getName(), y.getName()); - assertEquals(x.isDirectory(), y.isDirectory()); - assertEquals(x.getMethod(), y.getMethod()); - assertEquals((x.getTime() / 2000), y.getTime() / 2000); - assertEquals(x.getSize(), y.getSize()); - assertEquals(x.getCompressedSize(), y.getCompressedSize()); - assertEquals(x.getCrc(), y.getCrc()); - assertEquals(x.getComment(), y.getComment()); + assertEquals(y.getName(), x.getName()); + assertEquals(y.isDirectory(), x.isDirectory()); + assertEquals(y.getMethod(), x.getMethod()); + assertEquals(y.getTime() / 2000, (x.getTime() / 2000)); + assertEquals(y.getSize(), x.getSize()); + assertEquals(y.getCompressedSize(), x.getCompressedSize()); + assertEquals(y.getCrc(), x.getCrc()); + assertEquals(y.getComment(), x.getComment()); } static void doTest(Zip zip) throws Throwable { @@ -226,7 +228,7 @@ public class TestZipFileEncodings { static void doTest0(Zip zip, ZipFile zf) throws Throwable { // (0) check zero-length entry name, no AIOOBE - assertEquals(zf.getEntry(""), null); + assertEquals(null, zf.getEntry("")); List list = new ArrayList(zip.entries.keySet()); // check each entry and its bytes @@ -238,7 +240,7 @@ public class TestZipFileEncodings { if (!e.isDirectory()) { // check with readAllBytes try (InputStream is = zf.getInputStream(e)) { - assertEquals(data, is.readAllBytes()); + assertArrayEquals(is.readAllBytes(), data); } int slash = name.indexOf('/'); if (slash > 0) { diff --git a/test/jdk/java/util/zip/ZipFile/ZipEntryTimeBounds.java b/test/jdk/java/util/zip/ZipFile/ZipEntryTimeBounds.java index ab0c2c3f3b0..0bc6b6c628b 100644 --- a/test/jdk/java/util/zip/ZipFile/ZipEntryTimeBounds.java +++ b/test/jdk/java/util/zip/ZipFile/ZipEntryTimeBounds.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,8 @@ * questions. */ -import org.testng.annotations.Test; + +import org.junit.jupiter.api.Test; import java.io.File; import java.io.FileOutputStream; @@ -34,13 +35,14 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; /* @test * @bug 8246129 * @summary JDK add metadata to zip files with entries timestamped at the * lower bound of the DOS time epoch, i.e., 1980-01-01T00:00:00Z - * @run testng/othervm ZipEntryTimeBounds + * @run junit/othervm ZipEntryTimeBounds */ public class ZipEntryTimeBounds { @@ -59,17 +61,17 @@ public class ZipEntryTimeBounds { TimeZone.setDefault(TimeZone.getTimeZone("GMT")); File f2 = createTempFile(); makeZip(f2, new GregorianCalendar(1980, Calendar.JANUARY, 1, 0, 0, 0).getTimeInMillis()); - assertEquals(Files.mismatch(f1.toPath(), f2.toPath()), -1L); + assertEquals(-1L, Files.mismatch(f1.toPath(), f2.toPath())); TimeZone.setDefault(TimeZone.getTimeZone("GMT+01")); File f3 = createTempFile(); makeZip(f3, new GregorianCalendar(1980, Calendar.JANUARY, 1, 0, 0, 0).getTimeInMillis()); - assertEquals(Files.mismatch(f1.toPath(), f3.toPath()), -1L); + assertEquals(-1L, Files.mismatch(f1.toPath(), f3.toPath())); // Check that the milliseconds part of the time is exactly preserved - assertEquals(new ZipFile(f1).getEntry("entry.txt").getTime() % 60000, 0); - assertEquals(new ZipFile(f2).getEntry("entry.txt").getTime() % 60000, 0); - assertEquals(new ZipFile(f3).getEntry("entry.txt").getTime() % 60000, 0); + assertEquals(0, new ZipFile(f1).getEntry("entry.txt").getTime() % 60000); + assertEquals(0, new ZipFile(f2).getEntry("entry.txt").getTime() % 60000); + assertEquals(0, new ZipFile(f3).getEntry("entry.txt").getTime() % 60000); } @Test @@ -85,22 +87,22 @@ public class ZipEntryTimeBounds { TimeZone.setDefault(TimeZone.getTimeZone("GMT")); File f2 = createTempFile(); makeZip(f2, new GregorianCalendar(1980, Calendar.JANUARY, 1, 0, 0, 1).getTimeInMillis()); - assertEquals(Files.mismatch(f1.toPath(), f2.toPath()), -1L); + assertEquals(-1L, Files.mismatch(f1.toPath(), f2.toPath())); TimeZone.setDefault(TimeZone.getTimeZone("GMT+01")); File f3 = createTempFile(); makeZip(f3, new GregorianCalendar(1980, Calendar.JANUARY, 1, 0, 0, 1).getTimeInMillis() + 999); - assertEquals(Files.mismatch(f1.toPath(), f3.toPath()), -1L); + assertEquals(-1L, Files.mismatch(f1.toPath(), f3.toPath())); // Check that the seconds part of the time is lossily preserved, // rounding down to the previous 2s step since epoch - assertEquals(new ZipFile(f1).getEntry("entry.txt").getTime() % 60000, 0); - assertEquals(new ZipFile(f2).getEntry("entry.txt").getTime() % 60000, 0); - assertEquals(new ZipFile(f3).getEntry("entry.txt").getTime() % 60000, 0); + assertEquals(0, new ZipFile(f1).getEntry("entry.txt").getTime() % 60000); + assertEquals(0, new ZipFile(f2).getEntry("entry.txt").getTime() % 60000); + assertEquals(0, new ZipFile(f3).getEntry("entry.txt").getTime() % 60000); File f4 = createTempFile(); makeZip(f4, new GregorianCalendar(1980, Calendar.JANUARY, 1, 0, 0, 2).getTimeInMillis()); - assertEquals(new ZipFile(f4).getEntry("entry.txt").getTime() % 60000, 2000); + assertEquals(2000, new ZipFile(f4).getEntry("entry.txt").getTime() % 60000); } @Test @@ -116,20 +118,20 @@ public class ZipEntryTimeBounds { TimeZone.setDefault(TimeZone.getTimeZone("GMT")); File f2 = createTempFile(); makeZip(f2, new GregorianCalendar(1979, Calendar.DECEMBER, 31, 23, 59, 59).getTimeInMillis()); - assertNotEquals(Files.mismatch(f1.toPath(), f2.toPath()), -1L); + assertNotEquals(-1L, Files.mismatch(f1.toPath(), f2.toPath())); TimeZone.setDefault(TimeZone.getTimeZone("GMT+01")); File f3 = createTempFile(); makeZip(f3, new GregorianCalendar(1979, Calendar.DECEMBER, 31, 23, 59, 59).getTimeInMillis() + 500); - assertNotEquals(Files.mismatch(f1.toPath(), f3.toPath()), -1L); + assertNotEquals(-1L, Files.mismatch(f1.toPath(), f3.toPath())); // Check that the time is preserved at second precision, no rounding // to 2s - assertEquals(new ZipFile(f1).getEntry("entry.txt").getTime() % 60000, 59000); - assertEquals(new ZipFile(f2).getEntry("entry.txt").getTime() % 60000, 59000); + assertEquals(59000, new ZipFile(f1).getEntry("entry.txt").getTime() % 60000); + assertEquals(59000, new ZipFile(f2).getEntry("entry.txt").getTime() % 60000); // Milliseconds are discarded even when storing entries with extended // time metadata - assertEquals(new ZipFile(f3).getEntry("entry.txt").getTime() % 60000, 59000); + assertEquals(59000, new ZipFile(f3).getEntry("entry.txt").getTime() % 60000); } private static void makeZip(File f, long time) throws Exception { diff --git a/test/jdk/java/util/zip/ZipFile/ZipFileDuplicateEntryTest.java b/test/jdk/java/util/zip/ZipFile/ZipFileDuplicateEntryTest.java index 95a223c8e1f..1fe9bd4c203 100644 --- a/test/jdk/java/util/zip/ZipFile/ZipFileDuplicateEntryTest.java +++ b/test/jdk/java/util/zip/ZipFile/ZipFileDuplicateEntryTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,10 +22,12 @@ * */ -import org.testng.annotations.AfterTest; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; @@ -45,19 +47,24 @@ import java.util.jar.JarFile; import java.util.jar.JarInputStream; import java.util.jar.JarOutputStream; import java.util.stream.Collectors; +import java.util.stream.Stream; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * @test * @bug 8276123 * @summary ZipFile::getEntry will not return a file entry when there is a * directory entry of the same name within a Zip File - * @run testng/othervm ZipFileDuplicateEntryTest + * @run junit/othervm ZipFileDuplicateEntryTest */ public class ZipFileDuplicateEntryTest { @@ -158,7 +165,7 @@ public class ZipFileDuplicateEntryTest { * * @throws IOException If an error occurs */ - @BeforeTest + @BeforeAll public static void setup() throws IOException { /** @@ -209,7 +216,7 @@ public class ZipFileDuplicateEntryTest { * * @throws IOException If an error occurs */ - @AfterTest + @AfterAll public static void cleanup() throws IOException { Files.deleteIfExists(ZIP_FILE); Files.deleteIfExists(ZIP_FILE2); @@ -218,16 +225,12 @@ public class ZipFileDuplicateEntryTest { } /** - * DataProvider used to specify the Zip entries to use + * MethodSource used to specify the Zip entries to use * - * @return The Entry to use within the test + * @return Stream that indicates which Entry to use within the test */ - @DataProvider - public Object[][] entries() { - return new Object[][]{ - {FILE_ENTRY}, - {DIR_ENTRY} - }; + public static Stream entries() { + return Stream.of(FILE_ENTRY, DIR_ENTRY); } /** @@ -252,7 +255,7 @@ public class ZipFileDuplicateEntryTest { System.out.printf("name: %s, isDirectory: %s, payload= %s%n", ze.getName(), ze.isDirectory(), new String(bytes)); } - assertEquals(bytes, DIR_ENTRY.bytes, + assertArrayEquals(DIR_ENTRY.bytes, bytes, String.format("Expected payload: %s", new String(DIR_ENTRY.bytes))); } @@ -266,7 +269,8 @@ public class ZipFileDuplicateEntryTest { * @param entry The entry to search for * @throws IOException If an error occurs */ - @Test(dataProvider = "entries") + @ParameterizedTest + @MethodSource("entries") public void testSameFileDirEntryName(Entry entry) throws IOException { System.out.printf("%n%n**** testSameFileDirEntryName ***%n"); @@ -282,7 +286,7 @@ public class ZipFileDuplicateEntryTest { System.out.printf("name: %s, isDirectory: %s, payload= %s%n", ze.getName(), ze.isDirectory(), new String(bytes)); } - assertEquals(entry.bytes, bytes, + assertArrayEquals(entry.bytes, bytes, String.format("Expected payload: %s", new String(entry.bytes))); } } @@ -310,7 +314,7 @@ public class ZipFileDuplicateEntryTest { System.out.printf("name: %s, isDirectory: %s, payload= %s%n", ze.getName(), ze.isDirectory(), new String(bytes)); } - assertEquals(bytes, DUPLICATE_FILE_ENTRY.bytes, + assertArrayEquals(DUPLICATE_FILE_ENTRY.bytes, bytes, String.format("Expected payload: %s", new String(DUPLICATE_FILE_ENTRY.bytes))); } } @@ -339,8 +343,8 @@ public class ZipFileDuplicateEntryTest { throw new RuntimeException( String.format("Invalid Zip entry: %s", zipEntry.getName())); } - assertEquals(zipEntry.getMethod(), e.method); - assertEquals(zis.readAllBytes(), e.bytes, + assertEquals(e.method, zipEntry.getMethod()); + assertArrayEquals(e.bytes, zis.readAllBytes(), String.format("Expected payload: %s", new String(e.bytes))); zipEntry = zis.getNextEntry(); } @@ -372,8 +376,9 @@ public class ZipFileDuplicateEntryTest { * @param entry The entry to validate * @throws IOException If an error occurs */ - @Test(dataProvider = "entries") - public static void JarFileInputStreamTest(Entry entry) throws IOException { + @ParameterizedTest + @MethodSource("entries") + public void JarFileInputStreamTest(Entry entry) throws IOException { System.out.printf("%n%n**** JarFileInputStreamTest ***%n"); try (JarFile jarFile = new JarFile(TEST_JAR.toFile())) { JarEntry je = jarFile.getJarEntry(entry.name); @@ -389,7 +394,7 @@ public class ZipFileDuplicateEntryTest { System.out.printf("bytes= %s, expected=%s%n", new String(bytes), new String(entry.bytes)); } - assertEquals(bytes, entry.bytes, + assertArrayEquals(entry.bytes, bytes, String.format("Expected payload: %s", new String(entry.bytes))); } } @@ -418,8 +423,8 @@ public class ZipFileDuplicateEntryTest { throw new RuntimeException( String.format("Invalid Jar entry: %s", jarEntry.getName())); } - assertEquals(jarEntry.getMethod(), e.method); - assertEquals(jis.readAllBytes(), e.bytes, + assertEquals(e.method, jarEntry.getMethod()); + assertArrayEquals(e.bytes, jis.readAllBytes(), String.format("Expected payload: %s", new String(e.bytes))); jarEntry = jis.getNextJarEntry(); } @@ -433,7 +438,8 @@ public class ZipFileDuplicateEntryTest { * @param entry The entry to validate * @throws IOException If an error occurs */ - @Test(dataProvider = "entries") + @ParameterizedTest + @MethodSource("entries") public void JarURLConnectionTest(Entry entry) throws Exception { System.out.printf("%n%n**** JarURLConnectionTest ***%n"); URL url = new URL("jar:" + TEST_JAR.toUri().toURL() + "!/" + entry.name); @@ -449,10 +455,10 @@ public class ZipFileDuplicateEntryTest { assertNull(con.getAttributes()); assertNull(con.getMainAttributes()); assertNull(con.getManifest()); - assertEquals(je.getName(), entry.name); - assertEquals(con.getEntryName(), entry.name); - assertEquals(je.getMethod(), entry.method); - assertEquals(con.getJarFileURL(), TEST_JAR.toUri().toURL()); + assertEquals(entry.name, je.getName()); + assertEquals(entry.name, con.getEntryName()); + assertEquals(entry.method, je.getMethod()); + assertEquals(TEST_JAR.toUri().toURL(), con.getJarFileURL()); if (DEBUG) { System.out.printf(" getEntryName: %s, getJarFileURL:%s%n", con.getEntryName(), con.getJarFileURL()); @@ -464,7 +470,7 @@ public class ZipFileDuplicateEntryTest { if (DEBUG) { System.out.printf(" Bytes read:%s%n", new String(bytes)); } - assertEquals(bytes, entry.bytes, + assertArrayEquals(entry.bytes, bytes, String.format("Expected payload: %s", new String(entry.bytes))); } } diff --git a/test/jdk/java/util/zip/ZipFile/ZipFileInputStreamSkipTest.java b/test/jdk/java/util/zip/ZipFile/ZipFileInputStreamSkipTest.java index e1c17200764..131f7a5c51c 100644 --- a/test/jdk/java/util/zip/ZipFile/ZipFileInputStreamSkipTest.java +++ b/test/jdk/java/util/zip/ZipFile/ZipFileInputStreamSkipTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,9 +22,11 @@ * */ -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; import java.io.IOException; import java.io.InputStream; @@ -39,32 +41,35 @@ import java.util.Map; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; /** * @test * @bug 8231451 * @summary Basic tests for ZipFileInputStream::skip * @modules jdk.zipfs - * @run testng/othervm ZipFileInputStreamSkipTest + * @run junit/othervm ZipFileInputStreamSkipTest */ public class ZipFileInputStreamSkipTest { // Stored and Deflated Zip File paths used by the tests - private final Path STORED_ZIPFILE = Path.of("skipStoredEntries.zip"); - private final Path DEFLATED_ZIPFILE = Path.of("skipDeflatedEntries.zip"); + private static final Path STORED_ZIPFILE = Path.of("skipStoredEntries.zip"); + private static final Path DEFLATED_ZIPFILE = Path.of("skipDeflatedEntries.zip"); // Saved Entries added to the relevant Zip file - private final HashMap STORED_ZIP_ENTRIES = new HashMap<>(); - private final HashMap DEFLATED_ZIP_ENTRIES = new HashMap<>(); + private static final HashMap STORED_ZIP_ENTRIES = new HashMap<>(); + private static final HashMap DEFLATED_ZIP_ENTRIES = new HashMap<>(); /** * Create the Zip Files used by the tests * * @throws IOException If an error occurs creating the Zip Files */ - @BeforeClass - private void createZip() throws IOException { + @BeforeAll + private static void createZip() throws IOException { Entry e0 = Entry.of("Entry-0", ZipEntry.STORED, "Tennis Pro"); Entry e1 = Entry.of("Entry-1", ZipEntry.STORED, "United States Tennis Association"); @@ -92,8 +97,8 @@ public class ZipFileInputStreamSkipTest { * * @throws IOException If an error occurs during cleanup */ - @AfterClass - private void cleanUp() throws IOException { + @AfterAll + private static void cleanUp() throws IOException { Files.deleteIfExists(STORED_ZIPFILE); Files.deleteIfExists(DEFLATED_ZIPFILE); } @@ -119,28 +124,28 @@ public class ZipFileInputStreamSkipTest { // Check that if we specify 0, that we return the correct // skip value value - assertEquals(in.skip(0), 0); + assertEquals(0, in.skip(0)); // Try to skip past EOF and should return remaining bytes - assertEquals(in.skip(entrySize + 100), entrySize); + assertEquals(entrySize, in.skip(entrySize + 100)); // Return to BOF and then specify a value which would // overflow the projected skip value and return the // number of bytes moved to reach EOF - assertEquals(in.skip(-entrySize), -entrySize); - assertEquals(in.skip(Long.MAX_VALUE), entrySize); + assertEquals(-entrySize, in.skip(-entrySize)); + assertEquals(entrySize, in.skip(Long.MAX_VALUE)); // From midpoint, try to skip past EOF and then skip back // to BOF - assertEquals(in.skip(-entrySize), -entrySize); - assertEquals(in.skip(midpoint), midpoint); - assertEquals(in.skip(1000), entrySize - midpoint); - assertEquals(in.skip(-entrySize), -entrySize); + assertEquals(-entrySize, in.skip(-entrySize)); + assertEquals(midpoint, in.skip(midpoint)); + assertEquals(entrySize - midpoint, in.skip(1000)); + assertEquals(-entrySize, in.skip(-entrySize)); // Read remaining bytes and validate against expected bytes byte[] bytes = in.readAllBytes(); - assertEquals(bytes, expected.bytes); - assertEquals(bytes.length, expected.bytes.length); + assertArrayEquals(expected.bytes, bytes); + assertEquals(expected.bytes.length, bytes.length); } } } @@ -167,25 +172,25 @@ public class ZipFileInputStreamSkipTest { // Check that if you try to move past BOF // that we return the correct value - assertEquals(in.skip(-1), 0); - assertEquals(in.skip(-100), 0); - assertEquals(in.skip(Long.MIN_VALUE), 0); + assertEquals(0, in.skip(-1)); + assertEquals(0, in.skip(-100)); + assertEquals(0, in.skip(Long.MIN_VALUE)); // Go to midpoint in file; then specify a value before // BOF which should result in the number of // bytes to BOF returned - assertEquals(in.skip(midpoint), midpoint); - assertEquals(in.skip(-(midpoint + 10)), -midpoint); + assertEquals(midpoint, in.skip(midpoint)); + assertEquals(-midpoint, in.skip(-(midpoint + 10))); // From midpoint, move back a couple of bytes - assertEquals(in.skip(midpoint), midpoint); - assertEquals(in.skip(-2), -2); + assertEquals(midpoint, in.skip(midpoint)); + assertEquals(-2, in.skip(-2)); // Read the remaining bytes and compare to the expected bytes byte[] bytes = in.readAllBytes(); - assertEquals(bytes, Arrays.copyOfRange(expected.bytes, - (int)midpoint - 2, (int) entrySize)); - assertEquals(bytes.length, entrySize - midpoint + 2); + assertArrayEquals(Arrays.copyOfRange(expected.bytes, + (int)midpoint - 2, (int) entrySize), bytes); + assertEquals(entrySize - midpoint + 2, bytes.length); } } } @@ -207,12 +212,12 @@ public class ZipFileInputStreamSkipTest { Entry expected = DEFLATED_ZIP_ENTRIES.get(entry.getName()); assertNotNull(expected); try (InputStream in = zf.getInputStream(entry)) { - assertEquals(in.skip(toSkip), toSkip); + assertEquals(toSkip, in.skip(toSkip)); byte[] bytes = in.readAllBytes(); var ebytes = Arrays.copyOfRange(expected.bytes, toSkip, expected.bytes.length); - assertEquals(bytes, ebytes); - assertEquals(bytes.length, expected.bytes.length - toSkip); + assertArrayEquals(ebytes, bytes); + assertEquals(expected.bytes.length - toSkip, bytes.length); } } } @@ -248,7 +253,7 @@ public class ZipFileInputStreamSkipTest { * @param entries The entries to add to the Zip File * @throws IOException If an error occurs while creating the Zip file */ - private void createZipFile(Path zipFile, Map env, + private static void createZipFile(Path zipFile, Map env, Entry... entries) throws IOException { try (FileSystem zipfs = FileSystems.newFileSystem(zipFile, env)) { diff --git a/test/jdk/java/util/zip/ZipOutputStream/EmptyComment.java b/test/jdk/java/util/zip/ZipOutputStream/EmptyComment.java index 0f52844f3f6..28c7569243c 100644 --- a/test/jdk/java/util/zip/ZipOutputStream/EmptyComment.java +++ b/test/jdk/java/util/zip/ZipOutputStream/EmptyComment.java @@ -1,5 +1,6 @@ /* * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,34 +22,36 @@ * questions. */ +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + import java.io.ByteArrayOutputStream; import java.util.function.Consumer; +import java.util.stream.IntStream; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - -import static org.testng.Assert.assertThrows; +import static org.junit.jupiter.api.Assertions.assertThrows; /** * @test * @bug 8277087 * @summary Verifies various use cases when the zip comment should be empty - * @run testng EmptyComment + * @run junit EmptyComment */ public final class EmptyComment { - @DataProvider() - Object[][] longLengths() { - return new Object[][]{{0xFFFF + 1}, {0xFFFF + 2}, {0xFFFF * 2}}; + static IntStream longLengths() { + return IntStream.of(0xFFFF + 1, 0xFFFF + 2, 0xFFFF * 2); } /** * Overflow, the text is too long to be stored as a comment. */ - @Test(dataProvider = "longLengths") + @ParameterizedTest + @MethodSource("longLengths") void testOverflow(int length) throws Exception { test(zos -> assertThrows(IllegalArgumentException.class, () -> { zos.setComment("X".repeat(length)); diff --git a/test/jdk/javax/crypto/Cipher/TestDisabledWithOids.java b/test/jdk/javax/crypto/Cipher/TestDisabledWithOids.java new file mode 100644 index 00000000000..d1d9fa7a5bb --- /dev/null +++ b/test/jdk/javax/crypto/Cipher/TestDisabledWithOids.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8375549 + * @summary Test JCE layer algorithm restriction using algorithms w/ oids + * @library /test/lib + * @run main/othervm -Djdk.crypto.disabledAlgorithms=Cipher.DES,Cipher.RSA/ECB/PKCS1Padding TestDisabledWithOids + * @run main/othervm -Djdk.crypto.disabledAlgorithms=Cipher.RSA/ECB/PKCS1Padding,Cipher.DES TestDisabledWithOids + */ +import java.security.NoSuchAlgorithmException; +import javax.crypto.Cipher; +import jdk.test.lib.Utils; + +public class TestDisabledWithOids { + public static void main(String[] args) throws Exception { + String algo1 = "RSA/ECB/PKCS1Padding"; + String algo2 = "DES"; + + Utils.runAndCheckException(() -> Cipher.getInstance(algo1), + NoSuchAlgorithmException.class); + Utils.runAndCheckException(() -> Cipher.getInstance(algo2), + NoSuchAlgorithmException.class); + System.out.println("Done"); + } +} diff --git a/test/jdk/javax/imageio/ReadAbortTest.java b/test/jdk/javax/imageio/ReadAbortTest.java index 7476dbe0de8..bda17aa4204 100644 --- a/test/jdk/javax/imageio/ReadAbortTest.java +++ b/test/jdk/javax/imageio/ReadAbortTest.java @@ -30,16 +30,17 @@ * calling IIOReadProgressListener.readAborted() for all readers. * @run main ReadAbortTest */ +import java.awt.Color; +import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; +import java.nio.file.Files; import java.util.Iterator; + import javax.imageio.ImageIO; import javax.imageio.ImageReader; import javax.imageio.event.IIOReadProgressListener; import javax.imageio.stream.ImageInputStream; -import java.awt.Color; -import java.awt.Graphics2D; -import java.nio.file.Files; public class ReadAbortTest implements IIOReadProgressListener { @@ -103,7 +104,9 @@ public class ReadAbortTest implements IIOReadProgressListener { } catch (Exception e) { throw e; } finally { - Files.delete(file.toPath()); + if (file != null && file.exists()) { + Files.delete(file.toPath()); + } } } diff --git a/test/jdk/javax/imageio/WriteAbortTest.java b/test/jdk/javax/imageio/WriteAbortTest.java index 624ce16c94e..43abd703d7d 100644 --- a/test/jdk/javax/imageio/WriteAbortTest.java +++ b/test/jdk/javax/imageio/WriteAbortTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,15 +30,16 @@ * calling IIOWriteProgressListener.readAborted() for all readers. * @run main WriteAbortTest */ -import java.awt.image.BufferedImage; -import java.io.File; -import javax.imageio.ImageIO; -import javax.imageio.stream.ImageInputStream; import java.awt.Color; import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.io.File; import java.nio.file.Files; + +import javax.imageio.ImageIO; import javax.imageio.ImageWriter; import javax.imageio.event.IIOWriteProgressListener; +import javax.imageio.stream.ImageInputStream; import javax.imageio.stream.ImageOutputStream; public class WriteAbortTest implements IIOWriteProgressListener { @@ -98,7 +99,9 @@ public class WriteAbortTest implements IIOWriteProgressListener { + format); } } finally { - Files.delete(file.toPath()); + if (file != null && file.exists()) { + Files.delete(file.toPath()); + } } } diff --git a/test/jdk/javax/print/PrintServiceLookup/FlushCustomClassLoader.java b/test/jdk/javax/print/PrintServiceLookup/FlushCustomClassLoader.java index c16fe0e5a82..8125b656de4 100644 --- a/test/jdk/javax/print/PrintServiceLookup/FlushCustomClassLoader.java +++ b/test/jdk/javax/print/PrintServiceLookup/FlushCustomClassLoader.java @@ -56,17 +56,6 @@ public final class FlushCustomClassLoader { } private static Reference getLoader(String m) throws Exception { - /* - * The print services are stored per the AppContext, and each AppContext - * caches the "current" class loader during creation. - * see javax.print.PrintServiceLookup. - * - * To prevent AppContext from cache our test loader we force AppContext - * creation early by the invokeAndWait. - * The "EventQueue.invokeAndWait(() -> {});" can be removed when the - * AppContext usage will be deleted in the PrintServiceLookup - */ - EventQueue.invokeAndWait(() -> {}); URL url = FlushCustomClassLoader.class.getProtectionDomain() .getCodeSource().getLocation(); diff --git a/test/jdk/javax/print/PrintablePrintDPI.java b/test/jdk/javax/print/PrintablePrintDPI.java index 6cae2be532c..6b5e83df233 100644 --- a/test/jdk/javax/print/PrintablePrintDPI.java +++ b/test/jdk/javax/print/PrintablePrintDPI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2025, BELLSOFT. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -54,7 +54,7 @@ import java.awt.print.PrinterJob; /* * @test - * @bug 8251928 + * @bug 8251928 8375221 * @key printer * @summary Printable.print method should reflect printer's DPI * @library /java/awt/regtesthelpers @@ -201,7 +201,9 @@ public class PrintablePrintDPI implements Printable { attributeSet.add(OrientationRequested.PORTRAIT); job.setPrintService(printService); job.setPrintable(this); - job.print(attributeSet); + if (job.printDialog(attributeSet)) { + job.print(attributeSet); + } } catch (PrinterException ex) { throw new RuntimeException(ex); } diff --git a/test/jdk/javax/sql/testng/TEST.properties b/test/jdk/javax/sql/TEST.properties similarity index 68% rename from test/jdk/javax/sql/testng/TEST.properties rename to test/jdk/javax/sql/TEST.properties index cb97c160507..d9ed805344a 100644 --- a/test/jdk/javax/sql/testng/TEST.properties +++ b/test/jdk/javax/sql/TEST.properties @@ -1,7 +1,7 @@ -# JDBC unit tests uses TestNG -TestNG.dirs= . +# JDBC unit tests uses JUnit +JUnit.dirs= . othervm.dirs= . -lib.dirs = /java/sql/testng +lib.dirs = /java/sql/util modules = java.sql.rowset/com.sun.rowset \ java.sql.rowset/com.sun.rowset.internal \ java.sql.rowset/com.sun.rowset.providers diff --git a/test/jdk/javax/sql/testng/jars/badFactory/META-INF/services/javax.sql.rowset.RowSetFactory b/test/jdk/javax/sql/jars/badFactory/META-INF/services/javax.sql.rowset.RowSetFactory similarity index 100% rename from test/jdk/javax/sql/testng/jars/badFactory/META-INF/services/javax.sql.rowset.RowSetFactory rename to test/jdk/javax/sql/jars/badFactory/META-INF/services/javax.sql.rowset.RowSetFactory diff --git a/test/jdk/javax/sql/testng/jars/goodFactory/META-INF/services/javax.sql.rowset.RowSetFactory b/test/jdk/javax/sql/jars/goodFactory/META-INF/services/javax.sql.rowset.RowSetFactory similarity index 100% rename from test/jdk/javax/sql/testng/jars/goodFactory/META-INF/services/javax.sql.rowset.RowSetFactory rename to test/jdk/javax/sql/jars/goodFactory/META-INF/services/javax.sql.rowset.RowSetFactory diff --git a/test/jdk/javax/sql/rowset/TEST.properties b/test/jdk/javax/sql/rowset/TEST.properties deleted file mode 100644 index 6c5a2c7aceb..00000000000 --- a/test/jdk/javax/sql/rowset/TEST.properties +++ /dev/null @@ -1 +0,0 @@ -modules = java.sql.rowset diff --git a/test/jdk/javax/sql/testng/test/rowset/BaseRowSetTests.java b/test/jdk/javax/sql/test/rowset/BaseRowSetTests.java similarity index 83% rename from test/jdk/javax/sql/testng/test/rowset/BaseRowSetTests.java rename to test/jdk/javax/sql/test/rowset/BaseRowSetTests.java index c1d2d9a2ed0..8c47415db39 100644 --- a/test/jdk/javax/sql/testng/test/rowset/BaseRowSetTests.java +++ b/test/jdk/javax/sql/test/rowset/BaseRowSetTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,14 +40,19 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.util.Calendar; +import java.util.stream.Stream; import javax.sql.RowSet; import javax.sql.rowset.serial.SerialArray; import javax.sql.rowset.serial.SerialBlob; import javax.sql.rowset.serial.SerialClob; import javax.sql.rowset.serial.SerialRef; -import static org.testng.Assert.*; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + import util.StubArray; import util.StubBaseRowSet; import util.StubBlob; @@ -67,7 +72,8 @@ public class BaseRowSetTests extends CommonRowSetTests { /* * Create a RowSetListener and validate that notifyCursorMoved is called */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void baseRowSetTest0000(StubBaseRowSet rs) throws Exception { TestRowSetListener rsl = new TestRowSetListener(); rs.addRowSetListener(rsl); @@ -78,7 +84,8 @@ public class BaseRowSetTests extends CommonRowSetTests { /* * Create a RowSetListener and validate that notifyRowChanged is called */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void baseRowSetTest0001(StubBaseRowSet rs) throws Exception { TestRowSetListener rsl = new TestRowSetListener(); rs.addRowSetListener(rsl); @@ -89,7 +96,8 @@ public class BaseRowSetTests extends CommonRowSetTests { /* * Create a RowSetListener and validate that notifyRowSetChanged is called */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void baseRowSetTest0002(StubBaseRowSet rs) throws Exception { TestRowSetListener rsl = new TestRowSetListener(); rs.addRowSetListener(rsl); @@ -101,7 +109,8 @@ public class BaseRowSetTests extends CommonRowSetTests { * Create multiple RowSetListeners and validate that notifyRowSetChanged * is called on all listeners */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void baseRowSetTest0003(StubBaseRowSet rs) throws Exception { TestRowSetListener rsl = new TestRowSetListener(); TestRowSetListener rsl2 = new TestRowSetListener(); @@ -116,7 +125,8 @@ public class BaseRowSetTests extends CommonRowSetTests { * Create multiple RowSetListeners and validate that notifyRowChanged * is called on all listeners */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void baseRowSetTest0004(StubBaseRowSet rs) throws Exception { TestRowSetListener rsl = new TestRowSetListener(); TestRowSetListener rsl2 = new TestRowSetListener(); @@ -131,7 +141,8 @@ public class BaseRowSetTests extends CommonRowSetTests { * Create multiple RowSetListeners and validate that notifyCursorMoved * is called on all listeners */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void baseRowSetTest0005(StubBaseRowSet rs) throws Exception { TestRowSetListener rsl = new TestRowSetListener(); TestRowSetListener rsl2 = new TestRowSetListener(); @@ -146,7 +157,8 @@ public class BaseRowSetTests extends CommonRowSetTests { * Create a RowSetListener and validate that notifyRowSetChanged, * notifyRowChanged() and notifyCursorMoved are called */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void baseRowSetTest0006(StubBaseRowSet rs) throws Exception { TestRowSetListener rsl = new TestRowSetListener(); rs.addRowSetListener(rsl); @@ -163,7 +175,8 @@ public class BaseRowSetTests extends CommonRowSetTests { * Create multiple RowSetListeners and validate that notifyRowSetChanged, * notifyRowChanged() and notifyCursorMoved are called on all listeners */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void baseRowSetTest0007(StubBaseRowSet rs) throws Exception { TestRowSetListener rsl = new TestRowSetListener(); TestRowSetListener rsl2 = new TestRowSetListener(); @@ -185,7 +198,8 @@ public class BaseRowSetTests extends CommonRowSetTests { * remove the listener, invoke notifyRowSetChanged again and verify the * listner is not called */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void baseRowSetTest0008(StubBaseRowSet rs) throws Exception { TestRowSetListener rsl = new TestRowSetListener(); rs.addRowSetListener(rsl); @@ -202,7 +216,8 @@ public class BaseRowSetTests extends CommonRowSetTests { * Set the base parameters and validate that the value set is * the correct type and value */ - @Test(dataProvider = "testBaseParameters") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("testBaseParameters") public void baseRowSetTest0009(int pos, Object o) throws Exception { assertTrue(getParam(pos, o).getClass().isInstance(o)); assertTrue(o.equals(getParam(pos, o))); @@ -212,7 +227,8 @@ public class BaseRowSetTests extends CommonRowSetTests { * Set the complex parameters and validate that the value set is * the correct type */ - @Test(dataProvider = "testAdvancedParameters") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("testAdvancedParameters") public void baseRowSetTest0010(int pos, Object o) throws Exception { assertTrue(getParam(pos, o).getClass().isInstance(o)); } @@ -220,7 +236,8 @@ public class BaseRowSetTests extends CommonRowSetTests { /* * Validate setNull specifying the supported type values */ - @Test(dataProvider = "jdbcTypes") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("jdbcTypes") public void baseRowSetTest0011(Integer type) throws Exception { brs = new StubBaseRowSet(); brs.setNull(1, type); @@ -231,7 +248,8 @@ public class BaseRowSetTests extends CommonRowSetTests { * Validate setNull specifying the supported type values and that * typeName is set internally */ - @Test(dataProvider = "jdbcTypes") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("jdbcTypes") public void baseRowSetTest0012(Integer type) throws Exception { brs = new StubBaseRowSet(); brs.setNull(1, type, "SUPERHERO"); @@ -274,7 +292,8 @@ public class BaseRowSetTests extends CommonRowSetTests { /* * Validate that initParams() initializes the parameters */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void baseRowSetTest0016(StubBaseRowSet rs) throws Exception { rs.setInt(1, 1); rs.initParams(); @@ -285,8 +304,7 @@ public class BaseRowSetTests extends CommonRowSetTests { /* * DataProvider used to set parameters for basic types that are supported */ - @DataProvider(name = "testBaseParameters") - private Object[][] testBaseParameters() throws SQLException { + private Stream testBaseParameters() throws SQLException { Integer aInt = 1; Long aLong = Long.MAX_VALUE; Short aShort = Short.MIN_VALUE; @@ -320,34 +338,32 @@ public class BaseRowSetTests extends CommonRowSetTests { brs.setObject(17, query, Types.CHAR); brs.setObject(18, query, Types.CHAR, 0); - return new Object[][]{ - {1, aInt}, - {2, query}, - {3, aLong}, - {4, aBoolean}, - {5, aShort}, - {6, aDouble}, - {7, bd}, - {8, aFloat}, - {9, aByte}, - {10, aDate}, - {11, aTime}, - {12, aTimeStamp}, - {13, aDate}, - {14, aTime}, - {15, aTimeStamp}, - {16, query}, - {17, query}, - {18, query} - - }; + return Stream.of( + Arguments.of(1, aInt), + Arguments.of(2, query), + Arguments.of(3, aLong), + Arguments.of(4, aBoolean), + Arguments.of(5, aShort), + Arguments.of(6, aDouble), + Arguments.of(7, bd), + Arguments.of(8, aFloat), + Arguments.of(9, aByte), + Arguments.of(10, aDate), + Arguments.of(11, aTime), + Arguments.of(12, aTimeStamp), + Arguments.of(13, aDate), + Arguments.of(14, aTime), + Arguments.of(15, aTimeStamp), + Arguments.of(16, query), + Arguments.of(17, query), + Arguments.of(18, query) + ); } /* * DataProvider used to set advanced parameters for types that are supported */ - @DataProvider(name = "testAdvancedParameters") - private Object[][] testAdvancedParameters() throws SQLException { + private Stream testAdvancedParameters() throws SQLException { byte[] bytes = new byte[10]; Ref aRef = new SerialRef(new StubRef("INTEGER", query)); @@ -367,17 +383,17 @@ public class BaseRowSetTests extends CommonRowSetTests { brs.setUnicodeStream(8, is, query.length()); brs.setCharacterStream(9, rdr, query.length()); - return new Object[][]{ - {1, bytes}, - {2, is}, - {3, aRef}, - {4, aArray}, - {5, aBlob}, - {6, aClob}, - {7, is}, - {8, is}, - {9, rdr} - }; + return Stream.of( + Arguments.of(1, bytes), + Arguments.of(2, is), + Arguments.of(3, aRef), + Arguments.of(4, aArray), + Arguments.of(5, aBlob), + Arguments.of(6, aClob), + Arguments.of(7, is), + Arguments.of(8, is), + Arguments.of(9, rdr) + ); } /* diff --git a/test/jdk/javax/sql/testng/test/rowset/CommonRowSetTests.java b/test/jdk/javax/sql/test/rowset/CommonRowSetTests.java similarity index 67% rename from test/jdk/javax/sql/testng/test/rowset/CommonRowSetTests.java rename to test/jdk/javax/sql/test/rowset/CommonRowSetTests.java index 89492aefed5..5e8163fbf05 100644 --- a/test/jdk/javax/sql/testng/test/rowset/CommonRowSetTests.java +++ b/test/jdk/javax/sql/test/rowset/CommonRowSetTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,17 +43,23 @@ import java.util.Calendar; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Stream; import javax.sql.RowSet; import javax.sql.rowset.BaseRowSet; import javax.sql.rowset.CachedRowSet; import javax.sql.rowset.RowSetFactory; import javax.sql.rowset.RowSetMetaDataImpl; import javax.sql.rowset.RowSetProvider; -import org.testng.Assert; -import static org.testng.Assert.assertNull; -import static org.testng.Assert.assertTrue; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + import util.BaseTest; import util.StubBlob; import util.StubClob; @@ -98,7 +104,7 @@ public abstract class CommonRowSetTests extends BaseTest { try { rsf = RowSetProvider.newFactory(); } catch (SQLException ex) { - Assert.fail(ex.getMessage()); + fail(ex.getMessage()); } } @@ -111,84 +117,76 @@ public abstract class CommonRowSetTests extends BaseTest { * DataProvider used to specify the value to set and check for the * methods for fetch direction */ - @DataProvider(name = "rowSetFetchDirection") - protected Object[][] rowSetFetchDirection() throws Exception { + protected Stream rowSetFetchDirection() throws Exception { RowSet rs = newInstance(); - return new Object[][]{ - {rs, ResultSet.FETCH_FORWARD}, - {rs, ResultSet.FETCH_REVERSE}, - {rs, ResultSet.FETCH_UNKNOWN} - }; + return Stream.of( + Arguments.of(rs, ResultSet.FETCH_FORWARD), + Arguments.of(rs, ResultSet.FETCH_REVERSE), + Arguments.of(rs, ResultSet.FETCH_UNKNOWN) + ); } /* * DataProvider used to specify the value to set and check for the * methods for Cursor Scroll Type */ - @DataProvider(name = "rowSetScrollTypes") - protected Object[][] rowSetScrollTypes() throws Exception { + protected Stream rowSetScrollTypes() throws Exception { RowSet rs = newInstance(); - return new Object[][]{ - {rs, ResultSet.TYPE_FORWARD_ONLY}, - {rs, ResultSet.TYPE_SCROLL_INSENSITIVE}, - {rs, ResultSet.TYPE_SCROLL_SENSITIVE} - }; + return Stream.of( + Arguments.of(rs, ResultSet.TYPE_FORWARD_ONLY), + Arguments.of(rs, ResultSet.TYPE_SCROLL_INSENSITIVE), + Arguments.of(rs, ResultSet.TYPE_SCROLL_SENSITIVE) + ); } /* * DataProvider used to specify the value to set and check for * methods using transaction isolation types */ - @DataProvider(name = "rowSetIsolationTypes") - protected Object[][] rowSetIsolationTypes() throws Exception { + protected Stream rowSetIsolationTypes() throws Exception { RowSet rs = newInstance(); - return new Object[][]{ - {rs, Connection.TRANSACTION_NONE}, - {rs, Connection.TRANSACTION_READ_COMMITTED}, - {rs, Connection.TRANSACTION_READ_UNCOMMITTED}, - {rs, Connection.TRANSACTION_REPEATABLE_READ}, - {rs, Connection.TRANSACTION_SERIALIZABLE} - }; + return Stream.of( + Arguments.of(rs, Connection.TRANSACTION_NONE), + Arguments.of(rs, Connection.TRANSACTION_READ_COMMITTED), + Arguments.of(rs, Connection.TRANSACTION_READ_UNCOMMITTED), + Arguments.of(rs, Connection.TRANSACTION_REPEATABLE_READ), + Arguments.of(rs, Connection.TRANSACTION_SERIALIZABLE) + ); } /* * DataProvider used to specify the value to set and check for the * methods for Concurrency */ - @DataProvider(name = "rowSetConcurrencyTypes") - protected Object[][] rowSetConcurrencyTypes() throws Exception { + protected Stream rowSetConcurrencyTypes() throws Exception { RowSet rs = newInstance(); - return new Object[][]{ - {rs, ResultSet.CONCUR_READ_ONLY}, - {rs, ResultSet.CONCUR_UPDATABLE} - }; + return Stream.of( + Arguments.of(rs, ResultSet.CONCUR_READ_ONLY), + Arguments.of(rs, ResultSet.CONCUR_UPDATABLE) + ); } /* * DataProvider used to specify the value to set and check for * methods using boolean values */ - @DataProvider(name = "rowSetTrueFalse") - protected Object[][] rowSetTrueFalse() throws Exception { + protected Stream rowSetTrueFalse() throws Exception { RowSet rs = newInstance(); - return new Object[][]{ - {rs, true}, - {rs, false} - }; + return Stream.of( + Arguments.of(rs, true), + Arguments.of(rs, false) + ); } /* * DataProvider used to specify the type of RowSet to use. We also must * initialize the RowSet */ - @DataProvider(name = "rowSetType") - protected Object[][] rowSetType() throws Exception { + protected Stream rowSetType() throws Exception { RowSet rs = newInstance(); - return new Object[][]{ - {rs} - }; + return Stream.of(rs); } /* @@ -503,7 +501,8 @@ public abstract class CommonRowSetTests extends BaseTest { /* * Validate that getCommand() returns null by default */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0000(RowSet rs) { assertNull(rs.getCommand()); } @@ -511,7 +510,8 @@ public abstract class CommonRowSetTests extends BaseTest { /* * Validate that getCommand() returns command specified to setCommand */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0001(RowSet rs) throws Exception { rs.setCommand(query); assertTrue(rs.getCommand().equals(query)); @@ -521,7 +521,8 @@ public abstract class CommonRowSetTests extends BaseTest { /* * Validate that getCurrency() returns the correct default value */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0002(RowSet rs) throws Exception { assertTrue(rs.getConcurrency() == ResultSet.CONCUR_UPDATABLE); } @@ -530,7 +531,8 @@ public abstract class CommonRowSetTests extends BaseTest { * Validate that getCurrency() returns the correct value * after a call to setConcurrency()) */ - @Test(dataProvider = "rowSetConcurrencyTypes") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetConcurrencyTypes") public void commonRowSetTest0003(RowSet rs, int concurType) throws Exception { rs.setConcurrency(concurType); assertTrue(rs.getConcurrency() == concurType); @@ -539,15 +541,17 @@ public abstract class CommonRowSetTests extends BaseTest { /* * Validate that getCurrency() throws a SQLException for an invalid value */ - @Test(dataProvider = "rowSetType", expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0004(RowSet rs) throws Exception { - rs.setConcurrency(ResultSet.CLOSE_CURSORS_AT_COMMIT); + assertThrows(SQLException.class, () -> rs.setConcurrency(ResultSet.CLOSE_CURSORS_AT_COMMIT)); } /* * Validate that getDataSourceName() returns null by default */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0005(RowSet rs) throws Exception { assertTrue(rs.getDataSourceName() == null); } @@ -556,7 +560,8 @@ public abstract class CommonRowSetTests extends BaseTest { * Validate that getDataSourceName() returns the value specified * by setDataSourceName() and getUrl() returns null */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0006(RowSet rs) throws Exception { rs.setUrl(url); rs.setDataSourceName(dsName); @@ -568,16 +573,20 @@ public abstract class CommonRowSetTests extends BaseTest { * Validate that setDataSourceName() throws a SQLException for an empty * String specified for the data source name */ - @Test(dataProvider = "rowSetType", expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0007(RowSet rs) throws Exception { - String dsname = ""; - rs.setDataSourceName(dsname); + assertThrows(SQLException.class, () -> { + String dsname = ""; + rs.setDataSourceName(dsname); + }); } /* * Validate that getEscapeProcessing() returns false by default */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0008(RowSet rs) throws Exception { assertTrue(rs.getEscapeProcessing()); } @@ -586,7 +595,8 @@ public abstract class CommonRowSetTests extends BaseTest { * Validate that getEscapeProcessing() returns value set by * setEscapeProcessing() */ - @Test(dataProvider = "rowSetTrueFalse") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetTrueFalse") public void commonRowSetTest0009(RowSet rs, boolean val) throws Exception { rs.setEscapeProcessing(val); assertTrue(rs.getEscapeProcessing() == val); @@ -595,7 +605,8 @@ public abstract class CommonRowSetTests extends BaseTest { /* * Validate that getFetchDirection() returns the correct default value */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0010(RowSet rs) throws Exception { assertTrue(rs.getFetchDirection() == ResultSet.FETCH_FORWARD); } @@ -604,7 +615,8 @@ public abstract class CommonRowSetTests extends BaseTest { * Validate that getFetchDirection() returns the value set by * setFetchDirection() */ - @Test(dataProvider = "rowSetFetchDirection") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetFetchDirection") public void commonRowSetTest0011(RowSet rs, int direction) throws Exception { rs.setFetchDirection(direction); assertTrue(rs.getFetchDirection() == direction); @@ -613,26 +625,31 @@ public abstract class CommonRowSetTests extends BaseTest { /* * Validate that setFetchSize() throws a SQLException for an invalid value */ - @Test(dataProvider = "rowSetType", expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0013(RowSet rs) throws Exception { - rs.setFetchSize(-1); + assertThrows(SQLException.class, () -> rs.setFetchSize(-1)); } /* * Validate that setFetchSize() throws a SQLException for a * value greater than getMaxRows() */ - @Test(dataProvider = "rowSetType", expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0014(RowSet rs) throws Exception { - rs.setMaxRows(5); - rs.setFetchSize(rs.getMaxRows() + 1); + assertThrows(SQLException.class, () -> { + rs.setMaxRows(5); + rs.setFetchSize(rs.getMaxRows() + 1); + }); } /* * Validate that getFetchSize() returns the correct value after * setFetchSize() has been called */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0015(RowSet rs) throws Exception { int maxRows = 150; rs.setFetchSize(0); @@ -647,16 +664,18 @@ public abstract class CommonRowSetTests extends BaseTest { /* * Validate that setMaxFieldSize() throws a SQLException for an invalid value */ - @Test(dataProvider = "rowSetType", expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0016(RowSet rs) throws Exception { - rs.setMaxFieldSize(-1); + assertThrows(SQLException.class, () -> rs.setMaxFieldSize(-1)); } /* * Validate that getMaxFieldSize() returns the value set by * setMaxFieldSize() */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0017(RowSet rs) throws Exception { rs.setMaxFieldSize(0); assertTrue(rs.getMaxFieldSize() == 0); @@ -670,7 +689,8 @@ public abstract class CommonRowSetTests extends BaseTest { * Validate that isReadOnly() returns value set by * setReadOnly() */ - @Test(dataProvider = "rowSetTrueFalse") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetTrueFalse") public void commonRowSetTest0018(RowSet rs, boolean val) throws Exception { rs.setReadOnly(val); assertTrue(rs.isReadOnly() == val); @@ -680,7 +700,8 @@ public abstract class CommonRowSetTests extends BaseTest { * Validate that getTransactionIsolation() returns value set by * setTransactionIsolation() */ - @Test(dataProvider = "rowSetIsolationTypes") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetIsolationTypes") public void commonRowSetTest0019(RowSet rs, int val) throws Exception { rs.setTransactionIsolation(val); assertTrue(rs.getTransactionIsolation() == val); @@ -689,7 +710,8 @@ public abstract class CommonRowSetTests extends BaseTest { /* * Validate that getType() returns value set by setType() */ - @Test(dataProvider = "rowSetScrollTypes") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetScrollTypes") public void commonRowSetTest0020(RowSet rs, int val) throws Exception { rs.setType(val); assertTrue(rs.getType() == val); @@ -699,7 +721,8 @@ public abstract class CommonRowSetTests extends BaseTest { * Validate that getEscapeProcessing() returns value set by * setEscapeProcessing() */ - @Test(dataProvider = "rowSetTrueFalse") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetTrueFalse") public void commonRowSetTest0021(BaseRowSet rs, boolean val) throws Exception { rs.setShowDeleted(val); assertTrue(rs.getShowDeleted() == val); @@ -709,7 +732,8 @@ public abstract class CommonRowSetTests extends BaseTest { * Validate that getTypeMap() returns same value set by * setTypeMap() */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0022(RowSet rs) throws Exception { Map> map = new HashMap<>(); map.put("SUPERHERO", Class.forName("util.SuperHero")); @@ -721,7 +745,8 @@ public abstract class CommonRowSetTests extends BaseTest { * Validate that getUsername() returns same value set by * setUsername() */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0023(RowSet rs) throws Exception { rs.setUsername(user); assertTrue(rs.getUsername().equals(user)); @@ -731,7 +756,8 @@ public abstract class CommonRowSetTests extends BaseTest { * Validate that getPassword() returns same password set by * setPassword() */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0024(RowSet rs) throws Exception { rs.setPassword(password); assertTrue(rs.getPassword().equals(password)); @@ -741,7 +767,8 @@ public abstract class CommonRowSetTests extends BaseTest { * Validate that getQueryTimeout() returns same value set by * setQueryTimeout() and that 0 is a valid timeout value */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0025(RowSet rs) throws Exception { int timeout = 0; rs.setQueryTimeout(timeout); @@ -752,7 +779,8 @@ public abstract class CommonRowSetTests extends BaseTest { * Validate that getQueryTimeout() returns same value set by * setQueryTimeout() and that 0 is a valid timeout value */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0026(RowSet rs) throws Exception { int timeout = 10000; rs.setQueryTimeout(timeout); @@ -763,9 +791,10 @@ public abstract class CommonRowSetTests extends BaseTest { * Validate that setQueryTimeout() throws a SQLException for a timeout * value < 0 */ - @Test(dataProvider = "rowSetType", expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0027(RowSet rs) throws Exception { - rs.setQueryTimeout(-1); + assertThrows(SQLException.class, () -> rs.setQueryTimeout(-1)); } @@ -773,7 +802,8 @@ public abstract class CommonRowSetTests extends BaseTest { * Validate addRowSetListener does not throw an Exception when null is * passed as the parameter */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0028(RowSet rs) throws Exception { rs.addRowSetListener(null); } @@ -782,7 +812,8 @@ public abstract class CommonRowSetTests extends BaseTest { * Validate removeRowSetListener does not throw an Exception when null is * passed as the parameter */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0029(RowSet rs) throws Exception { rs.removeRowSetListener(null); } @@ -790,7 +821,8 @@ public abstract class CommonRowSetTests extends BaseTest { /* * Set two parameters and then validate clearParameters() will clear them */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0030(BaseRowSet rs) throws Exception { rs.setInt(1, 1); rs.setString(2, query); @@ -803,7 +835,8 @@ public abstract class CommonRowSetTests extends BaseTest { * Validate that getURL() returns same value set by * setURL() */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0031(RowSet rs) throws Exception { rs.setUrl(url); assertTrue(rs.getUrl().equals(url)); @@ -813,560 +846,614 @@ public abstract class CommonRowSetTests extends BaseTest { * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0100(RowSet rs) throws Exception { - InputStream is = null; - rs.setAsciiStream(1, is); + assertThrows(SQLFeatureNotSupportedException.class, () -> { + InputStream is = null; + rs.setAsciiStream(1, is); + }); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0101(RowSet rs) throws Exception { - InputStream is = null; - rs.setAsciiStream("one", is); + assertThrows(SQLFeatureNotSupportedException.class, () -> { + InputStream is = null; + rs.setAsciiStream("one", is); + }); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0102(RowSet rs) throws Exception { - InputStream is = null; - rs.setAsciiStream("one", is, query.length()); + assertThrows(SQLFeatureNotSupportedException.class, () -> { + InputStream is = null; + rs.setAsciiStream("one", is, query.length()); + }); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0103(RowSet rs) throws Exception { - InputStream is = null; - rs.setBinaryStream(1, is); + assertThrows(SQLFeatureNotSupportedException.class, () -> { + InputStream is = null; + rs.setBinaryStream(1, is); + }); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0104(RowSet rs) throws Exception { - InputStream is = null; - rs.setBinaryStream("one", is); + assertThrows(SQLFeatureNotSupportedException.class, () -> { + InputStream is = null; + rs.setBinaryStream("one", is); + }); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0105(RowSet rs) throws Exception { - InputStream is = null; - rs.setBinaryStream("one", is, query.length()); + assertThrows(SQLFeatureNotSupportedException.class, () -> { + InputStream is = null; + rs.setBinaryStream("one", is, query.length()); + }); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0106(RowSet rs) throws Exception { - rs.setBigDecimal("one", BigDecimal.ONE); + assertThrows(SQLFeatureNotSupportedException.class, () -> rs.setBigDecimal("one", BigDecimal.ONE)); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0107(RowSet rs) throws Exception { - InputStream is = null; - rs.setBlob(1, is); + assertThrows(SQLFeatureNotSupportedException.class, () -> { + InputStream is = null; + rs.setBlob(1, is); + }); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0108(RowSet rs) throws Exception { - InputStream is = null; - rs.setBlob("one", is); + assertThrows(SQLFeatureNotSupportedException.class, () -> { + InputStream is = null; + rs.setBlob("one", is); + }); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0109(RowSet rs) throws Exception { - InputStream is = null; - rs.setBlob("one", is, query.length()); + assertThrows(SQLFeatureNotSupportedException.class, () -> { + InputStream is = null; + rs.setBlob("one", is, query.length()); + }); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0110(RowSet rs) throws Exception { - rs.setBlob("one", new StubBlob()); + assertThrows(SQLFeatureNotSupportedException.class, () -> rs.setBlob("one", new StubBlob())); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0111(RowSet rs) throws Exception { - rs.setBoolean("one", true); + assertThrows(SQLFeatureNotSupportedException.class, () -> rs.setBoolean("one", true)); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0112(RowSet rs) throws Exception { - byte b = 1; - rs.setByte("one", b); + assertThrows(SQLFeatureNotSupportedException.class, () -> { + byte b = 1; + rs.setByte("one", b); + }); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0113(RowSet rs) throws Exception { - byte b = 1; - rs.setBytes("one", new byte[10]); + assertThrows(SQLFeatureNotSupportedException.class, () -> { + byte b = 1; + rs.setBytes("one", new byte[10]); + }); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0114(RowSet rs) throws Exception { - Reader rdr = null; - rs.setCharacterStream("one", rdr, query.length()); + assertThrows(SQLFeatureNotSupportedException.class, () -> { + Reader rdr = null; + rs.setCharacterStream("one", rdr, query.length()); + }); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0115(RowSet rs) throws Exception { - Reader rdr = null; - rs.setCharacterStream("one", rdr); + assertThrows(SQLFeatureNotSupportedException.class, () -> { + Reader rdr = null; + rs.setCharacterStream("one", rdr); + }); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0116(RowSet rs) throws Exception { - Reader rdr = null; - rs.setCharacterStream(1, rdr); + assertThrows(SQLFeatureNotSupportedException.class, () -> { + Reader rdr = null; + rs.setCharacterStream(1, rdr); + }); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0117(RowSet rs) throws Exception { - Reader rdr = null; - rs.setClob(1, rdr); + assertThrows(SQLFeatureNotSupportedException.class, () -> { + Reader rdr = null; + rs.setClob(1, rdr); + }); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0118(RowSet rs) throws Exception { - Reader rdr = null; - rs.setClob("one", rdr); + assertThrows(SQLFeatureNotSupportedException.class, () -> { + Reader rdr = null; + rs.setClob("one", rdr); + }); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0119(RowSet rs) throws Exception { - Reader rdr = null; - rs.setClob("one", rdr, query.length()); + assertThrows(SQLFeatureNotSupportedException.class, () -> { + Reader rdr = null; + rs.setClob("one", rdr, query.length()); + }); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0120(RowSet rs) throws Exception { - rs.setClob("one", new StubClob()); + assertThrows(SQLFeatureNotSupportedException.class, () -> rs.setClob("one", new StubClob())); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0121(RowSet rs) throws Exception { - rs.setDate("one", Date.valueOf(LocalDate.now())); + assertThrows(SQLFeatureNotSupportedException.class, () -> rs.setDate("one", Date.valueOf(LocalDate.now()))); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0122(RowSet rs) throws Exception { - rs.setDate("one", Date.valueOf(LocalDate.now()), - Calendar.getInstance()); + assertThrows(SQLFeatureNotSupportedException.class, () -> rs.setDate("one", Date.valueOf(LocalDate.now()), + Calendar.getInstance())); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0123(RowSet rs) throws Exception { - rs.setTime("one", Time.valueOf(LocalTime.now())); + assertThrows(SQLFeatureNotSupportedException.class, () -> rs.setTime("one", Time.valueOf(LocalTime.now()))); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0124(RowSet rs) throws Exception { - rs.setTime("one", Time.valueOf(LocalTime.now()), - Calendar.getInstance()); + assertThrows(SQLFeatureNotSupportedException.class, () -> rs.setTime("one", Time.valueOf(LocalTime.now()), + Calendar.getInstance())); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0125(RowSet rs) throws Exception { - rs.setTimestamp("one", Timestamp.valueOf(LocalDateTime.now())); + assertThrows(SQLFeatureNotSupportedException.class, () -> rs.setTimestamp("one", Timestamp.valueOf(LocalDateTime.now()))); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0126(RowSet rs) throws Exception { - rs.setTimestamp("one", Timestamp.valueOf(LocalDateTime.now()), - Calendar.getInstance()); + assertThrows(SQLFeatureNotSupportedException.class, () -> rs.setTimestamp("one", Timestamp.valueOf(LocalDateTime.now()), + Calendar.getInstance())); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0127(RowSet rs) throws Exception { - rs.setDouble("one", 2.0d); + assertThrows(SQLFeatureNotSupportedException.class, () -> rs.setDouble("one", 2.0d)); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0128(RowSet rs) throws Exception { - rs.setFloat("one", 2.0f); + assertThrows(SQLFeatureNotSupportedException.class, () -> rs.setFloat("one", 2.0f)); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0129(RowSet rs) throws Exception { - rs.setInt("one", 21); + assertThrows(SQLFeatureNotSupportedException.class, () -> rs.setInt("one", 21)); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0130(RowSet rs) throws Exception { - rs.setLong("one", 21l); + assertThrows(SQLFeatureNotSupportedException.class, () -> rs.setLong("one", 21l)); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0131(RowSet rs) throws Exception { - Reader rdr = null; - rs.setNCharacterStream("one", rdr, query.length()); + assertThrows(SQLFeatureNotSupportedException.class, () -> { + Reader rdr = null; + rs.setNCharacterStream("one", rdr, query.length()); + }); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0132(RowSet rs) throws Exception { - Reader rdr = null; - rs.setNCharacterStream("one", rdr); + assertThrows(SQLFeatureNotSupportedException.class, () -> { + Reader rdr = null; + rs.setNCharacterStream("one", rdr); + }); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0133(RowSet rs) throws Exception { - Reader rdr = null; - rs.setNCharacterStream(1, rdr); + assertThrows(SQLFeatureNotSupportedException.class, () -> { + Reader rdr = null; + rs.setNCharacterStream(1, rdr); + }); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0134(RowSet rs) throws Exception { - Reader rdr = null; - rs.setNCharacterStream(1, rdr, query.length()); + assertThrows(SQLFeatureNotSupportedException.class, () -> { + Reader rdr = null; + rs.setNCharacterStream(1, rdr, query.length()); + }); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0135(RowSet rs) throws Exception { - Reader rdr = null; - rs.setClob("one", rdr); + assertThrows(SQLFeatureNotSupportedException.class, () -> { + Reader rdr = null; + rs.setClob("one", rdr); + }); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0136(RowSet rs) throws Exception { - Reader rdr = null; - rs.setClob("one", rdr, query.length()); + assertThrows(SQLFeatureNotSupportedException.class, () -> { + Reader rdr = null; + rs.setClob("one", rdr, query.length()); + }); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0137(RowSet rs) throws Exception { - rs.setNClob("one", new StubNClob()); + assertThrows(SQLFeatureNotSupportedException.class, () -> rs.setNClob("one", new StubNClob())); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0138(RowSet rs) throws Exception { - Reader rdr = null; - rs.setNClob(1, rdr); + assertThrows(SQLFeatureNotSupportedException.class, () -> { + Reader rdr = null; + rs.setNClob(1, rdr); + }); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0139(RowSet rs) throws Exception { - Reader rdr = null; - rs.setNClob(1, rdr, query.length()); + assertThrows(SQLFeatureNotSupportedException.class, () -> { + Reader rdr = null; + rs.setNClob(1, rdr, query.length()); + }); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0140(RowSet rs) throws Exception { - rs.setNClob(1, new StubNClob()); + assertThrows(SQLFeatureNotSupportedException.class, () -> rs.setNClob(1, new StubNClob())); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0141(RowSet rs) throws Exception { - rs.setNString(1, query); + assertThrows(SQLFeatureNotSupportedException.class, () -> rs.setNString(1, query)); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0142(RowSet rs) throws Exception { - rs.setNull("one", Types.INTEGER); + assertThrows(SQLFeatureNotSupportedException.class, () -> rs.setNull("one", Types.INTEGER)); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0143(RowSet rs) throws Exception { - rs.setNull("one", Types.INTEGER, "my.type"); + assertThrows(SQLFeatureNotSupportedException.class, () -> rs.setNull("one", Types.INTEGER, "my.type")); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0144(RowSet rs) throws Exception { - rs.setObject("one", query, Types.VARCHAR); + assertThrows(SQLFeatureNotSupportedException.class, () -> rs.setObject("one", query, Types.VARCHAR)); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0145(RowSet rs) throws Exception { - rs.setObject("one", query, Types.VARCHAR, 0); + assertThrows(SQLFeatureNotSupportedException.class, () -> rs.setObject("one", query, Types.VARCHAR, 0)); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0146(RowSet rs) throws Exception { - rs.setObject("one", query); + assertThrows(SQLFeatureNotSupportedException.class, () -> rs.setObject("one", query)); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0147(RowSet rs) throws Exception { - RowId aRowid = null; - rs.setRowId("one", aRowid); + assertThrows(SQLFeatureNotSupportedException.class, () -> { + RowId aRowid = null; + rs.setRowId("one", aRowid); + }); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0148(RowSet rs) throws Exception { - rs.setSQLXML("one", new StubSQLXML()); + assertThrows(SQLFeatureNotSupportedException.class, () -> rs.setSQLXML("one", new StubSQLXML())); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0149(RowSet rs) throws Exception { - rs.setSQLXML(1, new StubSQLXML()); + assertThrows(SQLFeatureNotSupportedException.class, () -> rs.setSQLXML(1, new StubSQLXML())); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0150(RowSet rs) throws Exception { - rs.setNString(1, query); + assertThrows(SQLFeatureNotSupportedException.class, () -> rs.setNString(1, query)); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0151(RowSet rs) throws Exception { - rs.setNString("one", query); + assertThrows(SQLFeatureNotSupportedException.class, () -> rs.setNString("one", query)); } /* * This method is currently not implemented in BaseRowSet and will * throw a SQLFeatureNotSupportedException */ - @Test(dataProvider = "rowSetType", - expectedExceptions = SQLFeatureNotSupportedException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonRowSetTest0152(RowSet rs) throws Exception { - short val = 21; - rs.setShort("one", val); + assertThrows(SQLFeatureNotSupportedException.class, () -> { + short val = 21; + rs.setShort("one", val); + }); } } diff --git a/test/jdk/javax/sql/testng/test/rowset/RowSetFactoryTests.java b/test/jdk/javax/sql/test/rowset/RowSetFactoryTests.java similarity index 80% rename from test/jdk/javax/sql/testng/test/rowset/RowSetFactoryTests.java rename to test/jdk/javax/sql/test/rowset/RowSetFactoryTests.java index 72a4341c7aa..480033afc2b 100644 --- a/test/jdk/javax/sql/testng/test/rowset/RowSetFactoryTests.java +++ b/test/jdk/javax/sql/test/rowset/RowSetFactoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,11 +23,15 @@ package test.rowset; import java.sql.SQLException; +import java.util.stream.Stream; import javax.sql.rowset.RowSetFactory; import javax.sql.rowset.RowSetProvider; -import static org.testng.Assert.*; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + import util.BaseTest; public class RowSetFactoryTests extends BaseTest { @@ -50,7 +54,8 @@ public class RowSetFactoryTests extends BaseTest { * Validate that the RowSetFactory returned by RowSetProvider.newFactory() * returns the correct RowSet implementations */ - @Test(dataProvider = "RowSetValues", enabled = true) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("RowSetValues") public void test(RowSetFactory rsf, String impl) throws SQLException { validateRowSetImpl(rsf, impl); } @@ -98,22 +103,20 @@ public class RowSetFactoryTests extends BaseTest { * DataProvider used to provide the RowSetFactory and the RowSet * implementation that should be returned */ - @DataProvider(name = "RowSetValues") - private Object[][] RowSetValues() throws SQLException { + private Stream RowSetValues() throws SQLException { RowSetFactory rsf = RowSetProvider.newFactory(); RowSetFactory rsf1 = RowSetProvider.newFactory(STUB_FACTORY_CLASSNAME, null); - return new Object[][]{ - {rsf, DEFAULT_CACHEDROWSET_CLASSNAME}, - {rsf, DEFAULT_FILTEREDROWSET_CLASSNAME}, - {rsf, DEFAULT_JDBCROWSET_CLASSNAME}, - {rsf, DEFAULT_JOINROWSET_CLASSNAME}, - {rsf, DEFAULT_WEBROWSET_CLASSNAME}, - {rsf1, STUB_CACHEDROWSET_CLASSNAME}, - {rsf1, STUB_FILTEREDROWSET_CLASSNAME}, - {rsf1, STUB_JDBCROWSET_CLASSNAME}, - {rsf1, STUB_JOINROWSET_CLASSNAME}, - {rsf1, STUB_WEBROWSET_CLASSNAME} - - }; + return Stream.of( + Arguments.of(rsf, DEFAULT_CACHEDROWSET_CLASSNAME), + Arguments.of(rsf, DEFAULT_FILTEREDROWSET_CLASSNAME), + Arguments.of(rsf, DEFAULT_JDBCROWSET_CLASSNAME), + Arguments.of(rsf, DEFAULT_JOINROWSET_CLASSNAME), + Arguments.of(rsf, DEFAULT_WEBROWSET_CLASSNAME), + Arguments.of(rsf1, STUB_CACHEDROWSET_CLASSNAME), + Arguments.of(rsf1, STUB_FILTEREDROWSET_CLASSNAME), + Arguments.of(rsf1, STUB_JDBCROWSET_CLASSNAME), + Arguments.of(rsf1, STUB_JOINROWSET_CLASSNAME), + Arguments.of(rsf1, STUB_WEBROWSET_CLASSNAME) + ); } } diff --git a/test/jdk/javax/sql/testng/test/rowset/RowSetMetaDataTests.java b/test/jdk/javax/sql/test/rowset/RowSetMetaDataTests.java similarity index 55% rename from test/jdk/javax/sql/testng/test/rowset/RowSetMetaDataTests.java rename to test/jdk/javax/sql/test/rowset/RowSetMetaDataTests.java index 8a944a8bbb1..59dc4f43033 100644 --- a/test/jdk/javax/sql/testng/test/rowset/RowSetMetaDataTests.java +++ b/test/jdk/javax/sql/test/rowset/RowSetMetaDataTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,12 +25,19 @@ package test.rowset; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Types; +import java.util.stream.IntStream; +import java.util.stream.Stream; import javax.sql.RowSetMetaData; import javax.sql.rowset.RowSetMetaDataImpl; -import static org.testng.Assert.*; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import org.junit.jupiter.params.provider.ValueSource; import util.BaseTest; public class RowSetMetaDataTests extends BaseTest { @@ -40,7 +47,7 @@ public class RowSetMetaDataTests extends BaseTest { // Instance to be used within the tests private RowSetMetaDataImpl rsmd; - @BeforeMethod + @BeforeEach public void setUpMethod() throws Exception { rsmd = new RowSetMetaDataImpl(); rsmd.setColumnCount(MAX_COLUMNS); @@ -49,325 +56,325 @@ public class RowSetMetaDataTests extends BaseTest { /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test(Integer col) throws Exception { - rsmd.getCatalogName(col); + assertThrows(SQLException.class, () -> rsmd.getCatalogName(col)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test01(Integer col) throws Exception { - rsmd.getColumnClassName(col); + assertThrows(SQLException.class, () -> rsmd.getColumnClassName(col)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test02(Integer col) throws Exception { - rsmd.getColumnDisplaySize(col); + assertThrows(SQLException.class, () -> rsmd.getColumnDisplaySize(col)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test03(Integer col) throws Exception { - rsmd.getColumnLabel(col); + assertThrows(SQLException.class, () -> rsmd.getColumnLabel(col)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test04(Integer col) throws Exception { - rsmd.getColumnName(col); + assertThrows(SQLException.class, () -> rsmd.getColumnName(col)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test05(Integer col) throws Exception { - rsmd.getColumnType(col); + assertThrows(SQLException.class, () -> rsmd.getColumnType(col)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test06(Integer col) throws Exception { - rsmd.getColumnTypeName(col); + assertThrows(SQLException.class, () -> rsmd.getColumnTypeName(col)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test07(Integer col) throws Exception { - rsmd.getPrecision(col); + assertThrows(SQLException.class, () -> rsmd.getPrecision(col)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test08(Integer col) throws Exception { - rsmd.getScale(col); + assertThrows(SQLException.class, () -> rsmd.getScale(col)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test09(Integer col) throws Exception { - rsmd.getSchemaName(col); + assertThrows(SQLException.class, () -> rsmd.getSchemaName(col)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test10(Integer col) throws Exception { - rsmd.getTableName(col); + assertThrows(SQLException.class, () -> rsmd.getTableName(col)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test11(Integer col) throws Exception { - rsmd.isAutoIncrement(col); + assertThrows(SQLException.class, () -> rsmd.isAutoIncrement(col)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test12(Integer col) throws Exception { - rsmd.isCaseSensitive(col); + assertThrows(SQLException.class, () -> rsmd.isCaseSensitive(col)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test13(Integer col) throws Exception { - rsmd.isCurrency(col); + assertThrows(SQLException.class, () -> rsmd.isCurrency(col)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test14(Integer col) throws Exception { - rsmd.isDefinitelyWritable(col); + assertThrows(SQLException.class, () -> rsmd.isDefinitelyWritable(col)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test15(Integer col) throws Exception { - rsmd.isNullable(col); + assertThrows(SQLException.class, () -> rsmd.isNullable(col)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test16(Integer col) throws Exception { - rsmd.isReadOnly(col); + assertThrows(SQLException.class, () -> rsmd.isReadOnly(col)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test17(Integer col) throws Exception { - rsmd.isSearchable(col); + assertThrows(SQLException.class, () -> rsmd.isSearchable(col)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test18(Integer col) throws Exception { - rsmd.isSigned(col); + assertThrows(SQLException.class, () -> rsmd.isSigned(col)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test19(Integer col) throws Exception { - rsmd.isWritable(col); + assertThrows(SQLException.class, () -> rsmd.isWritable(col)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test20(Integer col) throws Exception { - rsmd.setAutoIncrement(col, true); + assertThrows(SQLException.class, () -> rsmd.setAutoIncrement(col, true)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test21(Integer col) throws Exception { - rsmd.setCaseSensitive(col, true); + assertThrows(SQLException.class, () -> rsmd.setCaseSensitive(col, true)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test22(Integer col) throws Exception { - rsmd.setCatalogName(col, null); + assertThrows(SQLException.class, () -> rsmd.setCatalogName(col, null)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test23(Integer col) throws Exception { - rsmd.setColumnDisplaySize(col, 5); + assertThrows(SQLException.class, () -> rsmd.setColumnDisplaySize(col, 5)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test24(Integer col) throws Exception { - rsmd.setColumnLabel(col, "label"); + assertThrows(SQLException.class, () -> rsmd.setColumnLabel(col, "label")); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test25(Integer col) throws Exception { - rsmd.setColumnName(col, "F1"); + assertThrows(SQLException.class, () -> rsmd.setColumnName(col, "F1")); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test26(Integer col) throws Exception { - rsmd.setColumnType(col, Types.CHAR); + assertThrows(SQLException.class, () -> rsmd.setColumnType(col, Types.CHAR)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test27(Integer col) throws Exception { - rsmd.setColumnTypeName(col, "F1"); + assertThrows(SQLException.class, () -> rsmd.setColumnTypeName(col, "F1")); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test28(Integer col) throws Exception { - rsmd.setCurrency(col, true); + assertThrows(SQLException.class, () -> rsmd.setCurrency(col, true)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test29(Integer col) throws Exception { - rsmd.setNullable(col, ResultSetMetaData.columnNoNulls); + assertThrows(SQLException.class, () -> rsmd.setNullable(col, ResultSetMetaData.columnNoNulls)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test30(Integer col) throws Exception { - rsmd.setPrecision(col, 2); + assertThrows(SQLException.class, () -> rsmd.setPrecision(col, 2)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test31(Integer col) throws Exception { - rsmd.setScale(col, 2); + assertThrows(SQLException.class, () -> rsmd.setScale(col, 2)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test32(Integer col) throws Exception { - rsmd.setSchemaName(col, "Gotham"); + assertThrows(SQLException.class, () -> rsmd.setSchemaName(col, "Gotham")); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test33(Integer col) throws Exception { - rsmd.setSearchable(col, false); + assertThrows(SQLException.class, () -> rsmd.setSearchable(col, false)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test34(Integer col) throws Exception { - rsmd.setSigned(col, false); + assertThrows(SQLException.class, () -> rsmd.setSigned(col, false)); } /* * Validate a SQLException is thrown for an invalid column index */ - @Test(dataProvider = "invalidColumnRanges", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("invalidColumnRanges") public void test35(Integer col) throws Exception { - rsmd.setTableName(col, "SUPERHEROS"); + assertThrows(SQLException.class, () -> rsmd.setTableName(col, "SUPERHEROS")); } /* @@ -375,7 +382,8 @@ public class RowSetMetaDataTests extends BaseTest { * Note: Once setColumnClassName is added to RowSetMetaData, this * method will need to change. */ - @Test(dataProvider = "columnClassNames") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("columnClassNames") public void test36(Integer type, String name) throws Exception { rsmd.setColumnType(1, type); assertTrue(rsmd.getColumnClassName(1).equals(name)); @@ -385,7 +393,8 @@ public class RowSetMetaDataTests extends BaseTest { * Validate that all of the methods are accessible and the correct value * is returned for each column */ - @Test(dataProvider = "columnRanges") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("columnRanges") public void test37(Integer col) throws Exception { rsmd.setAutoIncrement(col, true); assertTrue(rsmd.isAutoIncrement(col)); @@ -429,7 +438,8 @@ public class RowSetMetaDataTests extends BaseTest { /* * Validate that the proper values are accepted by setNullable */ - @Test(dataProvider = "validSetNullableValues") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("validSetNullableValues") public void test38(Integer val) throws Exception { rsmd.setNullable(1, val); } @@ -437,7 +447,8 @@ public class RowSetMetaDataTests extends BaseTest { /* * Validate that the correct type is returned for the column */ - @Test(dataProvider = "jdbcTypes") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("jdbcTypes") public void test39(Integer type) throws Exception { rsmd.setColumnType(1, type); assertTrue(type == rsmd.getColumnType(1)); @@ -446,7 +457,8 @@ public class RowSetMetaDataTests extends BaseTest { /* * Validate that the correct value is returned from the isXXX methods */ - @Test(dataProvider = "trueFalse") + @ParameterizedTest(autoCloseArguments = false) + @ValueSource(booleans = {true, false}) public void test40(Boolean b) throws Exception { rsmd.setAutoIncrement(1, b); rsmd.setCaseSensitive(1, b); @@ -483,73 +495,62 @@ public class RowSetMetaDataTests extends BaseTest { * to validate that an IllegalArgumentException will be thrown from the * valueOf method */ - @DataProvider(name = "validSetNullableValues") - private Object[][] validSetNullableValues() { - return new Object[][]{ - {ResultSetMetaData.columnNoNulls}, - {ResultSetMetaData.columnNullable}, - {ResultSetMetaData.columnNullableUnknown} - }; + private Stream validSetNullableValues() { + return Stream.of( + ResultSetMetaData.columnNoNulls, + ResultSetMetaData.columnNullable, + ResultSetMetaData.columnNullableUnknown + ); } /* * DataProvider used to provide column indexes that are out of range so that * SQLException is thrown */ - @DataProvider(name = "invalidColumnRanges") - private Object[][] invalidColumnRanges() { - return new Object[][]{ - {-1}, - {0}, - {MAX_COLUMNS + 1} - }; + private Stream invalidColumnRanges() { + return Stream.of( + -1, + 0, + MAX_COLUMNS + 1 + ); } /* * DataProvider used to provide the valid column ranges for the * RowSetMetaDataImpl object */ - @DataProvider(name = "columnRanges") - private Object[][] columnRanges() { - Object[][] o = new Object[MAX_COLUMNS][1]; - for (int i = 1; i <= MAX_COLUMNS; i++) { - o[i - 1][0] = i; - } - return o; + private Stream columnRanges() { + return IntStream.rangeClosed(1, MAX_COLUMNS).boxed(); } /* * DataProvider used to specify the value to set via setColumnType and * the expected value to be returned from getColumnClassName */ - @DataProvider(name = "columnClassNames") - private Object[][] columnClassNames() { - return new Object[][]{ - {Types.CHAR, "java.lang.String"}, - {Types.NCHAR, "java.lang.String"}, - {Types.VARCHAR, "java.lang.String"}, - {Types.NVARCHAR, "java.lang.String"}, - {Types.LONGVARCHAR, "java.lang.String"}, - {Types.LONGNVARCHAR, "java.lang.String"}, - {Types.NUMERIC, "java.math.BigDecimal"}, - {Types.DECIMAL, "java.math.BigDecimal"}, - {Types.BIT, "java.lang.Boolean"}, - {Types.TINYINT, "java.lang.Byte"}, - {Types.SMALLINT, "java.lang.Short"}, - {Types.INTEGER, "java.lang.Integer"}, - {Types.FLOAT, "java.lang.Double"}, - {Types.DOUBLE, "java.lang.Double"}, - {Types.BINARY, "byte[]"}, - {Types.VARBINARY, "byte[]"}, - {Types.LONGVARBINARY, "byte[]"}, - {Types.DATE, "java.sql.Date"}, - {Types.TIME, "java.sql.Time"}, - {Types.TIMESTAMP, "java.sql.Timestamp"}, - {Types.CLOB, "java.sql.Clob"}, - {Types.BLOB, "java.sql.Blob"} - - }; - + private Stream columnClassNames() { + return Stream.of( + Arguments.of(Types.CHAR, "java.lang.String"), + Arguments.of(Types.NCHAR, "java.lang.String"), + Arguments.of(Types.VARCHAR, "java.lang.String"), + Arguments.of(Types.NVARCHAR, "java.lang.String"), + Arguments.of(Types.LONGVARCHAR, "java.lang.String"), + Arguments.of(Types.LONGNVARCHAR, "java.lang.String"), + Arguments.of(Types.NUMERIC, "java.math.BigDecimal"), + Arguments.of(Types.DECIMAL, "java.math.BigDecimal"), + Arguments.of(Types.BIT, "java.lang.Boolean"), + Arguments.of(Types.TINYINT, "java.lang.Byte"), + Arguments.of(Types.SMALLINT, "java.lang.Short"), + Arguments.of(Types.INTEGER, "java.lang.Integer"), + Arguments.of(Types.FLOAT, "java.lang.Double"), + Arguments.of(Types.DOUBLE, "java.lang.Double"), + Arguments.of(Types.BINARY, "byte[]"), + Arguments.of(Types.VARBINARY, "byte[]"), + Arguments.of(Types.LONGVARBINARY, "byte[]"), + Arguments.of(Types.DATE, "java.sql.Date"), + Arguments.of(Types.TIME, "java.sql.Time"), + Arguments.of(Types.TIMESTAMP, "java.sql.Timestamp"), + Arguments.of(Types.CLOB, "java.sql.Clob"), + Arguments.of(Types.BLOB, "java.sql.Blob") + ); } - } diff --git a/test/jdk/javax/sql/testng/test/rowset/RowSetProviderTests.java b/test/jdk/javax/sql/test/rowset/RowSetProviderTests.java similarity index 79% rename from test/jdk/javax/sql/testng/test/rowset/RowSetProviderTests.java rename to test/jdk/javax/sql/test/rowset/RowSetProviderTests.java index 47a5cdb1eb0..25422cf0950 100644 --- a/test/jdk/javax/sql/testng/test/rowset/RowSetProviderTests.java +++ b/test/jdk/javax/sql/test/rowset/RowSetProviderTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,14 +27,19 @@ import java.io.File; import java.net.URL; import java.net.URLClassLoader; import java.sql.SQLException; +import java.util.stream.Stream; import javax.sql.rowset.RowSetFactory; import javax.sql.rowset.RowSetProvider; -import static org.testng.Assert.*; -import org.testng.annotations.AfterClass; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + import util.BaseTest; import util.StubRowSetFactory; @@ -57,7 +62,7 @@ public class RowSetProviderTests extends BaseTest { * Save off the original property value for javax.sql.rowset.RowSetFactory, * original classloader and define the path to the jars directory */ - @BeforeClass + @BeforeAll public static void setUpClass() throws Exception { origFactoryProperty = System.getProperty("javax.sql.rowset.RowSetFactory"); cl = Thread.currentThread().getContextClassLoader(); @@ -68,7 +73,7 @@ public class RowSetProviderTests extends BaseTest { /* * Install the original javax.sql.rowset.RowSetFactory property value */ - @AfterClass + @AfterAll public static void tearDownClass() throws Exception { if (origFactoryProperty != null) { System.setProperty("javax.sql.rowset.RowSetFactory", @@ -80,7 +85,7 @@ public class RowSetProviderTests extends BaseTest { * Clear the javax.sql.rowset.RowSetFactory property value and * reset the classloader to its original value */ - @AfterMethod + @AfterEach public void tearDownMethod() throws Exception { System.clearProperty("javax.sql.rowset.RowSetFactory"); Thread.currentThread().setContextClassLoader(cl); @@ -89,7 +94,8 @@ public class RowSetProviderTests extends BaseTest { /* * Validate that the correct RowSetFactory is returned by newFactory(). */ - @Test(dataProvider = "RowSetFactoryValues") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("RowSetFactoryValues") public void test(RowSetFactory rsf, String impl) throws SQLException { validateProvider(rsf, impl); } @@ -109,7 +115,7 @@ public class RowSetProviderTests extends BaseTest { * Validate that the correct RowSetFactory is returned by newFactory() * when specified by the javax.sql.rowset.RowSetFactory property. */ - @Test(enabled = true) + @Test public void test02() throws SQLException { System.setProperty("javax.sql.rowset.RowSetFactory", STUB_FACTORY_CLASSNAME); validateProvider(RowSetProvider.newFactory(), STUB_FACTORY_CLASSNAME); @@ -120,11 +126,13 @@ public class RowSetProviderTests extends BaseTest { * when specified RowSetFactory specified by the * javax.sql.rowset.RowSetFactory property is not valid. */ - @Test(expectedExceptions = SQLException.class) + @Test public void test03() throws SQLException { - System.setProperty("javax.sql.rowset.RowSetFactory", - "invalid.RowSetFactoryImpl"); - RowSetFactory rsf = RowSetProvider.newFactory(); + assertThrows(SQLException.class, () -> { + System.setProperty("javax.sql.rowset.RowSetFactory", + "invalid.RowSetFactoryImpl"); + RowSetFactory rsf = RowSetProvider.newFactory(); + }); } /* @@ -144,13 +152,15 @@ public class RowSetProviderTests extends BaseTest { * Validate that a SQLException is thrown by newFactory() if the default * RowSetFactory specified by the ServiceLoader API is not valid */ - @Test(expectedExceptions = SQLException.class) + @Test public void test05() throws Exception { - File f = new File(jarPath + "badFactory"); - URLClassLoader loader = new URLClassLoader(new URL[]{ - new URL(f.toURI().toString())}, getClass().getClassLoader()); - Thread.currentThread().setContextClassLoader(loader); - RowSetProvider.newFactory(); + assertThrows(SQLException.class, () -> { + File f = new File(jarPath + "badFactory"); + URLClassLoader loader = new URLClassLoader(new URL[]{ + new URL(f.toURI().toString())}, getClass().getClassLoader()); + Thread.currentThread().setContextClassLoader(loader); + RowSetProvider.newFactory(); + }); } /* @@ -174,16 +184,15 @@ public class RowSetProviderTests extends BaseTest { * DataProvider used to provide a RowSetFactory and the expected * RowSetFactory implementation that should be returned */ - @DataProvider(name = "RowSetFactoryValues") - private Object[][] RowSetFactoryValues() throws SQLException { + private Stream RowSetFactoryValues() throws SQLException { RowSetFactory rsf = RowSetProvider.newFactory(); RowSetFactory rsf1 = RowSetProvider.newFactory(STUB_FACTORY_CLASSNAME, null); RowSetFactory rsf2 = RowSetProvider.newFactory(DEFFAULT_FACTORY_CLASSNAME, null); - return new Object[][]{ - {rsf, NO_VALADATE_IMPL}, - {rsf, DEFFAULT_FACTORY_CLASSNAME}, - {rsf1, STUB_FACTORY_CLASSNAME}, - {rsf2, DEFFAULT_FACTORY_CLASSNAME} - }; + return Stream.of( + Arguments.of(rsf, NO_VALADATE_IMPL), + Arguments.of(rsf, DEFFAULT_FACTORY_CLASSNAME), + Arguments.of(rsf1, STUB_FACTORY_CLASSNAME), + Arguments.of(rsf2, DEFFAULT_FACTORY_CLASSNAME) + ); } } diff --git a/test/jdk/javax/sql/testng/test/rowset/RowSetWarningTests.java b/test/jdk/javax/sql/test/rowset/RowSetWarningTests.java similarity index 97% rename from test/jdk/javax/sql/testng/test/rowset/RowSetWarningTests.java rename to test/jdk/javax/sql/test/rowset/RowSetWarningTests.java index 41b52c4ef57..81ae97af785 100644 --- a/test/jdk/javax/sql/testng/test/rowset/RowSetWarningTests.java +++ b/test/jdk/javax/sql/test/rowset/RowSetWarningTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * 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,8 +24,10 @@ package test.rowset; import java.sql.SQLException; import javax.sql.rowset.RowSetWarning; -import static org.testng.Assert.*; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + import util.BaseTest; public class RowSetWarningTests extends BaseTest { diff --git a/test/jdk/javax/sql/testng/test/rowset/cachedrowset/CachedRowSetTests.java b/test/jdk/javax/sql/test/rowset/cachedrowset/CachedRowSetTests.java similarity index 94% rename from test/jdk/javax/sql/testng/test/rowset/cachedrowset/CachedRowSetTests.java rename to test/jdk/javax/sql/test/rowset/cachedrowset/CachedRowSetTests.java index 1155a889187..5fd473924c3 100644 --- a/test/jdk/javax/sql/testng/test/rowset/cachedrowset/CachedRowSetTests.java +++ b/test/jdk/javax/sql/test/rowset/cachedrowset/CachedRowSetTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/javax/sql/testng/test/rowset/cachedrowset/CommonCachedRowSetTests.java b/test/jdk/javax/sql/test/rowset/cachedrowset/CommonCachedRowSetTests.java similarity index 79% rename from test/jdk/javax/sql/testng/test/rowset/cachedrowset/CommonCachedRowSetTests.java rename to test/jdk/javax/sql/test/rowset/cachedrowset/CommonCachedRowSetTests.java index 642c03c9a45..bc63ce28497 100644 --- a/test/jdk/javax/sql/testng/test/rowset/cachedrowset/CommonCachedRowSetTests.java +++ b/test/jdk/javax/sql/test/rowset/cachedrowset/CommonCachedRowSetTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * 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.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.util.Collection; +import java.util.stream.Stream; import javax.sql.RowSet; import javax.sql.rowset.CachedRowSet; import javax.sql.rowset.RowSetMetaDataImpl; @@ -44,12 +45,18 @@ import javax.sql.rowset.serial.SerialRef; import javax.sql.rowset.spi.SyncFactory; import javax.sql.rowset.spi.SyncProvider; import javax.sql.rowset.spi.SyncProviderException; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertNull; -import static org.testng.Assert.assertTrue; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + import test.rowset.CommonRowSetTests; import util.StubArray; import util.StubRef; @@ -83,52 +90,43 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { /* * DataProvider that uses a RowSet with the COFFEE_HOUSES Table */ - @DataProvider(name = "rowsetUsingCoffeeHouses") - protected Object[][] rowsetUsingCoffeeHouses() throws Exception { - RowSet rs = createCoffeeHousesRowSet(); - return new Object[][]{ - {rs} - }; + protected Stream rowsetUsingCoffeeHouses() throws Exception { + return Stream.of(createCoffeeHousesRowSet()); } /* * DataProvider that uses a RowSet with the COFFEES Table */ - @DataProvider(name = "rowsetUsingCoffees") - protected Object[][] rowsetUsingCoffees() throws Exception { - RowSet rs = createCoffeesRowSet(); - return new Object[][]{ - {rs} - }; + protected Stream rowsetUsingCoffees() throws Exception { + return Stream.of(createCoffeesRowSet()); } /* * DataProvider that uses a RowSet with the DATAYPES Table and * used to validate the various supported data types */ - @DataProvider(name = "rowsetUsingDataTypes") - protected Object[][] rowsetUsingDataTypes() throws Exception { + protected Stream rowsetUsingDataTypes() throws Exception { CachedRowSet rs = createDataTypesRowSet(); - return new Object[][]{ - {rs, JDBCType.INTEGER}, - {rs, JDBCType.CHAR}, - {rs, JDBCType.VARCHAR}, - {rs, JDBCType.BIGINT}, - {rs, JDBCType.BOOLEAN}, - {rs, JDBCType.SMALLINT}, - {rs, JDBCType.DOUBLE}, - {rs, JDBCType.DECIMAL}, - {rs, JDBCType.REAL}, - {rs, JDBCType.TINYINT}, - {rs, JDBCType.DATE}, - {rs, JDBCType.TIME}, - {rs, JDBCType.TIMESTAMP}, - {rs, JDBCType.VARBINARY}, - {rs, JDBCType.ARRAY}, - {rs, JDBCType.REF}, - {rs, JDBCType.FLOAT} - }; + return Stream.of( + Arguments.of(rs, JDBCType.INTEGER), + Arguments.of(rs, JDBCType.CHAR), + Arguments.of(rs, JDBCType.VARCHAR), + Arguments.of(rs, JDBCType.BIGINT), + Arguments.of(rs, JDBCType.BOOLEAN), + Arguments.of(rs, JDBCType.SMALLINT), + Arguments.of(rs, JDBCType.DOUBLE), + Arguments.of(rs, JDBCType.DECIMAL), + Arguments.of(rs, JDBCType.REAL), + Arguments.of(rs, JDBCType.TINYINT), + Arguments.of(rs, JDBCType.DATE), + Arguments.of(rs, JDBCType.TIME), + Arguments.of(rs, JDBCType.TIMESTAMP), + Arguments.of(rs, JDBCType.VARBINARY), + Arguments.of(rs, JDBCType.ARRAY), + Arguments.of(rs, JDBCType.REF), + Arguments.of(rs, JDBCType.FLOAT) + ); } /* @@ -254,7 +252,7 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { private void compareMetaData(ResultSetMetaData rsmd, ResultSetMetaData rsmd1) throws SQLException { - assertEquals(rsmd1.getColumnCount(), rsmd.getColumnCount()); + assertEquals(rsmd.getColumnCount(), rsmd1.getColumnCount()); int cols = rsmd.getColumnCount(); for (int i = 1; i <= cols; i++) { assertTrue(rsmd1.getCatalogName(i).equals(rsmd.getCatalogName(i))); @@ -356,26 +354,33 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { * Validate SyncProviderException is thrown when acceptChanges is called * but there is not a way to make a connection to the datasource */ - @Test(dataProvider = "rowSetType", expectedExceptions = SyncProviderException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonCachedRowSetTest0000(CachedRowSet rs) throws Exception { - rs.acceptChanges(); - rs.close(); + assertThrows(SyncProviderException.class, () -> { + rs.acceptChanges(); + rs.close(); + }); } /* * Validate SyncProviderException is thrown when acceptChanges is called * when null is passed as the datasource */ - @Test(dataProvider = "rowSetType", expectedExceptions = SyncProviderException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonCachedRowSetTest0001(CachedRowSet rs) throws Exception { - rs.acceptChanges(null); - rs.close(); + assertThrows(SyncProviderException.class, () -> { + rs.acceptChanges(null); + rs.close(); + }); } /* * Validate that that RIOPtimsticProvider is the default SyncProvider */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonCachedRowSetTest0002(CachedRowSet rs) throws SQLException { SyncProvider sp = rs.getSyncProvider(); assertTrue(sp instanceof com.sun.rowset.providers.RIOptimisticProvider); @@ -385,7 +390,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { /* * Validate that you can specify a SyncProvider */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonCachedRowSetTest0003(CachedRowSet rs) throws SQLException { // Register a provider and make sure it is avaiable @@ -400,7 +406,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { /* * Create a RowSetListener and validate that notifyRowSetChanged is called */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonCachedRowSetTest0004(CachedRowSet rs) throws Exception { TestRowSetListener rsl = new TestRowSetListener(); rs.addRowSetListener(rsl); @@ -412,7 +419,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { /* * Create a RowSetListener and validate that notifyRowSetChanged is called */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonCachedRowSetTest0005(CachedRowSet rs) throws Exception { TestRowSetListener rsl = new TestRowSetListener(); rs.addRowSetListener(rsl); @@ -424,7 +432,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { /* * Create a RowSetListener and validate that notifyRowChanged is called */ - @Test(dataProvider = "rowsetUsingCoffeeHouses") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0006(RowSet rs) throws Exception { TestRowSetListener rsl = new TestRowSetListener(); rs.addRowSetListener(rsl); @@ -443,7 +452,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { * Create a multiple RowSetListeners and validate that notifyRowChanged, * notifiyMoved is called on all listners */ - @Test(dataProvider = "rowsetUsingCoffeeHouses") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0007(RowSet rs) throws Exception { TestRowSetListener rsl = new TestRowSetListener(); TestRowSetListener rsl2 = new TestRowSetListener(); @@ -467,7 +477,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { * Create a RowSetListener and validate that notifyRowChanged and * notifyCursorMoved are called */ - @Test(dataProvider = "rowsetUsingCoffeeHouses") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0008(CachedRowSet rs) throws Exception { TestRowSetListener rsl = new TestRowSetListener(); rs.addRowSetListener(rsl); @@ -487,7 +498,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { /* * Create a RowSetListener and validate that notifyCursorMoved is called */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonCachedRowSetTest0009(RowSet rs) throws Exception { TestRowSetListener rsl = new TestRowSetListener(); rs.addRowSetListener(rsl); @@ -499,7 +511,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { /* * Validate that getTableName() returns the proper values */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonCachedRowSetTest0010(CachedRowSet rs) throws Exception { assertNull(rs.getTableName()); rs.setTableName(COFFEE_HOUSES_TABLE); @@ -510,12 +523,13 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { /* * Validate that getKeyColumns() returns the proper values */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonCachedRowSetTest0011(CachedRowSet rs) throws Exception { int[] pkeys = {1, 3}; assertNull(rs.getKeyColumns()); rs.setKeyColumns(pkeys); - assertEquals(rs.getKeyColumns(), pkeys); + assertArrayEquals(pkeys, rs.getKeyColumns()); rs.close(); } @@ -523,52 +537,62 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { * Validate that setMatchColumn throws a SQLException if the column * index specified is out of range */ - @Test(dataProvider = "rowsetUsingCoffeeHouses", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0012(CachedRowSet rs) throws Exception { - rs.setMatchColumn(-1); - rs.close(); + assertThrows(SQLException.class, () -> { + rs.setMatchColumn(-1); + rs.close(); + }); } /* * Validate that setMatchColumn throws a SQLException if the column * index specified is out of range */ - @Test(dataProvider = "rowsetUsingCoffeeHouses", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0013(CachedRowSet rs) throws Exception { - int[] cols = {1, -1}; - rs.setMatchColumn(cols); - rs.close(); + assertThrows(SQLException.class, () -> { + int[] cols = {1, -1}; + rs.setMatchColumn(cols); + rs.close(); + }); } /* * Validate that setMatchColumn throws a SQLException if the column * index specified is out of range */ - @Test(dataProvider = "rowsetUsingCoffeeHouses", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0014(CachedRowSet rs) throws Exception { - rs.setMatchColumn((String) null); - rs.close(); + assertThrows(SQLException.class, () -> { + rs.setMatchColumn((String) null); + rs.close(); + }); } /* * Validate that setMatchColumn throws a SQLException if the column * index specified is out of range */ - @Test(dataProvider = "rowsetUsingCoffeeHouses", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0015(CachedRowSet rs) throws Exception { - String[] cols = {"ID", null}; - rs.setMatchColumn(cols); + assertThrows(SQLException.class, () -> { + String[] cols = {"ID", null}; + rs.setMatchColumn(cols); + }); } /* * Validate that getMatchColumn returns the same value specified by * setMatchColumn */ - @Test(dataProvider = "rowsetUsingCoffeeHouses", enabled = false) + @Disabled + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0016(CachedRowSet rs) throws Exception { int[] expectedCols = {1}; String[] expectedColNames = {"ID"}; @@ -578,8 +602,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { for (int i = 0; i < actualCols.length; i++) { System.out.println(actualCols[i]); } - assertEquals(actualCols, expectedCols); - assertEquals(actualColNames, expectedColNames); + assertArrayEquals(expectedCols, actualCols); + assertArrayEquals(expectedColNames, actualColNames); rs.close(); } @@ -587,15 +611,17 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { * Validate that getMatchColumn returns the same value specified by * setMatchColumn */ - @Test(dataProvider = "rowsetUsingCoffeeHouses", enabled = false) + @Disabled + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0017(CachedRowSet rs) throws Exception { int[] expectedCols = {1}; String[] expectedColNames = {"ID"}; rs.setMatchColumn(expectedColNames[0]); int[] actualCols = rs.getMatchColumnIndexes(); String[] actualColNames = rs.getMatchColumnNames(); - assertEquals(actualCols, expectedCols); - assertEquals(actualColNames, expectedColNames); + assertArrayEquals(expectedCols, actualCols); + assertArrayEquals(expectedColNames, actualColNames); rs.close(); } @@ -603,16 +629,18 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { * Validate that getMatchColumn returns the same valid value specified by * setMatchColumn */ - @Test(dataProvider = "rowsetUsingCoffeeHouses", enabled = false) + @Disabled + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0018(CachedRowSet rs) throws Exception { int[] expectedCols = {1, 3}; String[] expectedColNames = {"COF_ID", "SUP_ID"}; rs.setMatchColumn(expectedCols); int[] actualCols = rs.getMatchColumnIndexes(); String[] actualColNames = rs.getMatchColumnNames(); - assertEquals(actualCols, expectedCols); - assertEquals(actualColNames, expectedColNames); - assertEquals(actualCols, expectedCols); + assertArrayEquals(expectedCols, actualCols); + assertArrayEquals(expectedColNames, actualColNames); + assertArrayEquals(expectedCols, actualCols); rs.close(); } @@ -620,15 +648,17 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { * Validate that getMatchColumn returns the same valid value specified by * setMatchColumn */ - @Test(dataProvider = "rowsetUsingCoffeeHouses", enabled = false) + @Disabled + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0019(CachedRowSet rs) throws Exception { int[] expectedCols = {1, 3}; String[] expectedColNames = {"COF_ID", "SUP_ID"}; rs.setMatchColumn(expectedColNames); int[] actualCols = rs.getMatchColumnIndexes(); String[] actualColNames = rs.getMatchColumnNames(); - assertEquals(actualCols, expectedCols); - assertEquals(actualColNames, expectedColNames); + assertArrayEquals(expectedCols, actualCols); + assertArrayEquals(expectedColNames, actualColNames); rs.close(); } @@ -636,69 +666,78 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { * Validate that getMatchColumnIndexes throws a SQLException if * unsetMatchColumn has been called */ - @Test(dataProvider = "rowsetUsingCoffeeHouses", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0020(CachedRowSet rs) throws Exception { - rs.setMatchColumn(1); - int[] actualCols = rs.getMatchColumnIndexes(); - assertTrue(actualCols != null); - rs.unsetMatchColumn(1); - actualCols = rs.getMatchColumnIndexes(); - rs.close(); + assertThrows(SQLException.class, () -> { + rs.setMatchColumn(1); + int[] actualCols = rs.getMatchColumnIndexes(); + assertTrue(actualCols != null); + rs.unsetMatchColumn(1); + actualCols = rs.getMatchColumnIndexes(); + rs.close(); + }); } /* * Validate that getMatchColumnNames throws a SQLException if * unsetMatchColumn has been called */ - @Test(dataProvider = "rowsetUsingCoffeeHouses", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0021(CachedRowSet rs) throws Exception { - String matchColumn = "ID"; - rs.setMatchColumn(matchColumn); - String[] actualColNames = rs.getMatchColumnNames(); - assertTrue(actualColNames != null); - rs.unsetMatchColumn(matchColumn); - actualColNames = rs.getMatchColumnNames(); - rs.close(); + assertThrows(SQLException.class, () -> { + String matchColumn = "ID"; + rs.setMatchColumn(matchColumn); + String[] actualColNames = rs.getMatchColumnNames(); + assertTrue(actualColNames != null); + rs.unsetMatchColumn(matchColumn); + actualColNames = rs.getMatchColumnNames(); + rs.close(); + }); } /* * Validate that getMatchColumnIndexes throws a SQLException if * unsetMatchColumn has been called */ - @Test(dataProvider = "rowsetUsingCoffeeHouses", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0022(CachedRowSet rs) throws Exception { - int[] expectedCols = {1, 3}; - rs.setMatchColumn(expectedCols); - int[] actualCols = rs.getMatchColumnIndexes(); - assertTrue(actualCols != null); - rs.unsetMatchColumn(expectedCols); - actualCols = rs.getMatchColumnIndexes(); - rs.close(); + assertThrows(SQLException.class, () -> { + int[] expectedCols = {1, 3}; + rs.setMatchColumn(expectedCols); + int[] actualCols = rs.getMatchColumnIndexes(); + assertTrue(actualCols != null); + rs.unsetMatchColumn(expectedCols); + actualCols = rs.getMatchColumnIndexes(); + rs.close(); + }); } /* * Validate that getMatchColumnNames throws a SQLException if * unsetMatchColumn has been called */ - @Test(dataProvider = "rowsetUsingCoffeeHouses", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0023(CachedRowSet rs) throws Exception { - String[] expectedColNames = {"COF_ID", "SUP_ID"}; - rs.setMatchColumn(expectedColNames); - String[] actualColNames = rs.getMatchColumnNames(); - assertTrue(actualColNames != null); - rs.unsetMatchColumn(expectedColNames); - actualColNames = rs.getMatchColumnNames(); - rs.close(); + assertThrows(SQLException.class, () -> { + String[] expectedColNames = {"COF_ID", "SUP_ID"}; + rs.setMatchColumn(expectedColNames); + String[] actualColNames = rs.getMatchColumnNames(); + assertTrue(actualColNames != null); + rs.unsetMatchColumn(expectedColNames); + actualColNames = rs.getMatchColumnNames(); + rs.close(); + }); } /* * Validate size() returns the correct number of rows */ - @Test(dataProvider = "rowsetUsingCoffeeHouses") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0024(CachedRowSet rs) throws Exception { assertTrue(rs.size() == COFFEE_HOUSES_ROWS); rs.close(); @@ -708,9 +747,10 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { * Validate that the correct rows are returned comparing the primary * keys */ - @Test(dataProvider = "rowsetUsingCoffeeHouses") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0025(RowSet rs) throws SQLException { - assertEquals(getPrimaryKeys(rs), COFFEE_HOUSES_PRIMARY_KEYS); + assertArrayEquals(COFFEE_HOUSES_PRIMARY_KEYS, getPrimaryKeys(rs)); rs.close(); } @@ -719,7 +759,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { * Validate the visibility of the row depending on the value of * setShowdelete */ - @Test(dataProvider = "rowsetUsingCoffeeHouses") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0026(CachedRowSet rs) throws Exception { Object[] afterDelete = { 10023, 33002, 10040, 32001, 10042, 10024, 10039, 10041, @@ -727,13 +768,13 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { }; int rowToDelete = 10035; // All rows should be found - assertEquals(getPrimaryKeys(rs), COFFEE_HOUSES_PRIMARY_KEYS); + assertArrayEquals(COFFEE_HOUSES_PRIMARY_KEYS, getPrimaryKeys(rs)); // Delete the row assertTrue(deleteRowByPrimaryKey(rs, rowToDelete, 1)); // With setShowDeleted(false) which is the default, // the deleted row should not be visible assertFalse(findRowByPrimaryKey(rs, rowToDelete, 1)); - assertEquals(getPrimaryKeys(rs), afterDelete); + assertArrayEquals(afterDelete, getPrimaryKeys(rs)); assertTrue(rs.size() == COFFEE_HOUSES_ROWS); // With setShowDeleted(true), the deleted row should be visible rs.setShowDeleted(true); @@ -744,7 +785,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { /* * Validate that there is no page size by default */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonCachedRowSetTest0027(CachedRowSet rs) throws Exception { assertTrue(rs.getPageSize() == 0); rs.close(); @@ -754,7 +796,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { * Validate the value you set via setPageSize is returned by getPageSize * then reset to having no limit */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonCachedRowSetTest0028(CachedRowSet rs) throws Exception { int rows = 100; rs.setPageSize(rows); @@ -768,30 +811,39 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { * Validate SQLException is thrown when an invalid value is specified * for setPageSize */ - @Test(dataProvider = "rowSetType", expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonCachedRowSetTest0029(CachedRowSet rs) throws Exception { - rs.setPageSize(-1); - rs.close(); + assertThrows(SQLException.class, () -> { + rs.setPageSize(-1); + rs.close(); + }); } /* * Validate SQLException is thrown when nextPage is called without a * call to populate or execute */ - @Test(dataProvider = "rowSetType", expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonCachedRowSetTest0030(CachedRowSet rs) throws Exception { - rs.nextPage(); - rs.close(); + assertThrows(SQLException.class, () -> { + rs.nextPage(); + rs.close(); + }); } /* * Validate SQLException is thrown when previousPage is called without a * call to populate or execute */ - @Test(dataProvider = "rowSetType", expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonCachedRowSetTest0031(CachedRowSet rs) throws Exception { - rs.previousPage(); - rs.close(); + assertThrows(SQLException.class, () -> { + rs.previousPage(); + rs.close(); + }); } @@ -799,40 +851,48 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { * Validate SQLException is thrown when execute is called * but there is not a way to make a connection to the datasource */ - @Test(dataProvider = "rowSetType", expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonCachedRowSetTest0032(CachedRowSet rs) throws Exception { - rs.execute(null); - rs.close(); + assertThrows(SQLException.class, () -> { + rs.execute(null); + rs.close(); + }); } /* * Validate SQLException is thrown when execute is called * but there is not a way to make a connection to the datasource */ - @Test(dataProvider = "rowSetType", expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonCachedRowSetTest0033(CachedRowSet rs) throws Exception { - rs.execute(); - rs.close(); + assertThrows(SQLException.class, () -> { + rs.execute(); + rs.close(); + }); } /* * Validate that toCollection() returns the proper values */ - @Test(dataProvider = "rowsetUsingCoffeeHouses") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0034(CachedRowSet rs) throws Exception { Object[] cities = {"Mendocino", "Seattle", "SF", "Portland", "SF", "Sacramento", "Carmel", "LA", "Olympia", "Seattle", "SF", "LA", "San Jose", "Eugene"}; rs.beforeFirst(); - assertEquals(rs.toCollection(2).toArray(), cities); - assertEquals(rs.toCollection("CITY").toArray(), cities); + assertArrayEquals(cities, rs.toCollection(2).toArray()); + assertArrayEquals(cities, rs.toCollection("CITY").toArray()); rs.close(); } /* * Validate that toCollection() returns the proper values */ - @Test(dataProvider = "rowsetUsingCoffeeHouses") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0035(CachedRowSet rs) throws Exception { Collection col = rs.toCollection(); assertTrue(rs.size() == col.size()); @@ -850,7 +910,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { /* * Validate that createCopy() returns the proper values */ - @Test(dataProvider = "rowsetUsingCoffeeHouses") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0036(CachedRowSet rs) throws Exception { try (CachedRowSet crs1 = rs.createCopy()) { compareRowSets(rs, crs1); @@ -861,7 +922,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { /* * Validate that createCopySchema() returns the proper values */ - @Test(dataProvider = "rowsetUsingCoffeeHouses") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0037(CachedRowSet rs) throws Exception { try (CachedRowSet crs1 = rs.createCopySchema()) { assertTrue(crs1.size() == 0); @@ -875,7 +937,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { * and getMatchColumnIndexes should throw a SQLException. This test * specifies setMatchColumn(int) */ - @Test(dataProvider = "rowsetUsingCoffeeHouses") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0038(CachedRowSet rs) throws Exception { rs.setMatchColumn(1); try (CachedRowSet crs1 = rs.createCopyNoConstraints()) { @@ -904,7 +967,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { * and getMatchColumnIndexes should throw a SQLException. This test * specifies setMatchColumn(String) */ - @Test(dataProvider = "rowsetUsingCoffeeHouses") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0039(CachedRowSet rs) throws Exception { rs.setMatchColumn("ID"); try (CachedRowSet crs1 = rs.createCopyNoConstraints()) { @@ -932,7 +996,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { * Validate that columnUpdated works with the various datatypes specifying * the column index */ - @Test(dataProvider = "rowsetUsingDataTypes") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingDataTypes") public void commonCachedRowSetTest0040(CachedRowSet rs, JDBCType type) throws Exception { rs.beforeFirst(); assertTrue(rs.next()); @@ -1029,7 +1094,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { * Validate that columnUpdated works with the various datatypes specifying * the column name */ - @Test(dataProvider = "rowsetUsingDataTypes") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingDataTypes") public void commonCachedRowSetTest0041(CachedRowSet rs, JDBCType type) throws Exception { rs.beforeFirst(); assertTrue(rs.next()); @@ -1127,7 +1193,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { * Validate isBeforeFirst(), isFirst() and first() return the correct * results */ - @Test(dataProvider = "rowsetUsingCoffeeHouses") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0042(RowSet rs) throws Exception { assertFalse(rs.isBeforeFirst()); assertFalse(rs.isFirst()); @@ -1150,7 +1217,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { * Validate isAfterLast(), isLast() and last() return the correct * results */ - @Test(dataProvider = "rowsetUsingCoffeeHouses") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0043(RowSet rs) throws Exception { assertFalse(rs.isAfterLast()); assertFalse(rs.isLast()); @@ -1173,121 +1241,140 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { * Validate a SQLException is thrown when undoDelete is called on the * insertRow */ - @Test(dataProvider = "rowsetUsingCoffeeHouses", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0044(CachedRowSet rs) throws Exception { - rs.insertRow(); - rs.undoDelete(); - rs.close(); + assertThrows(SQLException.class, () -> { + rs.insertRow(); + rs.undoDelete(); + rs.close(); + }); } /* * Validate a SQLException is thrown when undoDelete is called when * cursor is before the first row */ - @Test(dataProvider = "rowsetUsingCoffeeHouses", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0045(CachedRowSet rs) throws Exception { - rs.setShowDeleted(true); - rs.beforeFirst(); - rs.undoDelete(); - rs.close(); + assertThrows(SQLException.class, () -> { + rs.setShowDeleted(true); + rs.beforeFirst(); + rs.undoDelete(); + rs.close(); + }); } /* * Validate a SQLException is thrown when undoDelete is called when * cursor is after the last row */ - @Test(dataProvider = "rowsetUsingCoffeeHouses", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0046(CachedRowSet rs) throws Exception { - rs.setShowDeleted(true); - rs.afterLast(); - rs.undoDelete(); - rs.close(); + assertThrows(SQLException.class, () -> { + rs.setShowDeleted(true); + rs.afterLast(); + rs.undoDelete(); + rs.close(); + }); } /* * Validate a SQLException is thrown when undoUpdate is called on the * insertRow */ - @Test(dataProvider = "rowsetUsingCoffeeHouses", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0047(CachedRowSet rs) throws Exception { - rs.insertRow(); - rs.undoUpdate(); - rs.close(); + assertThrows(SQLException.class, () -> { + rs.insertRow(); + rs.undoUpdate(); + rs.close(); + }); } /* * Validate a SQLException is thrown when undoUpdate is called when * cursor is before the first row */ - @Test(dataProvider = "rowsetUsingCoffeeHouses", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0048(CachedRowSet rs) throws Exception { - rs.setShowDeleted(true); - rs.beforeFirst(); - rs.undoUpdate(); - rs.close(); + assertThrows(SQLException.class, () -> { + rs.setShowDeleted(true); + rs.beforeFirst(); + rs.undoUpdate(); + rs.close(); + }); } /* * Validate a SQLException is thrown when undoUpdate is called when * cursor is after the last row */ - @Test(dataProvider = "rowsetUsingCoffeeHouses", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0049(CachedRowSet rs) throws Exception { - rs.setShowDeleted(true); - rs.afterLast(); - rs.undoUpdate(); - rs.close(); + assertThrows(SQLException.class, () -> { + rs.setShowDeleted(true); + rs.afterLast(); + rs.undoUpdate(); + rs.close(); + }); } /* * Validate a SQLException is thrown when undoInsert is called on the * insertRow */ - @Test(dataProvider = "rowsetUsingCoffeeHouses", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0050(CachedRowSet rs) throws Exception { - rs.insertRow(); - rs.undoInsert(); - rs.close(); + assertThrows(SQLException.class, () -> { + rs.insertRow(); + rs.undoInsert(); + rs.close(); + }); } /* * Validate a SQLException is thrown when undoInsert is called when * cursor is before the first row */ - @Test(dataProvider = "rowsetUsingCoffeeHouses", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0051(CachedRowSet rs) throws Exception { - rs.setShowDeleted(true); - rs.beforeFirst(); - rs.undoInsert(); - rs.close(); + assertThrows(SQLException.class, () -> { + rs.setShowDeleted(true); + rs.beforeFirst(); + rs.undoInsert(); + rs.close(); + }); } /* * Validate a SQLException is thrown when undoInsert is called when * cursor is after the last row */ - @Test(dataProvider = "rowsetUsingCoffeeHouses", - expectedExceptions = SQLException.class) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0052(CachedRowSet rs) throws Exception { - rs.setShowDeleted(true); - rs.afterLast(); - rs.undoInsert(); - rs.close(); + assertThrows(SQLException.class, () -> { + rs.setShowDeleted(true); + rs.afterLast(); + rs.undoInsert(); + rs.close(); + }); } /* * Insert a row, then call undoInsert to roll back the insert and validate * the row is not there */ - @Test(dataProvider = "rowsetUsingCoffeeHouses") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0053(CachedRowSet rs) throws Exception { int rowToInsert = 1961; assertTrue(rs.size() == COFFEE_HOUSES_ROWS); @@ -1314,7 +1401,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { * Insert a row, delete the row and then call undoDelete to make sure it * is comes back */ - @Test(dataProvider = "rowsetUsingCoffeeHouses") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0054(CachedRowSet rs) throws Exception { int rowToDelete = 1961; assertTrue(rs.size() == COFFEE_HOUSES_ROWS); @@ -1348,7 +1436,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { * Insert a row, modify a field and then call undoUpdate to revert the * insert */ - @Test(dataProvider = "rowsetUsingCoffeeHouses") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0055(CachedRowSet rs) throws Exception { int rowToInsert = 1961; assertTrue(rs.size() == COFFEE_HOUSES_ROWS); @@ -1385,7 +1474,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { * Validate getOriginal returns a ResultSet which is a copy of the original * RowSet */ - @Test(dataProvider = "rowsetUsingCoffees") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffees") public void commonCachedRowSetTest0056(CachedRowSet rs) throws Exception { String coffee = "Hazelnut"; int sales = 100; @@ -1414,12 +1504,12 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { assertTrue(rs1.getInt(1) == origId); assertTrue(rs1.getString(2).equals(origCoffee)); assertTrue(rs1.getInt(5) == origSales); - assertEquals(getPrimaryKeys(rs1), COFFEES_PRIMARY_KEYS); + assertArrayEquals(COFFEES_PRIMARY_KEYS, getPrimaryKeys(rs1)); // Check current rowset assertTrue(rs.getInt(1) == id); assertTrue(rs.getString(2).equals(coffee)); assertTrue(rs.getInt(5) == sales); - assertEquals(getPrimaryKeys(rs), updatedPkeys); + assertArrayEquals(updatedPkeys, getPrimaryKeys(rs)); } rs.close(); } @@ -1428,7 +1518,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { * Validate getOriginalRow returns a ResultSet which is a copy of the * original row that was modified */ - @Test(dataProvider = "rowsetUsingCoffees") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffees") public void commonCachedRowSetTest0057(CachedRowSet rs) throws Exception { String coffee = "Hazelnut"; int sales = 100; @@ -1463,7 +1554,7 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { assertTrue(rs.getInt(1) == id); assertTrue(rs.getString(2).equals(coffee)); assertTrue(rs.getInt(5) == sales); - assertEquals(getPrimaryKeys(rs), updatedPkeys); + assertArrayEquals(updatedPkeys, getPrimaryKeys(rs)); } rs.close(); } @@ -1472,7 +1563,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { * Validate that restoreOrginal will restore the RowSet to its * state prior to the insert of a row */ - @Test(dataProvider = "rowsetUsingCoffeeHouses") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0058(CachedRowSet rs) throws Exception { int rowToInsert = 1961; assertTrue(rs.size() == COFFEE_HOUSES_ROWS); @@ -1509,7 +1601,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { * Validate that restoreOrginal will restore the RowSet to its * state prior to deleting a row */ - @Test(dataProvider = "rowsetUsingCoffees", enabled = true) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffees") public void commonCachedRowSetTest0059(CachedRowSet rs) throws Exception { int rowToDelete = 2; try (CachedRowSet crs1 = rsf.createCachedRowSet()) { @@ -1540,7 +1633,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { * Validate that restoreOrginal will restore the RowSet to its * state prior to updating a row */ - @Test(dataProvider = "rowsetUsingCoffees", enabled = true) + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffees") public void commonCachedRowSetTest0060(CachedRowSet rs) throws Exception { int rowToUpdate = 2; String coffee = "Hazelnut"; @@ -1578,7 +1672,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { * Initialize a RowSet via the populate method. Validate it matches * the original ResultSet */ - @Test(dataProvider = "rowsetUsingCoffeeHouses") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0061(CachedRowSet rs) throws Exception { try (CachedRowSet crs1 = rsf.createCachedRowSet()) { rs.beforeFirst(); @@ -1593,7 +1688,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { * Validate it matches the original ResultSet starting for the specofied * offset */ - @Test(dataProvider = "rowsetUsingCoffeeHouses") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffeeHouses") public void commonCachedRowSetTest0062(CachedRowSet rs) throws Exception { Object[] expectedRows = { 32001, 10042, 10024, 10039, 10041, 33005, 33010, 10035, 10037, @@ -1603,8 +1699,8 @@ public abstract class CommonCachedRowSetTests extends CommonRowSetTests { try (CachedRowSet crs1 = rsf.createCachedRowSet()) { rs.beforeFirst(); crs1.populate(rs, startingRow); - assertEquals(crs1.size(), COFFEE_HOUSES_ROWS - startingRow + 1); - assertEquals(getPrimaryKeys(crs1), expectedRows); + assertEquals(COFFEE_HOUSES_ROWS - startingRow + 1, crs1.size()); + assertArrayEquals(expectedRows, getPrimaryKeys(crs1)); } rs.close(); } diff --git a/test/jdk/javax/sql/testng/test/rowset/filteredrowset/CityFilter.java b/test/jdk/javax/sql/test/rowset/filteredrowset/CityFilter.java similarity index 97% rename from test/jdk/javax/sql/testng/test/rowset/filteredrowset/CityFilter.java rename to test/jdk/javax/sql/test/rowset/filteredrowset/CityFilter.java index 2188c4eed08..458088ccb45 100644 --- a/test/jdk/javax/sql/testng/test/rowset/filteredrowset/CityFilter.java +++ b/test/jdk/javax/sql/test/rowset/filteredrowset/CityFilter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/javax/sql/testng/test/rowset/filteredrowset/FilteredRowSetTests.java b/test/jdk/javax/sql/test/rowset/filteredrowset/FilteredRowSetTests.java similarity index 81% rename from test/jdk/javax/sql/testng/test/rowset/filteredrowset/FilteredRowSetTests.java rename to test/jdk/javax/sql/test/rowset/filteredrowset/FilteredRowSetTests.java index 263a79a68b6..55d9323f373 100644 --- a/test/jdk/javax/sql/testng/test/rowset/filteredrowset/FilteredRowSetTests.java +++ b/test/jdk/javax/sql/test/rowset/filteredrowset/FilteredRowSetTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * 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,24 +26,30 @@ import java.sql.SQLException; import javax.sql.RowSet; import javax.sql.rowset.FilteredRowSet; import javax.sql.rowset.Predicate; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertNull; -import static org.testng.Assert.assertTrue; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; + +import org.junit.jupiter.api.AfterEach; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + import test.rowset.webrowset.CommonWebRowSetTests; public class FilteredRowSetTests extends CommonWebRowSetTests { private FilteredRowSet frs; - @BeforeMethod + @BeforeEach public void setUpMethod() throws Exception { frs = createCoffeeHousesRowSet(); } - @AfterMethod + @AfterEach public void tearDownMethod() throws Exception { frs.close(); } @@ -83,7 +89,7 @@ public class FilteredRowSetTests extends CommonWebRowSetTests { 10023, 10040, 10042, 10024, 10039, 10041, 10035, 10037, 10034 }; frs.setFilter(new PrimaryKeyFilter(10000, 10999, 1)); - assertEquals(getPrimaryKeys(frs), expectedKeys); + assertArrayEquals(expectedKeys, getPrimaryKeys(frs)); } /* @@ -96,7 +102,7 @@ public class FilteredRowSetTests extends CommonWebRowSetTests { 10023, 10040, 10042, 10024, 10039, 10041, 10035, 10037, 10034 }; frs.setFilter(new PrimaryKeyFilter(10000, 10999, "STORE_ID")); - assertEquals(getPrimaryKeys(frs), expectedKeys); + assertArrayEquals(expectedKeys, getPrimaryKeys(frs)); } @@ -111,7 +117,7 @@ public class FilteredRowSetTests extends CommonWebRowSetTests { }; String[] cityArray = {"SF", "LA"}; frs.setFilter(new CityFilter(cityArray, 2)); - assertEquals(getPrimaryKeys(frs), expectedKeys); + assertArrayEquals(expectedKeys, getPrimaryKeys(frs)); } /* @@ -125,14 +131,16 @@ public class FilteredRowSetTests extends CommonWebRowSetTests { }; String[] cityArray = {"SF", "LA"}; frs.setFilter(new CityFilter(cityArray, "CITY")); - assertEquals(getPrimaryKeys(frs), expectedKeys); + assertArrayEquals(expectedKeys, getPrimaryKeys(frs)); } // Tests that are common but need to be disabled due to an implementation bug - @Test(dataProvider = "rowSetType", enabled = false) + @Disabled + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonCachedRowSetTest0043(RowSet rs) throws Exception { // Need to fix bug in FilteredRowSets } diff --git a/test/jdk/javax/sql/testng/test/rowset/filteredrowset/PrimaryKeyFilter.java b/test/jdk/javax/sql/test/rowset/filteredrowset/PrimaryKeyFilter.java similarity index 97% rename from test/jdk/javax/sql/testng/test/rowset/filteredrowset/PrimaryKeyFilter.java rename to test/jdk/javax/sql/test/rowset/filteredrowset/PrimaryKeyFilter.java index 2a748314006..0353312419c 100644 --- a/test/jdk/javax/sql/testng/test/rowset/filteredrowset/PrimaryKeyFilter.java +++ b/test/jdk/javax/sql/test/rowset/filteredrowset/PrimaryKeyFilter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/javax/sql/testng/test/rowset/jdbcrowset/JdbcRowSetDriverManagerTest.java b/test/jdk/javax/sql/test/rowset/jdbcrowset/JdbcRowSetDriverManagerTest.java similarity index 95% rename from test/jdk/javax/sql/testng/test/rowset/jdbcrowset/JdbcRowSetDriverManagerTest.java rename to test/jdk/javax/sql/test/rowset/jdbcrowset/JdbcRowSetDriverManagerTest.java index be86798177a..5b135e16b5c 100644 --- a/test/jdk/javax/sql/testng/test/rowset/jdbcrowset/JdbcRowSetDriverManagerTest.java +++ b/test/jdk/javax/sql/test/rowset/jdbcrowset/JdbcRowSetDriverManagerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. * 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,9 @@ import java.sql.SQLException; import javax.sql.rowset.JdbcRowSet; import javax.sql.rowset.RowSetFactory; import javax.sql.rowset.RowSetProvider; -import org.testng.annotations.Test; + +import org.junit.jupiter.api.Test; + import util.BaseTest; import util.StubDriver; @@ -41,7 +43,7 @@ public class JdbcRowSetDriverManagerTest extends BaseTest { * Validate that JDBCRowSetImpl can connect to a JDBC driver that is * register by DriverManager. */ - @Test(enabled = true) + @Test public void test0000() throws SQLException { DriverManager.registerDriver(new StubDriver()); diff --git a/test/jdk/javax/sql/testng/test/rowset/joinrowset/JoinRowSetTests.java b/test/jdk/javax/sql/test/rowset/joinrowset/JoinRowSetTests.java similarity index 83% rename from test/jdk/javax/sql/testng/test/rowset/joinrowset/JoinRowSetTests.java rename to test/jdk/javax/sql/test/rowset/joinrowset/JoinRowSetTests.java index b84453e9a3b..92ce09bcf85 100644 --- a/test/jdk/javax/sql/testng/test/rowset/joinrowset/JoinRowSetTests.java +++ b/test/jdk/javax/sql/test/rowset/joinrowset/JoinRowSetTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * 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,16 +26,22 @@ import java.sql.SQLException; import java.sql.Types; import java.util.ArrayList; import java.util.List; +import java.util.stream.Stream; import javax.sql.RowSet; import javax.sql.rowset.CachedRowSet; import javax.sql.rowset.JoinRowSet; import javax.sql.rowset.RowSetMetaDataImpl; import javax.sql.rowset.WebRowSet; -import static org.testng.Assert.assertEquals; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + import test.rowset.webrowset.CommonWebRowSetTests; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + public class JoinRowSetTests extends CommonWebRowSetTests { private final String SUPPLIERS_TABLE = "SUPPLIERS"; @@ -150,8 +156,7 @@ public class JoinRowSetTests extends CommonWebRowSetTests { /* * DataProvider used to set parameters for basic types that are supported */ - @DataProvider(name = "createCachedRowSetsToUse") - private Object[][] createCachedRowSetsToUse() throws SQLException { + private Stream createCachedRowSetsToUse() throws SQLException { CachedRowSet crs = rsf.createCachedRowSet(); initCoffeesMetaData(crs); createCoffeesRows(crs); @@ -162,9 +167,7 @@ public class JoinRowSetTests extends CommonWebRowSetTests { createSuppiersRows(crs1); // Make sure you are not on the insertRow crs1.moveToCurrentRow(); - return new Object[][]{ - {crs, crs1} - }; + return Stream.of(Arguments.of(crs, crs1)); } /* @@ -178,13 +181,14 @@ public class JoinRowSetTests extends CommonWebRowSetTests { results.add(jrs.getInt("COF_ID")); } } - assertEquals(results.toArray(), EXPECTED); + assertArrayEquals(EXPECTED, results.toArray()); } /* * Join two CachedRowSets specifying a column name to join against */ - @Test(dataProvider = "createCachedRowSetsToUse") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("createCachedRowSetsToUse") public void joinRowSetTests0000(CachedRowSet crs, CachedRowSet crs1) throws Exception { @@ -200,7 +204,8 @@ public class JoinRowSetTests extends CommonWebRowSetTests { /* * Join two CachedRowSets specifying a column index to join against */ - @Test(dataProvider = "createCachedRowSetsToUse") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("createCachedRowSetsToUse") public void joinRowSetTests0001(CachedRowSet crs, CachedRowSet crs1) throws Exception { @@ -216,7 +221,8 @@ public class JoinRowSetTests extends CommonWebRowSetTests { /* * Join two CachedRowSets specifying a column name to join against */ - @Test(dataProvider = "createCachedRowSetsToUse") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("createCachedRowSetsToUse") public void joinRowSetTests0002(CachedRowSet crs, CachedRowSet crs1) throws Exception { @@ -233,7 +239,8 @@ public class JoinRowSetTests extends CommonWebRowSetTests { /* * Join two CachedRowSets specifying a column index to join against */ - @Test(dataProvider = "createCachedRowSetsToUse") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("createCachedRowSetsToUse") public void joinRowSetTests0003(CachedRowSet crs, CachedRowSet crs1) throws Exception { @@ -251,7 +258,8 @@ public class JoinRowSetTests extends CommonWebRowSetTests { /* * Join two CachedRowSets specifying a column name to join against */ - @Test(dataProvider = "createCachedRowSetsToUse") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("createCachedRowSetsToUse") public void joinRowSetTests0005(CachedRowSet crs, CachedRowSet crs1) throws Exception { @@ -269,7 +277,8 @@ public class JoinRowSetTests extends CommonWebRowSetTests { /* * Join two CachedRowSets specifying a column index to join against */ - @Test(dataProvider = "createCachedRowSetsToUse") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("createCachedRowSetsToUse") public void joinRowSetTests0006(CachedRowSet crs, CachedRowSet crs1) throws Exception { @@ -286,39 +295,56 @@ public class JoinRowSetTests extends CommonWebRowSetTests { } // Disabled tests due to bugs in JoinRowSet - @Test(dataProvider = "rowSetType", enabled = false) + @Disabled + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonCachedRowSetTest0004(CachedRowSet rs) throws Exception { } - @Test(dataProvider = "rowSetType", enabled = false) + @Disabled + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonCachedRowSetTest0005(CachedRowSet rs) throws Exception { } - @Test(dataProvider = "rowSetType", enabled = false) + @Disabled + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonCachedRowSetTest0008(CachedRowSet rs) throws Exception { } - @Test(dataProvider = "rowSetType", enabled = false) + @Disabled + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonCachedRowSetTest0026(CachedRowSet rs) throws Exception { } - @Test(dataProvider = "rowSetType", enabled = false) + @Disabled + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonCachedRowSetTest0027(CachedRowSet rs) throws Exception { } - @Test(dataProvider = "rowSetType", enabled = false) + @Disabled + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonCachedRowSetTest0053(CachedRowSet rs) throws Exception { } - @Test(dataProvider = "rowSetType", enabled = false) + @Disabled + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonCachedRowSetTest0054(CachedRowSet rs) throws Exception { } - @Test(dataProvider = "rowSetType", enabled = false) + @Disabled + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void commonCachedRowSetTest0055(CachedRowSet rs) throws Exception { } - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void WebRowSetTest0009(WebRowSet wrs1) throws Exception { } } diff --git a/test/jdk/javax/sql/test/rowset/resourcebundle/TEST.properties b/test/jdk/javax/sql/test/rowset/resourcebundle/TEST.properties new file mode 100644 index 00000000000..045227a0c2b --- /dev/null +++ b/test/jdk/javax/sql/test/rowset/resourcebundle/TEST.properties @@ -0,0 +1,2 @@ +# Enabled for ValidateGetBundle.java +modules = java.sql.rowset/com.sun.rowset:+open diff --git a/test/jdk/javax/sql/resourceBundleTests/ValidateGetBundle.java b/test/jdk/javax/sql/test/rowset/resourcebundle/ValidateGetBundle.java similarity index 94% rename from test/jdk/javax/sql/resourceBundleTests/ValidateGetBundle.java rename to test/jdk/javax/sql/test/rowset/resourcebundle/ValidateGetBundle.java index be17caed5c8..63f12740c09 100644 --- a/test/jdk/javax/sql/resourceBundleTests/ValidateGetBundle.java +++ b/test/jdk/javax/sql/test/rowset/resourcebundle/ValidateGetBundle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,6 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ +package test.rowset.resourcebundle; import com.sun.rowset.JdbcRowSetResourceBundle; @@ -35,8 +36,6 @@ import org.junit.jupiter.params.provider.Arguments; * @test * @bug 8294989 * @summary Check JDBC RowSet resource bundle access - * @modules java.sql.rowset/com.sun.rowset:+open - * @run junit/othervm ValidateGetBundle */ public class ValidateGetBundle{ diff --git a/test/jdk/javax/sql/testng/test/rowset/ValidateResourceBundleAccess.java b/test/jdk/javax/sql/test/rowset/resourcebundle/ValidateResourceBundleAccess.java similarity index 89% rename from test/jdk/javax/sql/testng/test/rowset/ValidateResourceBundleAccess.java rename to test/jdk/javax/sql/test/rowset/resourcebundle/ValidateResourceBundleAccess.java index 7591891c42b..5deca26cb25 100644 --- a/test/jdk/javax/sql/testng/test/rowset/ValidateResourceBundleAccess.java +++ b/test/jdk/javax/sql/test/rowset/resourcebundle/ValidateResourceBundleAccess.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,21 +20,21 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package test.rowset; +package test.rowset.resourcebundle; import java.util.Locale; import java.sql.SQLException; import javax.sql.rowset.RowSetProvider; -import org.testng.annotations.Test; -import org.testng.annotations.BeforeClass; -import static org.testng.Assert.*; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; /** * @test * @bug 8294989 * @summary Check that the resource bundle can be accessed * @throws SQLException if an unexpected error occurs - * @run testng/othervm */ public class ValidateResourceBundleAccess{ // Expected JDBCResourceBundle message, jdbcrowsetimpl.invalstate @@ -43,8 +43,8 @@ public class ValidateResourceBundleAccess{ private static final String RSREADERERROR = "Internal Error in RowSetReader: no connection or command"; // Checking against English messages, set to US Locale - @BeforeClass - public void setEnglishEnvironment() { + @BeforeAll + public static void setEnglishEnvironment() { Locale.setDefault(Locale.US); } diff --git a/test/jdk/javax/sql/testng/test/rowset/serial/SQLInputImplTests.java b/test/jdk/javax/sql/test/rowset/serial/SQLInputImplTests.java similarity index 92% rename from test/jdk/javax/sql/testng/test/rowset/serial/SQLInputImplTests.java rename to test/jdk/javax/sql/test/rowset/serial/SQLInputImplTests.java index 5bd10ed8848..33efda61c4e 100644 --- a/test/jdk/javax/sql/testng/test/rowset/serial/SQLInputImplTests.java +++ b/test/jdk/javax/sql/test/rowset/serial/SQLInputImplTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * 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,9 +33,11 @@ import java.util.Arrays; import java.util.HashMap; import java.util.Map; import javax.sql.rowset.serial.SQLInputImpl; -import static org.testng.Assert.*; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + import util.BaseTest; import util.StubArray; import util.StubBlob; @@ -54,7 +56,7 @@ public class SQLInputImplTests extends BaseTest { private SuperHero hero; private final String sqlType = "SUPERHERO"; - @BeforeMethod + @BeforeEach public void setUpMethod() throws Exception { map = new HashMap<>(); impl = new TestSQLDataImpl("TestSQLData"); @@ -68,18 +70,22 @@ public class SQLInputImplTests extends BaseTest { * Validate that a SQLException is thrown if the attribute value is * null */ - @Test(expectedExceptions = SQLException.class) + @Test public void test() throws Exception { - SQLInputImpl x = new SQLInputImpl(null, map); + assertThrows(SQLException.class, () -> { + SQLInputImpl x = new SQLInputImpl(null, map); + }); } /* * Validate that a SQLException is thrown if the map value is * null */ - @Test(expectedExceptions = SQLException.class) + @Test public void test02() throws Exception { - SQLInputImpl x = new SQLInputImpl(typeValues, null); + assertThrows(SQLException.class, () -> { + SQLInputImpl x = new SQLInputImpl(typeValues, null); + }); } /* @@ -124,7 +130,7 @@ public class SQLInputImplTests extends BaseTest { /* * Validate a Array can be read */ - @Test(enabled = true) + @Test public void test06() throws Exception { Object[] coffees = new Object[]{"Espresso", "Colombian", "French Roast", "Cappuccino"}; @@ -139,7 +145,7 @@ public class SQLInputImplTests extends BaseTest { /* * Validate a Blob can be read */ - @Test(enabled = true) + @Test public void test07() throws Exception { Blob b = new StubBlob(); Object[] values = {b}; @@ -153,7 +159,7 @@ public class SQLInputImplTests extends BaseTest { /* * Validate a Clob can be read */ - @Test(enabled = true) + @Test public void test08() throws Exception { Clob c = new StubClob(); Object[] values = {c}; @@ -166,7 +172,7 @@ public class SQLInputImplTests extends BaseTest { /* * Validate a Ref can be read */ - @Test(enabled = true) + @Test public void test09() throws Exception { Ref ref = new StubRef(sqlType, hero); Object[] values = {ref}; @@ -179,7 +185,7 @@ public class SQLInputImplTests extends BaseTest { /* * Validate a URL can be read */ - @Test(enabled = true) + @Test public void test10() throws Exception { URL u = new URL("http://www.oracle.com/"); Object[] values = {u}; diff --git a/test/jdk/javax/sql/testng/test/rowset/serial/SQLOutputImplTests.java b/test/jdk/javax/sql/test/rowset/serial/SQLOutputImplTests.java similarity index 91% rename from test/jdk/javax/sql/testng/test/rowset/serial/SQLOutputImplTests.java rename to test/jdk/javax/sql/test/rowset/serial/SQLOutputImplTests.java index 1f90c9981a7..83712e81396 100644 --- a/test/jdk/javax/sql/testng/test/rowset/serial/SQLOutputImplTests.java +++ b/test/jdk/javax/sql/test/rowset/serial/SQLOutputImplTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * 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,9 +41,11 @@ import javax.sql.rowset.serial.SerialClob; import javax.sql.rowset.serial.SerialDatalink; import javax.sql.rowset.serial.SerialRef; import javax.sql.rowset.serial.SerialStruct; -import static org.testng.Assert.*; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + import util.BaseTest; import util.StubArray; import util.StubBlob; @@ -64,7 +66,7 @@ public class SQLOutputImplTests extends BaseTest { private SuperHero hero; private SQLOutputImpl outImpl; - @BeforeMethod + @BeforeEach public void setUpMethod() throws Exception { results = new Vector(); impl = new TestSQLDataImpl("TestSQLData"); @@ -78,18 +80,22 @@ public class SQLOutputImplTests extends BaseTest { * Validate that a SQLException is thrown if the attribute value is * null */ - @Test(expectedExceptions = SQLException.class) + @Test public void test() throws Exception { - SQLOutputImpl x = new SQLOutputImpl(null, map); + assertThrows(SQLException.class, () -> { + SQLOutputImpl x = new SQLOutputImpl(null, map); + }); } /* * Validate that a SQLException is thrown if the map value is * null */ - @Test(expectedExceptions = SQLException.class) + @Test public void test02() throws Exception { - SQLOutputImpl x = new SQLOutputImpl(results, null); + assertThrows(SQLException.class, () -> { + SQLOutputImpl x = new SQLOutputImpl(results, null); + }); } /* @@ -109,7 +115,7 @@ public class SQLOutputImplTests extends BaseTest { /* * Validate a Array can be written and returned */ - @Test(enabled = true) + @Test public void test04() throws Exception { Object[] coffees = new Object[]{"Espresso", "Colombian", "French Roast", "Cappuccino"}; @@ -123,7 +129,7 @@ public class SQLOutputImplTests extends BaseTest { /* * Validate a Blob can be written and returned */ - @Test(enabled = true) + @Test public void test05() throws Exception { Blob b = new StubBlob(); outImpl.writeBlob(b); @@ -136,7 +142,7 @@ public class SQLOutputImplTests extends BaseTest { /* * Validate a Clob can be written and returned */ - @Test(enabled = true) + @Test public void test06() throws Exception { Clob c = new StubClob(); outImpl.writeClob(c); @@ -148,7 +154,7 @@ public class SQLOutputImplTests extends BaseTest { /* * Validate a Ref can be written and returned */ - @Test(enabled = true) + @Test public void test07() throws Exception { Ref ref = new StubRef(sqlType, hero); outImpl.writeRef(ref); @@ -159,7 +165,7 @@ public class SQLOutputImplTests extends BaseTest { /* * Validate a Struct can be written and returned */ - @Test(enabled = true) + @Test public void test08() throws Exception { Object[] attributes = new Object[]{"Bruce", "Wayne", 1939, "Batman"}; @@ -173,7 +179,7 @@ public class SQLOutputImplTests extends BaseTest { /* * Validate a DataLink can be written and returned */ - @Test(enabled = true) + @Test public void test09() throws Exception { URL u = new URL("http://www.oracle.com/"); outImpl.writeURL(u); @@ -186,7 +192,7 @@ public class SQLOutputImplTests extends BaseTest { /* * Validate an Object implementing SQLData can be written and returned */ - @Test(enabled = true) + @Test public void test10() throws Exception { Object[] attributes = new Object[]{"Bruce", "Wayne", 1939, "Batman"}; diff --git a/test/jdk/javax/sql/testng/test/rowset/serial/SerialArrayTests.java b/test/jdk/javax/sql/test/rowset/serial/SerialArrayTests.java similarity index 72% rename from test/jdk/javax/sql/testng/test/rowset/serial/SerialArrayTests.java rename to test/jdk/javax/sql/test/rowset/serial/SerialArrayTests.java index 345315b7f05..892de9416a1 100644 --- a/test/jdk/javax/sql/testng/test/rowset/serial/SerialArrayTests.java +++ b/test/jdk/javax/sql/test/rowset/serial/SerialArrayTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * 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,9 +29,11 @@ import java.util.HashMap; import java.util.Map; import javax.sql.rowset.serial.SerialArray; import javax.sql.rowset.serial.SerialException; -import static org.testng.Assert.*; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + import util.BaseTest; import util.StubArray; @@ -42,7 +44,7 @@ public class SerialArrayTests extends BaseTest { private Array a; private Map> map; - @BeforeMethod + @BeforeEach public void setUpMethod() throws Exception { coffees = new Object[]{"Espresso", "Colombian", "French Roast", "Cappuccino"}; @@ -61,111 +63,133 @@ public class SerialArrayTests extends BaseTest { /* * Validate a SQLException is thrown if the map is null */ - @Test(expectedExceptions = SQLException.class) + @Test public void test02() throws Exception { - SerialArray sa = new SerialArray(a, null); + assertThrows(SQLException.class, () -> { + SerialArray sa = new SerialArray(a, null); + }); } /* * Validate a SerialException is thrown when getResultSet() is called */ - @Test(expectedExceptions = SerialException.class) + @Test public void test03() throws Exception { - SerialArray sa = new SerialArray(a); - sa.getResultSet(); + assertThrows(SerialException.class, () -> { + SerialArray sa = new SerialArray(a); + sa.getResultSet(); + }); } /* * Validate a SerialException is thrown when getResultSet() is called */ - @Test(expectedExceptions = SerialException.class) + @Test public void test04() throws Exception { - SerialArray sa = new SerialArray(a); - sa.getResultSet(null); + assertThrows(SerialException.class, () -> { + SerialArray sa = new SerialArray(a); + sa.getResultSet(null); + }); } /* * Validate a SerialException is thrown when getResultSet() is called */ - @Test(expectedExceptions = SerialException.class) + @Test public void test05() throws Exception { - SerialArray sa = new SerialArray(a); - sa.getResultSet(1, 1); + assertThrows(SerialException.class, () -> { + SerialArray sa = new SerialArray(a); + sa.getResultSet(1, 1); + }); } /* * Validate a SerialException is thrown when getResultSet() is called */ - @Test(expectedExceptions = SerialException.class) + @Test public void test06() throws Exception { - SerialArray sa = new SerialArray(a); - sa.getResultSet(1, 1, null); + assertThrows(SerialException.class, () -> { + SerialArray sa = new SerialArray(a); + sa.getResultSet(1, 1, null); + }); } /* * Validate a SerialException is thrown when getArray() is invoked after * free() is called */ - @Test(expectedExceptions = SerialException.class) + @Test public void test07() throws Exception { - SerialArray sa = new SerialArray(a); - sa.free(); - sa.getArray(); + assertThrows(SerialException.class, () -> { + SerialArray sa = new SerialArray(a); + sa.free(); + sa.getArray(); + }); } /* * Validate a SerialException is thrown when getArray() is invoked after * free() is called */ - @Test(expectedExceptions = SerialException.class) + @Test public void test08() throws Exception { - SerialArray sa = new SerialArray(a); - sa.free(); - sa.getArray(map); + assertThrows(SerialException.class, () -> { + SerialArray sa = new SerialArray(a); + sa.free(); + sa.getArray(map); + }); } /* * Validate a SerialException is thrown when getArray() is invoked after * free() is called */ - @Test(expectedExceptions = SerialException.class) + @Test public void test09() throws Exception { - SerialArray sa = new SerialArray(a); - sa.free(); - sa.getArray(1, 1, map); + assertThrows(SerialException.class, () -> { + SerialArray sa = new SerialArray(a); + sa.free(); + sa.getArray(1, 1, map); + }); } /* * Validate a SerialException is thrown when getArray() is invoked after * free() is called */ - @Test(expectedExceptions = SerialException.class) + @Test public void test10() throws Exception { - SerialArray sa = new SerialArray(a); - sa.free(); - sa.getArray(1, 1); + assertThrows(SerialException.class, () -> { + SerialArray sa = new SerialArray(a); + sa.free(); + sa.getArray(1, 1); + }); } /* * Validate a SerialException is thrown when getBaseType() is invoked after * free() is called */ - @Test(expectedExceptions = SerialException.class) + @Test public void test11() throws Exception { - SerialArray sa = new SerialArray(a); - sa.free(); - sa.getBaseType(); + assertThrows(SerialException.class, () -> { + SerialArray sa = new SerialArray(a); + sa.free(); + sa.getBaseType(); + }); } /* * Validate a SerialException is thrown when getBaseTypeName() is invoked after * free() is called */ - @Test(expectedExceptions = SerialException.class) + @Test public void test12() throws Exception { - SerialArray sa = new SerialArray(a); - sa.free(); - sa.getBaseTypeName(); + assertThrows(SerialException.class, () -> { + SerialArray sa = new SerialArray(a); + sa.free(); + sa.getBaseTypeName(); + }); } /* diff --git a/test/jdk/javax/sql/testng/test/rowset/serial/SerialBlobTests.java b/test/jdk/javax/sql/test/rowset/serial/SerialBlobTests.java similarity index 69% rename from test/jdk/javax/sql/testng/test/rowset/serial/SerialBlobTests.java rename to test/jdk/javax/sql/test/rowset/serial/SerialBlobTests.java index f3f6c327683..f4a32bc19d7 100644 --- a/test/jdk/javax/sql/testng/test/rowset/serial/SerialBlobTests.java +++ b/test/jdk/javax/sql/test/rowset/serial/SerialBlobTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,11 +24,14 @@ package test.rowset.serial; import java.io.InputStream; import java.io.OutputStream; +import java.sql.SQLException; import java.util.Arrays; import javax.sql.rowset.serial.SerialBlob; import javax.sql.rowset.serial.SerialException; -import static org.testng.Assert.*; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + import util.BaseTest; import util.StubBlob; @@ -37,6 +40,16 @@ public class SerialBlobTests extends BaseTest { // byte[] used to populate SerialBlob private byte[] bytes = new byte[]{1, 2, 3, 4, 5}; + /* + * Validate calling setBinaryStream() on a SerialBlob constructed from a + * byte array throws SerialException. Bug 7077451. + */ + @Test + void setBinaryStreamExceptionTest() throws SQLException { + SerialBlob blob = new SerialBlob(new byte[0]); + assertThrows(SerialException.class, () -> blob.setBinaryStream(0)); + } + /* * Validate calling free() does not throw an Exception */ @@ -50,110 +63,130 @@ public class SerialBlobTests extends BaseTest { * Validate calling getBinaryStream() after calling free() throws an * SerialException */ - @Test(expectedExceptions = SerialException.class) + @Test public void test01() throws Exception { - SerialBlob sb = new SerialBlob(new StubBlob()); - sb.free(); - sb.getBinaryStream(); + assertThrows(SerialException.class, () -> { + SerialBlob sb = new SerialBlob(new StubBlob()); + sb.free(); + sb.getBinaryStream(); + }); } /* * Validate calling getBinaryStream() after calling free() throws an * SerialException */ - @Test(expectedExceptions = SerialException.class) + @Test public void test02() throws Exception { - SerialBlob sb = new SerialBlob(new StubBlob()); - sb.free(); - sb.getBinaryStream(1, 5); + assertThrows(SerialException.class, () -> { + SerialBlob sb = new SerialBlob(new StubBlob()); + sb.free(); + sb.getBinaryStream(1, 5); + }); } /* * Validate calling getBytes() after calling free() throws an * SerialException */ - @Test(expectedExceptions = SerialException.class) + @Test public void test03() throws Exception { - SerialBlob sb = new SerialBlob(new StubBlob()); - sb.free(); - sb.getBytes(1, 1); + assertThrows(SerialException.class, () -> { + SerialBlob sb = new SerialBlob(new StubBlob()); + sb.free(); + sb.getBytes(1, 1); + }); } /* * Validate calling getLength() after calling free() throws an * SerialException */ - @Test(expectedExceptions = SerialException.class) + @Test public void test04() throws Exception { - SerialBlob sb = new SerialBlob(new StubBlob()); - sb.free(); - sb.length(); + assertThrows(SerialException.class, () -> { + SerialBlob sb = new SerialBlob(new StubBlob()); + sb.free(); + sb.length(); + }); } /* * Validate calling position() after calling free() throws an * SerialException */ - @Test(expectedExceptions = SerialException.class) + @Test public void test05() throws Exception { - SerialBlob sb = new SerialBlob(new StubBlob()); - sb.free(); - sb.position(new byte[5], 1); + assertThrows(SerialException.class, () -> { + SerialBlob sb = new SerialBlob(new StubBlob()); + sb.free(); + sb.position(new byte[5], 1); + }); } /* * Validate calling position() after calling free() throws an * SerialException */ - @Test(expectedExceptions = SerialException.class) + @Test public void test06() throws Exception { - SerialBlob sb = new SerialBlob(new StubBlob()); - sb.free(); - sb.position(new StubBlob(), 1); + assertThrows(SerialException.class, () -> { + SerialBlob sb = new SerialBlob(new StubBlob()); + sb.free(); + sb.position(new StubBlob(), 1); + }); } /* * Validate calling free() after calling setBinaryStream() throws an * SerialException */ - @Test(expectedExceptions = SerialException.class) + @Test public void test07() throws Exception { - SerialBlob sb = new SerialBlob(new StubBlob()); - sb.free(); - sb.setBinaryStream(5); + assertThrows(SerialException.class, () -> { + SerialBlob sb = new SerialBlob(new StubBlob()); + sb.free(); + sb.setBinaryStream(5); + }); } /* * Validate calling free() after calling setBytes() throws an * SerialException */ - @Test(expectedExceptions = SerialException.class) + @Test public void test08() throws Exception { - SerialBlob sb = new SerialBlob(new StubBlob()); - sb.free(); - sb.setBytes(1, new byte[5]); + assertThrows(SerialException.class, () -> { + SerialBlob sb = new SerialBlob(new StubBlob()); + sb.free(); + sb.setBytes(1, new byte[5]); + }); } /* * Validate calling setBytes() after calling free() throws an * SerialException */ - @Test(expectedExceptions = SerialException.class) + @Test public void test09() throws Exception { - SerialBlob sb = new SerialBlob(new StubBlob()); - sb.free(); - sb.setBytes(1, new byte[10], 0, 5); + assertThrows(SerialException.class, () -> { + SerialBlob sb = new SerialBlob(new StubBlob()); + sb.free(); + sb.setBytes(1, new byte[10], 0, 5); + }); } /* * Validate calling truncate() after calling free() throws an * SerialException */ - @Test(expectedExceptions = SerialException.class) + @Test public void test10() throws Exception { - SerialBlob sb = new SerialBlob(new StubBlob()); - sb.free(); - sb.truncate(1); + assertThrows(SerialException.class, () -> { + SerialBlob sb = new SerialBlob(new StubBlob()); + sb.free(); + sb.truncate(1); + }); } /* @@ -173,56 +206,68 @@ public class SerialBlobTests extends BaseTest { /* * Validate a SerialException is thrown if pos < 0 for getBinaryStream */ - @Test(expectedExceptions = SerialException.class) + @Test public void test12() throws Exception { - SerialBlob sb = new SerialBlob(bytes); - InputStream is = sb.getBinaryStream(-1, 3); + assertThrows(SerialException.class, () -> { + SerialBlob sb = new SerialBlob(bytes); + InputStream is = sb.getBinaryStream(-1, 3); + }); } /* * Validate a SerialException is thrown if pos = 0 for getBinaryStream */ - @Test(expectedExceptions = SerialException.class) + @Test public void test13() throws Exception { - SerialBlob sb = new SerialBlob(bytes); - InputStream is = sb.getBinaryStream(0, 3); + assertThrows(SerialException.class, () -> { + SerialBlob sb = new SerialBlob(bytes); + InputStream is = sb.getBinaryStream(0, 3); + }); } /* * Validate a SerialException is thrown if len > the length of the stream * for getBinaryStream */ - @Test(expectedExceptions = SerialException.class) + @Test public void test14() throws Exception { - SerialBlob sb = new SerialBlob(bytes); - InputStream is = sb.getBinaryStream(0, 3); + assertThrows(SerialException.class, () -> { + SerialBlob sb = new SerialBlob(bytes); + InputStream is = sb.getBinaryStream(0, 3); + }); } /* * Validate a SerialException is thrown if length < 1 */ - @Test(expectedExceptions = SerialException.class) + @Test public void test15() throws Exception { - SerialBlob sb = new SerialBlob(bytes); - InputStream is = sb.getBinaryStream(1, 0); + assertThrows(SerialException.class, () -> { + SerialBlob sb = new SerialBlob(bytes); + InputStream is = sb.getBinaryStream(1, 0); + }); } /* * Validate a SerialException is thrown if length > byte array length */ - @Test(expectedExceptions = SerialException.class) + @Test public void test16() throws Exception { - SerialBlob sb = new SerialBlob(bytes); - InputStream is = sb.getBinaryStream(1, 6); + assertThrows(SerialException.class, () -> { + SerialBlob sb = new SerialBlob(bytes); + InputStream is = sb.getBinaryStream(1, 6); + }); } /* * Validate a SerialException is thrown if pos > byte array length */ - @Test(expectedExceptions = SerialException.class) + @Test public void test17() throws Exception { - SerialBlob sb = new SerialBlob(bytes); - InputStream is = sb.getBinaryStream(bytes.length + 2, 6); + assertThrows(SerialException.class, () -> { + SerialBlob sb = new SerialBlob(bytes); + InputStream is = sb.getBinaryStream(bytes.length + 2, 6); + }); } /* @@ -241,12 +286,14 @@ public class SerialBlobTests extends BaseTest { /* * Test clone after free has been called that the clone is not accessible */ - @Test(expectedExceptions = SerialException.class) + @Test public void test19() throws Exception { - SerialBlob sb = new SerialBlob(bytes); - sb.free(); - SerialBlob sb2 = (SerialBlob) sb.clone(); - InputStream is = sb2.getBinaryStream(1, 3); + assertThrows(SerialException.class, () -> { + SerialBlob sb = new SerialBlob(bytes); + sb.free(); + SerialBlob sb2 = (SerialBlob) sb.clone(); + InputStream is = sb2.getBinaryStream(1, 3); + }); } /* @@ -264,10 +311,12 @@ public class SerialBlobTests extends BaseTest { * Validate a SerialException is thrown if byte[] is used to * create the SeriablBlob and setBinaryStream is called */ - @Test(expectedExceptions = SerialException.class) + @Test public void test21() throws Exception { - SerialBlob sb = new SerialBlob(bytes); - sb.setBinaryStream(3); + assertThrows(SerialException.class, () -> { + SerialBlob sb = new SerialBlob(bytes); + sb.setBinaryStream(3); + }); } /* @@ -281,7 +330,7 @@ public class SerialBlobTests extends BaseTest { byte[] expected = new byte[]{1, 7, 8, 9, 5}; SerialBlob sb = new SerialBlob(bytes); int written = sb.setBytes(2, diff); - assertEquals(written, diff.length); + assertEquals(diff.length, written); assertTrue( Arrays.equals(sb.getBytes(1, (int) sb.length()), expected), @@ -300,7 +349,7 @@ public class SerialBlobTests extends BaseTest { byte[] expected = new byte[]{1, 8, 9, 0, 5}; SerialBlob sb = new SerialBlob(bytes); int written = sb.setBytes(2, diff, 1, bytesToWrite); - assertEquals(written, bytesToWrite); + assertEquals(bytesToWrite, written); assertTrue( Arrays.equals(sb.getBytes(1, (int) sb.length()), expected), @@ -355,7 +404,7 @@ public class SerialBlobTests extends BaseTest { byte[] pattern = new byte[]{3, 4}; SerialBlob sb = new SerialBlob(bytes); long pos = sb.position(pattern, 1); - assertEquals(pos, expectedPos); + assertEquals(expectedPos, pos); } /* @@ -368,7 +417,7 @@ public class SerialBlobTests extends BaseTest { byte[] pattern = new byte[]{3, 4, 5}; SerialBlob sb = new SerialBlob(bytes); long pos = sb.position(pattern, 2); - assertEquals(pos, expectedPos); + assertEquals(expectedPos, pos); } /* @@ -381,7 +430,7 @@ public class SerialBlobTests extends BaseTest { byte[] pattern = new byte[]{4, 6}; SerialBlob sb = new SerialBlob(new StubBlob()); long pos = sb.position(pattern, 1); - assertEquals(pos, expectedPos); + assertEquals(expectedPos, pos); } /* @@ -394,7 +443,7 @@ public class SerialBlobTests extends BaseTest { byte[] pattern = new byte[]{6, 8}; SerialBlob sb = new SerialBlob(new StubBlob()); long pos = sb.position(pattern, 2); - assertEquals(pos, expectedPos); + assertEquals(expectedPos, pos); } /* @@ -411,8 +460,8 @@ public class SerialBlobTests extends BaseTest { byte[] expected = new byte[]{1, 2, 3, 4, 7}; SerialBlob sb = new SerialBlob(bytes); int written = sb.setBytes(writePos, diff, 0, bytesToWrite); - assertEquals(written, bytesToWrite); - assertEquals(sb.getBytes(1, (int) sb.length()), expected); + assertEquals(bytesToWrite, written); + assertArrayEquals(expected, sb.getBytes(1, (int) sb.length())); } /* @@ -428,8 +477,8 @@ public class SerialBlobTests extends BaseTest { byte[] expected = new byte[]{1, 2, 3, 4, 8, 9}; SerialBlob sb = new SerialBlob(bytes); int written = sb.setBytes(writePos, diff, 1, bytesToWrite); - assertEquals(written, bytesToWrite); - assertEquals(sb.getBytes(1, (int) sb.length()), expected); + assertEquals(bytesToWrite, written); + assertArrayEquals(expected, sb.getBytes(1, (int) sb.length())); } /* @@ -445,29 +494,33 @@ public class SerialBlobTests extends BaseTest { byte[] expected = new byte[]{1, 2, 3, 4, 5, 8, 9, 0}; SerialBlob sb = new SerialBlob(bytes); int written = sb.setBytes(writePos, diff, 1, bytesToWrite); - assertEquals(written, bytesToWrite); - assertEquals(sb.getBytes(1, (int) sb.length()), expected); + assertEquals(bytesToWrite, written); + assertArrayEquals(expected, sb.getBytes(1, (int) sb.length())); } /* * Validate a SerialException is thrown if length < 0 for setBytes */ - @Test(expectedExceptions = SerialException.class) + @Test public void test34() throws Exception { - int length = -1; - SerialBlob sb = new SerialBlob(bytes); - int written = sb.setBytes(1, new byte[]{1}, 1, length); + assertThrows(SerialException.class, () -> { + int length = -1; + SerialBlob sb = new SerialBlob(bytes); + int written = sb.setBytes(1, new byte[]{1}, 1, length); + }); } /* * Validate a SerialException is thrown if length + offset > * Integer.MAX_VALUE for setBytes */ - @Test(expectedExceptions = SerialException.class) + @Test public void test35() throws Exception { - int offset = 1; - int length = Integer.MAX_VALUE; - SerialBlob sb = new SerialBlob(bytes); - int written = sb.setBytes(1, new byte[]{1, 2, 3}, offset, length); + assertThrows(SerialException.class, () -> { + int offset = 1; + int length = Integer.MAX_VALUE; + SerialBlob sb = new SerialBlob(bytes); + int written = sb.setBytes(1, new byte[]{1, 2, 3}, offset, length); + }); } } diff --git a/test/jdk/javax/sql/testng/test/rowset/serial/SerialClobTests.java b/test/jdk/javax/sql/test/rowset/serial/SerialClobTests.java similarity index 72% rename from test/jdk/javax/sql/testng/test/rowset/serial/SerialClobTests.java rename to test/jdk/javax/sql/test/rowset/serial/SerialClobTests.java index 95c5f6f64a7..2636c3b6a84 100644 --- a/test/jdk/javax/sql/testng/test/rowset/serial/SerialClobTests.java +++ b/test/jdk/javax/sql/test/rowset/serial/SerialClobTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * 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,10 +26,14 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.Reader; import java.io.Writer; +import java.sql.SQLException; import javax.sql.rowset.serial.SerialClob; import javax.sql.rowset.serial.SerialException; -import static org.testng.Assert.*; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + import util.BaseTest; import util.StubClob; @@ -43,6 +47,26 @@ public class SerialClobTests extends BaseTest { 'o', 'r', 'l', 'd'}; } + /* + * Validate calling setAsciiStream() on a SerialClob constructed from a + * char array throws SerialException. Bug 7077451. + */ + @Test + void setAsciiStreamExceptionTest() throws SQLException { + SerialClob clob = new SerialClob(new char[0]); + assertThrows(SerialException.class, () -> clob.setAsciiStream(0)); + } + + /* + * Validate calling setCharacterStream() on a SerialClob constructed from a + * char array throws SerialException. Bug 7077451. + */ + @Test + void setCharacterStreamExceptionTest() throws SQLException { + SerialClob clob = new SerialClob(new char[0]); + assertThrows(SerialException.class, () -> clob.setCharacterStream(0)); + } + /* * Validate calling free() does not throw an Exception */ @@ -56,192 +80,228 @@ public class SerialClobTests extends BaseTest { * Validate calling getCharacterStream() after calling free() throws an * SerialException */ - @Test(expectedExceptions = SerialException.class) + @Test public void test01() throws Exception { - SerialClob sc = new SerialClob(new StubClob()); - sc.free(); - sc.getCharacterStream(); + assertThrows(SerialException.class, () -> { + SerialClob sc = new SerialClob(new StubClob()); + sc.free(); + sc.getCharacterStream(); + }); } /* * Validate calling getCharacterStream() after calling free() throws an * SerialException */ - @Test(expectedExceptions = SerialException.class) + @Test public void test02() throws Exception { - SerialClob sc = new SerialClob(chars); - sc.free(); - sc.getCharacterStream(); + assertThrows(SerialException.class, () -> { + SerialClob sc = new SerialClob(chars); + sc.free(); + sc.getCharacterStream(); + }); } /* * Validate calling getCharacterStream() after calling free() throws an * SerialException */ - @Test(expectedExceptions = SerialException.class) + @Test public void test03() throws Exception { - SerialClob sc = new SerialClob(new StubClob()); - sc.free(); - sc.getCharacterStream(1, 5); + assertThrows(SerialException.class, () -> { + SerialClob sc = new SerialClob(new StubClob()); + sc.free(); + sc.getCharacterStream(1, 5); + }); } /* * Validate calling getSubString() after calling free() throws an * SerialException */ - @Test(expectedExceptions = SerialException.class) + @Test public void test04() throws Exception { - SerialClob sc = new SerialClob(new StubClob()); - sc.free(); - sc.getSubString(1, 1); + assertThrows(SerialException.class, () -> { + SerialClob sc = new SerialClob(new StubClob()); + sc.free(); + sc.getSubString(1, 1); + }); } /* * Validate calling truncate() after calling free() throws an * SerialException */ - @Test(expectedExceptions = SerialException.class) + @Test public void test05() throws Exception { - SerialClob sc = new SerialClob(new StubClob()); - sc.free(); - sc.truncate(1); + assertThrows(SerialException.class, () -> { + SerialClob sc = new SerialClob(new StubClob()); + sc.free(); + sc.truncate(1); + }); } /* * Validate calling getAsciiStream() after calling free() throws an * SerialException */ - @Test(expectedExceptions = SerialException.class) + @Test public void test06() throws Exception { - SerialClob sc = new SerialClob(new StubClob()); - sc.free(); - sc.getAsciiStream(); + assertThrows(SerialException.class, () -> { + SerialClob sc = new SerialClob(new StubClob()); + sc.free(); + sc.getAsciiStream(); + }); } /* * Validate calling length() after calling free() throws an SerialException */ - @Test(expectedExceptions = SerialException.class) + @Test public void test07() throws Exception { - SerialClob sc = new SerialClob(new StubClob()); - sc.free(); - sc.length(); + assertThrows(SerialException.class, () -> { + SerialClob sc = new SerialClob(new StubClob()); + sc.free(); + sc.length(); + }); } /* * Validate calling position() after calling free() throws an * SerialException */ - @Test(expectedExceptions = SerialException.class) + @Test public void test08() throws Exception { - SerialClob sc = new SerialClob(new StubClob()); - sc.free(); - sc.position("hello", 1); + assertThrows(SerialException.class, () -> { + SerialClob sc = new SerialClob(new StubClob()); + sc.free(); + sc.position("hello", 1); + }); } /* * Validate calling position() after calling free() throws an * SerialException */ - @Test(expectedExceptions = SerialException.class) + @Test public void test09() throws Exception { - SerialClob sc = new SerialClob(new StubClob()); - sc.free(); - sc.position(new StubClob(), 1); + assertThrows(SerialException.class, () -> { + SerialClob sc = new SerialClob(new StubClob()); + sc.free(); + sc.position(new StubClob(), 1); + }); } /* * Validate calling setAsciiStream() after calling free() throws an * SerialException */ - @Test(expectedExceptions = SerialException.class) + @Test public void test10() throws Exception { - SerialClob sc = new SerialClob(new StubClob()); - sc.free(); - sc.setAsciiStream(5); + assertThrows(SerialException.class, () -> { + SerialClob sc = new SerialClob(new StubClob()); + sc.free(); + sc.setAsciiStream(5); + }); } /* * Validate calling setCharacterStream() after calling free() throws an * SerialException */ - @Test(expectedExceptions = SerialException.class) + @Test public void test11() throws Exception { - SerialClob sc = new SerialClob(new StubClob()); - sc.free(); - sc.setCharacterStream(5); + assertThrows(SerialException.class, () -> { + SerialClob sc = new SerialClob(new StubClob()); + sc.free(); + sc.setCharacterStream(5); + }); } /* * Validate calling setString() after calling free() throws an * SerialException */ - @Test(expectedExceptions = SerialException.class) + @Test public void test12() throws Exception { - SerialClob sc = new SerialClob(new StubClob()); - sc.free(); - sc.setString(1, "hello"); + assertThrows(SerialException.class, () -> { + SerialClob sc = new SerialClob(new StubClob()); + sc.free(); + sc.setString(1, "hello"); + }); } /* * Validate calling setString() after calling free() throws an * SerialException */ - @Test(expectedExceptions = SerialException.class) + @Test public void test13() throws Exception { - SerialClob sc = new SerialClob(new StubClob()); - sc.free(); - sc.setString(1, "hello", 0, 5); + assertThrows(SerialException.class, () -> { + SerialClob sc = new SerialClob(new StubClob()); + sc.free(); + sc.setString(1, "hello", 0, 5); + }); } /* * Test that SerialException is thrown if pos < 0 on a call to * getCharacterStream */ - @Test(expectedExceptions = SerialException.class) + @Test public void test14() throws Exception { - SerialClob sc = new SerialClob(chars); - sc.getCharacterStream(-1, 5); + assertThrows(SerialException.class, () -> { + SerialClob sc = new SerialClob(chars); + sc.getCharacterStream(-1, 5); + }); } /* * Test that SerialException is thrown if pos = 0 on a call to * getCharacterStream */ - @Test(expectedExceptions = SerialException.class) + @Test public void test15() throws Exception { - SerialClob sc = new SerialClob(chars); - sc.getCharacterStream(0, 5); + assertThrows(SerialException.class, () -> { + SerialClob sc = new SerialClob(chars); + sc.getCharacterStream(0, 5); + }); } /* * Test that SerialException is thrown if pos = 0 on a call to * getCharacterStream */ - @Test(expectedExceptions = SerialException.class) + @Test public void test16() throws Exception { - SerialClob sc = new SerialClob(chars); - sc.getCharacterStream(1, 100); + assertThrows(SerialException.class, () -> { + SerialClob sc = new SerialClob(chars); + sc.getCharacterStream(1, 100); + }); } /* * Test that SerialException is thrown if length = 0 on a call to * getCharacterStream */ - @Test(expectedExceptions = SerialException.class) + @Test public void test17() throws Exception { - SerialClob sc = new SerialClob(chars); - sc.getCharacterStream(1, 0); + assertThrows(SerialException.class, () -> { + SerialClob sc = new SerialClob(chars); + sc.getCharacterStream(1, 0); + }); } /* * Test that SerialException is thrown if pos > length on a call to * getCharacterStream */ - @Test(expectedExceptions = SerialException.class) + @Test public void test18() throws Exception { - SerialClob sc = new SerialClob(chars); - sc.getCharacterStream(100, 5); + assertThrows(SerialException.class, () -> { + SerialClob sc = new SerialClob(chars); + sc.getCharacterStream(100, 5); + }); } /* @@ -401,7 +461,7 @@ public class SerialClobTests extends BaseTest { String expected = "Hello, I am the Batman!"; SerialClob sc = new SerialClob(val.toCharArray()); int written = sc.setString(13, val1); - assertEquals(val1.length(), written); + assertEquals(written, val1.length()); assertTrue(expected.equals(sc.getSubString(1, (int) sc.length()))); } @@ -420,8 +480,8 @@ public class SerialClobTests extends BaseTest { String expected = "Hi, I am the Joker!!!!!"; SerialClob sc = new SerialClob(val.toCharArray()); int written = sc.setString(writePos, val1, offset, expectedWritten); - assertEquals(written, expectedWritten); - assertEquals(sc.getSubString(1, (int) sc.length()), expected); + assertEquals(expectedWritten, written); + assertEquals(expected, sc.getSubString(1, (int) sc.length())); } /* @@ -478,7 +538,8 @@ public class SerialClobTests extends BaseTest { * Check that getCharacterStream() returns a Reader and that the char[] that * was specified to create the SerialClob can be returned via the Reader */ - @Test(enabled = false) + @Test + @Disabled public void test37() throws Exception { SerialClob sc = new SerialClob(chars); String expected = "ello w"; @@ -504,12 +565,14 @@ public class SerialClobTests extends BaseTest { * Check calling setString() with offset > val1.length() throws a * SerialException */ - @Test(expectedExceptions = SerialException.class) + @Test public void test39() throws Exception { - String val1 = "hello"; - int offset = val1.length() + 1; - SerialClob sc = new SerialClob(chars); - sc.setString(1, val1, offset, 0); + assertThrows(SerialException.class, () -> { + String val1 = "hello"; + int offset = val1.length() + 1; + SerialClob sc = new SerialClob(chars); + sc.setString(1, val1, offset, 0); + }); } /* @@ -526,8 +589,8 @@ public class SerialClobTests extends BaseTest { String expected = "Hello, I am the Joker, who are you?!"; SerialClob sc = new SerialClob(val.toCharArray()); int written = sc.setString(writePos, val1, offset, expectedWritten); - assertEquals(written, expectedWritten); - assertEquals(sc.getSubString(1, (int) sc.length()), expected); + assertEquals(expectedWritten, written); + assertEquals(expected, sc.getSubString(1, (int) sc.length())); } /* @@ -544,29 +607,33 @@ public class SerialClobTests extends BaseTest { String expected = "Hi, I am the Joker!"; SerialClob sc = new SerialClob(val.toCharArray()); int written = sc.setString(writePos, val1, offset, expectedWritten); - assertEquals(written, expectedWritten); - assertEquals(sc.getSubString(1, (int) sc.length()), expected); + assertEquals(expectedWritten, written); + assertEquals(expected, sc.getSubString(1, (int) sc.length())); } /* * Validate a SerialException is thrown if length < 0 for setString */ - @Test(expectedExceptions = SerialException.class) + @Test public void test42() throws Exception { - int length = -1; - SerialClob sc = new SerialClob(chars); - int written = sc.setString(1, "hello", 1, length); + assertThrows(SerialException.class, () -> { + int length = -1; + SerialClob sc = new SerialClob(chars); + int written = sc.setString(1, "hello", 1, length); + }); } /* * Validate a SerialException is thrown if length + offset > * Integer.MAX_VALUE for setString */ - @Test(expectedExceptions = SerialException.class) + @Test public void test43() throws Exception { - int offset = 1; - int length = Integer.MAX_VALUE; - SerialClob sc = new SerialClob(chars); - int written = sc.setString(1, "hello", offset, length); + assertThrows(SerialException.class, () -> { + int offset = 1; + int length = Integer.MAX_VALUE; + SerialClob sc = new SerialClob(chars); + int written = sc.setString(1, "hello", offset, length); + }); } } diff --git a/test/jdk/javax/sql/testng/test/rowset/serial/SerialDataLinkTests.java b/test/jdk/javax/sql/test/rowset/serial/SerialDataLinkTests.java similarity index 90% rename from test/jdk/javax/sql/testng/test/rowset/serial/SerialDataLinkTests.java rename to test/jdk/javax/sql/test/rowset/serial/SerialDataLinkTests.java index 0c7f19e85b1..12c1341161d 100644 --- a/test/jdk/javax/sql/testng/test/rowset/serial/SerialDataLinkTests.java +++ b/test/jdk/javax/sql/test/rowset/serial/SerialDataLinkTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * 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,11 @@ package test.rowset.serial; import java.net.URL; import javax.sql.rowset.serial.SerialDatalink; import javax.sql.rowset.serial.SerialException; -import static org.testng.Assert.*; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + import util.BaseTest; public class SerialDataLinkTests extends BaseTest { @@ -36,7 +38,7 @@ public class SerialDataLinkTests extends BaseTest { private URL u1; private SerialDatalink dl; - @BeforeMethod + @BeforeEach public void setUpMethod() throws Exception { u = new URL("http://www.oracle.com/"); u1 = new URL("http://www.usatoday.com/"); @@ -46,9 +48,11 @@ public class SerialDataLinkTests extends BaseTest { /* * Validate that a SerialException is thrown if the URL is null */ - @Test(expectedExceptions = SerialException.class) + @Test public void test() throws Exception { - SerialDatalink dl1 = new SerialDatalink(null); + assertThrows(SerialException.class, () -> { + SerialDatalink dl1 = new SerialDatalink(null); + }); } /* diff --git a/test/jdk/javax/sql/testng/test/rowset/serial/SerialExceptionTests.java b/test/jdk/javax/sql/test/rowset/serial/SerialExceptionTests.java similarity index 95% rename from test/jdk/javax/sql/testng/test/rowset/serial/SerialExceptionTests.java rename to test/jdk/javax/sql/test/rowset/serial/SerialExceptionTests.java index 8ef215584a9..51c733b995a 100644 --- a/test/jdk/javax/sql/testng/test/rowset/serial/SerialExceptionTests.java +++ b/test/jdk/javax/sql/test/rowset/serial/SerialExceptionTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * 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,8 +24,10 @@ package test.rowset.serial; import java.sql.SQLException; import javax.sql.rowset.serial.SerialException; -import static org.testng.Assert.*; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + import util.BaseTest; public class SerialExceptionTests extends BaseTest { diff --git a/test/jdk/javax/sql/testng/test/rowset/serial/SerialJavaObjectTests.java b/test/jdk/javax/sql/test/rowset/serial/SerialJavaObjectTests.java similarity index 86% rename from test/jdk/javax/sql/testng/test/rowset/serial/SerialJavaObjectTests.java rename to test/jdk/javax/sql/test/rowset/serial/SerialJavaObjectTests.java index c2fcf2fa48f..e521125df97 100644 --- a/test/jdk/javax/sql/testng/test/rowset/serial/SerialJavaObjectTests.java +++ b/test/jdk/javax/sql/test/rowset/serial/SerialJavaObjectTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,11 @@ import java.util.Arrays; import javax.sql.rowset.RowSetMetaDataImpl; import javax.sql.rowset.serial.SerialException; import javax.sql.rowset.serial.SerialJavaObject; -import static org.testng.Assert.*; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + import util.BaseTest; public class SerialJavaObjectTests extends BaseTest { @@ -37,18 +40,23 @@ public class SerialJavaObjectTests extends BaseTest { * Validate that an NPE is thrown when null is specified to create * the SerialJavaObject */ - @Test(expectedExceptions = NullPointerException.class) + @Test public void test() throws Exception { - SerialJavaObject sjo = new SerialJavaObject(null); + assertThrows(NullPointerException.class, () -> { + SerialJavaObject sjo = new SerialJavaObject(null); + }); } /* * Validate that a SerialException is thrown when the object specified * contains public static fields */ - @Test(expectedExceptions = SerialException.class, enabled = false) + @Test + @Disabled public void test01() throws Exception { - SerialJavaObject sjo = new SerialJavaObject(new RowSetMetaDataImpl()); + assertThrows(SerialException.class, () -> { + SerialJavaObject sjo = new SerialJavaObject(new RowSetMetaDataImpl()); + }); } /* diff --git a/test/jdk/javax/sql/testng/test/rowset/serial/SerialRefTests.java b/test/jdk/javax/sql/test/rowset/serial/SerialRefTests.java similarity index 86% rename from test/jdk/javax/sql/testng/test/rowset/serial/SerialRefTests.java rename to test/jdk/javax/sql/test/rowset/serial/SerialRefTests.java index 8f23de70aa6..1b4e72593b0 100644 --- a/test/jdk/javax/sql/testng/test/rowset/serial/SerialRefTests.java +++ b/test/jdk/javax/sql/test/rowset/serial/SerialRefTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * 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,9 +27,12 @@ import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import javax.sql.rowset.serial.SerialRef; -import static org.testng.Assert.*; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + import util.BaseTest; import util.StubRef; import util.SuperHero; @@ -41,7 +44,7 @@ public class SerialRefTests extends BaseTest { private final String sqlType = "SUPERHERO"; private SuperHero hero; - @BeforeMethod + @BeforeEach public void setUpMethod() throws Exception { map.put(sqlType, Class.forName("util.SuperHero")); hero = new SuperHero(sqlType, "Bruce", "Wayne", 1939, "Batman"); @@ -51,18 +54,22 @@ public class SerialRefTests extends BaseTest { /* * Validate that a SQLException() is thrown if the Ref is null */ - @Test(expectedExceptions = SQLException.class) + @Test public void test01() throws Exception { - SerialRef sr = new SerialRef(null); + assertThrows(SQLException.class, () -> { + SerialRef sr = new SerialRef(null); + }); } /* * Validate that a SQLException() is thrown if the typeName is null in the * Ref used to create the SerialRef */ - @Test(expectedExceptions = SQLException.class) + @Test public void test02() throws Exception { - SerialRef sr = new SerialRef(new StubRef(null, hero)); + assertThrows(SQLException.class, () -> { + SerialRef sr = new SerialRef(new StubRef(null, hero)); + }); } /* @@ -72,7 +79,7 @@ public class SerialRefTests extends BaseTest { @Test public void test03() throws Exception { SerialRef sr = new SerialRef(ref); - assertEquals(sr.getBaseTypeName(), sqlType); + assertEquals(sqlType, sr.getBaseTypeName()); } /* @@ -87,7 +94,8 @@ public class SerialRefTests extends BaseTest { /* * Validate that getObject() returns the same object used to create the Ref */ - @Test(enabled = false) + @Test + @Disabled public void test05() throws Exception { SerialRef sr = new SerialRef(ref); assertTrue(hero.equals(sr.getObject(map))); diff --git a/test/jdk/javax/sql/testng/test/rowset/serial/SerialStructTests.java b/test/jdk/javax/sql/test/rowset/serial/SerialStructTests.java similarity index 92% rename from test/jdk/javax/sql/testng/test/rowset/serial/SerialStructTests.java rename to test/jdk/javax/sql/test/rowset/serial/SerialStructTests.java index 79ac2421c9a..dfc34b60e2b 100644 --- a/test/jdk/javax/sql/testng/test/rowset/serial/SerialStructTests.java +++ b/test/jdk/javax/sql/test/rowset/serial/SerialStructTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * 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,9 +27,11 @@ import java.util.Arrays; import java.util.HashMap; import java.util.Map; import javax.sql.rowset.serial.SerialStruct; -import static org.testng.Assert.*; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + import util.BaseTest; import util.StubStruct; import util.SuperHero; @@ -42,7 +44,7 @@ public class SerialStructTests extends BaseTest { private final String sqlType = "SUPERHERO"; private SuperHero hero; - @BeforeMethod + @BeforeEach public void setUpMethod() throws Exception { attributes = new Object[]{"Bruce", "Wayne", 1939, "Batman"}; @@ -58,7 +60,7 @@ public class SerialStructTests extends BaseTest { @Test public void test01() throws Exception { SerialStruct ss = new SerialStruct(struct, map); - assertEquals(ss.getSQLTypeName(), sqlType); + assertEquals(sqlType, ss.getSQLTypeName()); } /* @@ -68,7 +70,7 @@ public class SerialStructTests extends BaseTest { @Test public void test02() throws Exception { SerialStruct ss = new SerialStruct(hero, map); - assertEquals(ss.getSQLTypeName(), sqlType); + assertEquals(sqlType, ss.getSQLTypeName()); } /* diff --git a/test/jdk/javax/sql/testng/test/rowset/spi/SyncFactoryExceptionTests.java b/test/jdk/javax/sql/test/rowset/spi/SyncFactoryExceptionTests.java similarity index 95% rename from test/jdk/javax/sql/testng/test/rowset/spi/SyncFactoryExceptionTests.java rename to test/jdk/javax/sql/test/rowset/spi/SyncFactoryExceptionTests.java index e93a6109ec7..b747c48989d 100644 --- a/test/jdk/javax/sql/testng/test/rowset/spi/SyncFactoryExceptionTests.java +++ b/test/jdk/javax/sql/test/rowset/spi/SyncFactoryExceptionTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * 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,8 +24,10 @@ package test.rowset.spi; import java.sql.SQLException; import javax.sql.rowset.spi.SyncFactoryException; -import static org.testng.Assert.*; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + import util.BaseTest; public class SyncFactoryExceptionTests extends BaseTest { diff --git a/test/jdk/javax/sql/testng/test/rowset/spi/SyncFactoryTests.java b/test/jdk/javax/sql/test/rowset/spi/SyncFactoryTests.java similarity index 92% rename from test/jdk/javax/sql/testng/test/rowset/spi/SyncFactoryTests.java rename to test/jdk/javax/sql/test/rowset/spi/SyncFactoryTests.java index 415488abb9f..260cf150f59 100644 --- a/test/jdk/javax/sql/testng/test/rowset/spi/SyncFactoryTests.java +++ b/test/jdk/javax/sql/test/rowset/spi/SyncFactoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * 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,9 +33,11 @@ import javax.naming.Context; import javax.sql.rowset.spi.SyncFactory; import javax.sql.rowset.spi.SyncFactoryException; import javax.sql.rowset.spi.SyncProvider; -import static org.testng.Assert.*; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + import util.PropertyStubProvider; import util.StubSyncProvider; import util.StubContext; @@ -67,7 +69,7 @@ public class SyncFactoryTests { ctx = new StubContext(); } - @BeforeMethod + @BeforeEach public void setUpMethod() throws Exception { // Make sure the provider provider that is registered is removed // before each run @@ -120,17 +122,21 @@ public class SyncFactoryTests { /* * Validate that a SyncFactoryException is thrown if the ProviderID is null */ - @Test(expectedExceptions = SyncFactoryException.class) + @Test public void test03() throws SyncFactoryException { - SyncProvider p = SyncFactory.getInstance(null); + assertThrows(SyncFactoryException.class, () -> { + SyncProvider p = SyncFactory.getInstance(null); + }); } /* * Validate that a SyncFactoryException is thrown if the Logger is null */ - @Test(expectedExceptions = SyncFactoryException.class,enabled=true) + @Test public void test04() throws SyncFactoryException { - Logger l = SyncFactory.getLogger(); + assertThrows(SyncFactoryException.class, () -> { + Logger l = SyncFactory.getLogger(); + }); } /* @@ -179,15 +185,15 @@ public class SyncFactoryTests { * Validate that setJNDIContext throws a SyncFactoryException if the * context is null */ - @Test(expectedExceptions = SyncFactoryException.class, enabled=true) + @Test public void test08() throws Exception { - SyncFactory.setJNDIContext(null); + assertThrows(SyncFactoryException.class, () -> SyncFactory.setJNDIContext(null)); } /* * Validate that setJNDIContext succeeds */ - @Test(enabled=true) + @Test public void test09() throws Exception { SyncFactory.setJNDIContext(ctx); } diff --git a/test/jdk/javax/sql/testng/test/rowset/spi/SyncProviderExceptionTests.java b/test/jdk/javax/sql/test/rowset/spi/SyncProviderExceptionTests.java similarity index 96% rename from test/jdk/javax/sql/testng/test/rowset/spi/SyncProviderExceptionTests.java rename to test/jdk/javax/sql/test/rowset/spi/SyncProviderExceptionTests.java index 22863b0f6bb..f8786f1b429 100644 --- a/test/jdk/javax/sql/testng/test/rowset/spi/SyncProviderExceptionTests.java +++ b/test/jdk/javax/sql/test/rowset/spi/SyncProviderExceptionTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * 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,11 +27,12 @@ import java.sql.SQLException; import javax.sql.rowset.spi.SyncProviderException; import javax.sql.rowset.spi.SyncResolver; -import static org.testng.Assert.*; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; +import org.junit.jupiter.api.AfterAll; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + import util.BaseTest; import util.StubSyncResolver; @@ -40,16 +41,16 @@ public class SyncProviderExceptionTests extends BaseTest { // Used by SyncProviderException::getSyncResolver tests private SyncResolver resolver; - @BeforeClass + @BeforeAll public static void setUpClass() throws Exception { System.out.println(System.getProperty("java.naming.factory.initial")); } - @AfterClass + @AfterAll public static void tearDownClass() throws Exception { } - @BeforeMethod + @BeforeEach public void setupTest() { resolver = new SyncProviderException().getSyncResolver(); } diff --git a/test/jdk/javax/sql/testng/test/rowset/webrowset/CommonWebRowSetTests.java b/test/jdk/javax/sql/test/rowset/webrowset/CommonWebRowSetTests.java similarity index 81% rename from test/jdk/javax/sql/testng/test/rowset/webrowset/CommonWebRowSetTests.java rename to test/jdk/javax/sql/test/rowset/webrowset/CommonWebRowSetTests.java index ce0801e0fe4..023adc8254b 100644 --- a/test/jdk/javax/sql/testng/test/rowset/webrowset/CommonWebRowSetTests.java +++ b/test/jdk/javax/sql/test/rowset/webrowset/CommonWebRowSetTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,11 +35,15 @@ import java.math.BigDecimal; import java.sql.ResultSet; import java.util.Arrays; import javax.sql.rowset.WebRowSet; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertEqualsNoOrder; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertTrue; -import org.testng.annotations.Test; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + import test.rowset.cachedrowset.CommonCachedRowSetTests; public abstract class CommonWebRowSetTests extends CommonCachedRowSetTests { @@ -131,10 +135,11 @@ public abstract class CommonWebRowSetTests extends CommonCachedRowSetTests { /* * Validate the expected Rows are contained within the RowSet */ - @Test(dataProvider = "rowsetUsingCoffees") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffees") public void WebRowSetTest0000(WebRowSet wrs) throws Exception { - assertEquals(getPrimaryKeys(wrs), COFFEES_PRIMARY_KEYS); - assertEquals(wrs.size(), COFFEES_ROWS); + assertArrayEquals(COFFEES_PRIMARY_KEYS, getPrimaryKeys(wrs)); + assertEquals(COFFEES_ROWS, wrs.size()); wrs.close(); } @@ -142,14 +147,15 @@ public abstract class CommonWebRowSetTests extends CommonCachedRowSetTests { * Validate the expected Rows are contained within the RowSet * populated by readXML(Reader) */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void WebRowSetTest0001(WebRowSet wrs1) throws Exception { try (FileReader fr = new FileReader(COFFEE_ROWS_XML)) { wrs1.readXml(fr); } - assertEquals(getPrimaryKeys(wrs1), COFFEES_PRIMARY_KEYS); - assertEquals(wrs1.size(), COFFEES_ROWS); + assertArrayEquals(COFFEES_PRIMARY_KEYS, getPrimaryKeys(wrs1)); + assertEquals(COFFEES_ROWS, wrs1.size()); wrs1.close(); } @@ -158,13 +164,14 @@ public abstract class CommonWebRowSetTests extends CommonCachedRowSetTests { * Validate the expected Rows are contained within the RowSet * populated by readXML(InputStream) */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void WebRowSetTest0002(WebRowSet wrs1) throws Exception { try (FileInputStream fis = new FileInputStream(COFFEE_ROWS_XML)) { wrs1.readXml(fis); } - assertEquals(getPrimaryKeys(wrs1), COFFEES_PRIMARY_KEYS); - assertEquals(wrs1.size(), COFFEES_ROWS); + assertArrayEquals(COFFEES_PRIMARY_KEYS, getPrimaryKeys(wrs1)); + assertEquals(COFFEES_ROWS, wrs1.size()); wrs1.close(); } @@ -173,12 +180,13 @@ public abstract class CommonWebRowSetTests extends CommonCachedRowSetTests { * back via readXML(InputStream) and validate the primary keys * are the same */ - @Test(dataProvider = "rowsetUsingCoffees") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffees") public void WebRowSetTest0003(WebRowSet wrs) throws Exception { ByteArrayOutputStream baos = writeWebRowSetWithOutputStream(wrs); try (WebRowSet wrs1 = readWebRowSetWithOInputStream(baos)) { - assertEquals(getPrimaryKeys(wrs1), COFFEES_PRIMARY_KEYS); - assertEquals(wrs1.size(), COFFEES_ROWS); + assertArrayEquals(COFFEES_PRIMARY_KEYS, getPrimaryKeys(wrs1)); + assertEquals(COFFEES_ROWS, wrs1.size()); } } @@ -187,14 +195,15 @@ public abstract class CommonWebRowSetTests extends CommonCachedRowSetTests { * back via readXML(InputStream) and validate the primary keys * are the same */ - @Test(dataProvider = "rowsetUsingCoffees") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffees") public void WebRowSetTest0004(WebRowSet wrs) throws Exception { ResultSet rs = wrs; rs.beforeFirst(); ByteArrayOutputStream baos = writeWebRowSetWithOutputStream(rs); try (WebRowSet wrs1 = readWebRowSetWithOInputStream(baos)) { - assertEquals(getPrimaryKeys(wrs1), COFFEES_PRIMARY_KEYS); - assertEquals(wrs1.size(), COFFEES_ROWS); + assertArrayEquals(COFFEES_PRIMARY_KEYS, getPrimaryKeys(wrs1)); + assertEquals(COFFEES_ROWS, wrs1.size()); } } @@ -203,12 +212,13 @@ public abstract class CommonWebRowSetTests extends CommonCachedRowSetTests { * back via readXML(Reader) and validate the primary keys * are the same */ - @Test(dataProvider = "rowsetUsingCoffees") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffees") public void WebRowSetTest0005(WebRowSet wrs) throws Exception { ByteArrayOutputStream baos = writeWebRowSetWithOutputStreamWithWriter(wrs); try (WebRowSet wrs1 = readWebRowSetWithOInputStreamWithReader(baos)) { - assertEquals(getPrimaryKeys(wrs1), COFFEES_PRIMARY_KEYS); - assertEquals(wrs1.size(), COFFEES_ROWS); + assertArrayEquals(COFFEES_PRIMARY_KEYS, getPrimaryKeys(wrs1)); + assertEquals(COFFEES_ROWS, wrs1.size()); } } @@ -217,14 +227,15 @@ public abstract class CommonWebRowSetTests extends CommonCachedRowSetTests { * back via readXML(Reader) and validate the primary keys * are the same */ - @Test(dataProvider = "rowsetUsingCoffees") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffees") public void WebRowSetTest0006(WebRowSet wrs) throws Exception { ResultSet rs = wrs; rs.beforeFirst(); ByteArrayOutputStream baos = writeWebRowSetWithOutputStreamWithWriter(rs); try (WebRowSet wrs1 = readWebRowSetWithOInputStreamWithReader(baos)) { - assertEquals(getPrimaryKeys(wrs1), COFFEES_PRIMARY_KEYS); - assertEquals(wrs1.size(), COFFEES_ROWS); + assertArrayEquals(COFFEES_PRIMARY_KEYS, getPrimaryKeys(wrs1)); + assertEquals(COFFEES_ROWS, wrs1.size()); } } @@ -232,11 +243,13 @@ public abstract class CommonWebRowSetTests extends CommonCachedRowSetTests { * Validate the expected Rows are contained within the RowSet * after deleting the specified rows */ - @Test(dataProvider = "rowsetUsingCoffees", enabled = false) + @Disabled + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowsetUsingCoffees") public void WebRowSetTest0007(WebRowSet wrs) throws Exception { - assertEquals(getPrimaryKeys(wrs), COFFEES_PRIMARY_KEYS); + assertArrayEquals(COFFEES_PRIMARY_KEYS, getPrimaryKeys(wrs)); int[] rowsToDelete = {2, 4}; - assertEquals(getPrimaryKeys(wrs), COFFEES_PRIMARY_KEYS); + assertArrayEquals(COFFEES_PRIMARY_KEYS, getPrimaryKeys(wrs)); for (int row : rowsToDelete) { assertTrue(deleteRowByPrimaryKey(wrs, row, 1)); } @@ -262,12 +275,13 @@ public abstract class CommonWebRowSetTests extends CommonCachedRowSetTests { * that was populated by reading an xml file with all rows * marked as a currentRow */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void WebRowSetTest0008(WebRowSet wrs1) throws Exception { FileInputStream fis = new FileInputStream(COFFEE_ROWS_XML); wrs1.readXml(fis); assertTrue(wrs1.size() == COFFEES_ROWS); - assertEquals(getPrimaryKeys(wrs1), COFFEES_PRIMARY_KEYS); + assertArrayEquals(COFFEES_PRIMARY_KEYS, getPrimaryKeys(wrs1)); // Validate that the rows are not marked as deleted, inserted or updated wrs1.beforeFirst(); while (wrs1.next()) { @@ -284,14 +298,15 @@ public abstract class CommonWebRowSetTests extends CommonCachedRowSetTests { * Also validate that they are or are not visible based on the * setShowDeleted value */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void WebRowSetTest0009(WebRowSet wrs1) throws Exception { int[] rowsToDelete = {2, 4}; Object[] expectedRows = {1, 3, 5}; FileInputStream fis = new FileInputStream(DELETED_COFFEE_ROWS_XML); wrs1.readXml(fis); assertTrue(wrs1.size() == COFFEES_ROWS); - assertEquals(getPrimaryKeys(wrs1), expectedRows); + assertArrayEquals(expectedRows, getPrimaryKeys(wrs1)); // With setShowDeleted(false) which is the default, // the deleted row should not be visible for (int row : rowsToDelete) { @@ -302,7 +317,7 @@ public abstract class CommonWebRowSetTests extends CommonCachedRowSetTests { for (int row : rowsToDelete) { assertTrue(findRowByPrimaryKey(wrs1, row, 1)); } - assertEquals(getPrimaryKeys(wrs1), COFFEES_PRIMARY_KEYS); + assertArrayEquals(COFFEES_PRIMARY_KEYS, getPrimaryKeys(wrs1)); wrs1.close(); } @@ -311,12 +326,13 @@ public abstract class CommonWebRowSetTests extends CommonCachedRowSetTests { * Validate that the correct row in the WebRowSet that had been created * from an xml file is marked as updated and contains the correct values */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void WebRowSetTest0010(WebRowSet wrs1) throws Exception { FileInputStream fis = new FileInputStream(UPDATED_COFFEE_ROWS_XML); wrs1.readXml(fis); assertTrue(wrs1.size() == COFFEES_ROWS); - assertEquals(getPrimaryKeys(wrs1), COFFEES_PRIMARY_KEYS); + assertArrayEquals(COFFEES_PRIMARY_KEYS, getPrimaryKeys(wrs1)); wrs1.beforeFirst(); while (wrs1.next()) { if (wrs1.getInt(1) == 3) { @@ -337,7 +353,8 @@ public abstract class CommonWebRowSetTests extends CommonCachedRowSetTests { * Validate the correct row is marked as inserted in a WebRowSet * that is read from an xml file */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void WebRowSetTest0011(WebRowSet wrs1) throws Exception { int expectedSize = COFFEES_ROWS + 2; int addedRowPK = 15; @@ -348,7 +365,10 @@ public abstract class CommonWebRowSetTests extends CommonCachedRowSetTests { FileInputStream fis = new FileInputStream(INSERTED_COFFEE_ROWS_XML); wrs1.readXml(fis); assertTrue(wrs1.size() == expectedSize); - assertEqualsNoOrder(getPrimaryKeys(wrs1), expected); + var actual = getPrimaryKeys(wrs1); + Arrays.sort(actual); + Arrays.sort(expected); + assertArrayEquals(expected, actual); wrs1.beforeFirst(); while (wrs1.next()) { if (wrs1.getInt(1) == 15 || wrs1.getInt(1) == 20) { @@ -367,7 +387,8 @@ public abstract class CommonWebRowSetTests extends CommonCachedRowSetTests { /* * Read an xml file which contains a row that was inserted and updated */ - @Test(dataProvider = "rowSetType") + @ParameterizedTest(autoCloseArguments = false) + @MethodSource("rowSetType") public void WebRowSetTest0012(WebRowSet wrs1) throws Exception { int expectedSize = COFFEES_ROWS + 1; int addedRowPK = 100; @@ -376,7 +397,7 @@ public abstract class CommonWebRowSetTests extends CommonCachedRowSetTests { FileInputStream fis = new FileInputStream(UPDATED_INSERTED_COFFEE_ROWS_XML); wrs1.readXml(fis); assertTrue(wrs1.size() == expectedSize); - assertEquals(getPrimaryKeys(wrs1), expected); + assertArrayEquals(expected, getPrimaryKeys(wrs1)); wrs1.beforeFirst(); while (wrs1.next()) { if (wrs1.getInt(1) == addedRowPK) { diff --git a/test/jdk/javax/sql/testng/test/rowset/webrowset/WebRowSetTests.java b/test/jdk/javax/sql/test/rowset/webrowset/WebRowSetTests.java similarity index 94% rename from test/jdk/javax/sql/testng/test/rowset/webrowset/WebRowSetTests.java rename to test/jdk/javax/sql/test/rowset/webrowset/WebRowSetTests.java index 5f2890e0b5b..4692c0cee84 100644 --- a/test/jdk/javax/sql/testng/test/rowset/webrowset/WebRowSetTests.java +++ b/test/jdk/javax/sql/test/rowset/webrowset/WebRowSetTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/javax/sql/testng/util/PropertyStubProvider.java b/test/jdk/javax/sql/util/PropertyStubProvider.java similarity index 92% rename from test/jdk/javax/sql/testng/util/PropertyStubProvider.java rename to test/jdk/javax/sql/util/PropertyStubProvider.java index d397cc1c7d4..1cadcef26bb 100644 --- a/test/jdk/javax/sql/testng/util/PropertyStubProvider.java +++ b/test/jdk/javax/sql/util/PropertyStubProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/javax/sql/testng/util/StubArray.java b/test/jdk/javax/sql/util/StubArray.java similarity index 97% rename from test/jdk/javax/sql/testng/util/StubArray.java rename to test/jdk/javax/sql/util/StubArray.java index 1d2ef0e5b6f..b57760679a0 100644 --- a/test/jdk/javax/sql/testng/util/StubArray.java +++ b/test/jdk/javax/sql/util/StubArray.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/javax/sql/testng/util/StubBaseRowSet.java b/test/jdk/javax/sql/util/StubBaseRowSet.java similarity index 99% rename from test/jdk/javax/sql/testng/util/StubBaseRowSet.java rename to test/jdk/javax/sql/util/StubBaseRowSet.java index e003b522ed9..94be7f8e348 100644 --- a/test/jdk/javax/sql/testng/util/StubBaseRowSet.java +++ b/test/jdk/javax/sql/util/StubBaseRowSet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/javax/sql/testng/util/StubBlob.java b/test/jdk/javax/sql/util/StubBlob.java similarity index 97% rename from test/jdk/javax/sql/testng/util/StubBlob.java rename to test/jdk/javax/sql/util/StubBlob.java index 727e8a926d5..f86fd540841 100644 --- a/test/jdk/javax/sql/testng/util/StubBlob.java +++ b/test/jdk/javax/sql/util/StubBlob.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/javax/sql/testng/util/StubCachedRowSetImpl.java b/test/jdk/javax/sql/util/StubCachedRowSetImpl.java similarity index 99% rename from test/jdk/javax/sql/testng/util/StubCachedRowSetImpl.java rename to test/jdk/javax/sql/util/StubCachedRowSetImpl.java index 9000deb1b65..65e8169dbb6 100644 --- a/test/jdk/javax/sql/testng/util/StubCachedRowSetImpl.java +++ b/test/jdk/javax/sql/util/StubCachedRowSetImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/javax/sql/testng/util/StubClob.java b/test/jdk/javax/sql/util/StubClob.java similarity index 97% rename from test/jdk/javax/sql/testng/util/StubClob.java rename to test/jdk/javax/sql/util/StubClob.java index cb1e0c0a62a..b0db14b3526 100644 --- a/test/jdk/javax/sql/testng/util/StubClob.java +++ b/test/jdk/javax/sql/util/StubClob.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/javax/sql/testng/util/StubContext.java b/test/jdk/javax/sql/util/StubContext.java similarity index 98% rename from test/jdk/javax/sql/testng/util/StubContext.java rename to test/jdk/javax/sql/util/StubContext.java index af03534d991..6f03a1abd48 100644 --- a/test/jdk/javax/sql/testng/util/StubContext.java +++ b/test/jdk/javax/sql/util/StubContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/javax/sql/testng/util/StubFilteredRowSetImpl.java b/test/jdk/javax/sql/util/StubFilteredRowSetImpl.java similarity index 99% rename from test/jdk/javax/sql/testng/util/StubFilteredRowSetImpl.java rename to test/jdk/javax/sql/util/StubFilteredRowSetImpl.java index 8fcbfa4c085..0b73abc6c01 100644 --- a/test/jdk/javax/sql/testng/util/StubFilteredRowSetImpl.java +++ b/test/jdk/javax/sql/util/StubFilteredRowSetImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/javax/sql/testng/util/StubJdbcRowSetImpl.java b/test/jdk/javax/sql/util/StubJdbcRowSetImpl.java similarity index 99% rename from test/jdk/javax/sql/testng/util/StubJdbcRowSetImpl.java rename to test/jdk/javax/sql/util/StubJdbcRowSetImpl.java index ec59eb6c556..441b662ddc6 100644 --- a/test/jdk/javax/sql/testng/util/StubJdbcRowSetImpl.java +++ b/test/jdk/javax/sql/util/StubJdbcRowSetImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/javax/sql/testng/util/StubJoinRowSetImpl.java b/test/jdk/javax/sql/util/StubJoinRowSetImpl.java similarity index 99% rename from test/jdk/javax/sql/testng/util/StubJoinRowSetImpl.java rename to test/jdk/javax/sql/util/StubJoinRowSetImpl.java index c7ece7cd523..1f506f830ef 100644 --- a/test/jdk/javax/sql/testng/util/StubJoinRowSetImpl.java +++ b/test/jdk/javax/sql/util/StubJoinRowSetImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/javax/sql/testng/util/StubNClob.java b/test/jdk/javax/sql/util/StubNClob.java similarity index 93% rename from test/jdk/javax/sql/testng/util/StubNClob.java rename to test/jdk/javax/sql/util/StubNClob.java index 10682578b9a..0664aa42795 100644 --- a/test/jdk/javax/sql/testng/util/StubNClob.java +++ b/test/jdk/javax/sql/util/StubNClob.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/javax/sql/testng/util/StubRef.java b/test/jdk/javax/sql/util/StubRef.java similarity index 95% rename from test/jdk/javax/sql/testng/util/StubRef.java rename to test/jdk/javax/sql/util/StubRef.java index 052bd92c740..54a42df1e1c 100644 --- a/test/jdk/javax/sql/testng/util/StubRef.java +++ b/test/jdk/javax/sql/util/StubRef.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/javax/sql/testng/util/StubRowId.java b/test/jdk/javax/sql/util/StubRowId.java similarity index 93% rename from test/jdk/javax/sql/testng/util/StubRowId.java rename to test/jdk/javax/sql/util/StubRowId.java index f8e90d49867..d3bc51b9320 100644 --- a/test/jdk/javax/sql/testng/util/StubRowId.java +++ b/test/jdk/javax/sql/util/StubRowId.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/javax/sql/testng/util/StubRowSetFactory.java b/test/jdk/javax/sql/util/StubRowSetFactory.java similarity index 96% rename from test/jdk/javax/sql/testng/util/StubRowSetFactory.java rename to test/jdk/javax/sql/util/StubRowSetFactory.java index 624c53af1e7..abc34894a18 100644 --- a/test/jdk/javax/sql/testng/util/StubRowSetFactory.java +++ b/test/jdk/javax/sql/util/StubRowSetFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/javax/sql/testng/util/StubSQLXML.java b/test/jdk/javax/sql/util/StubSQLXML.java similarity index 97% rename from test/jdk/javax/sql/testng/util/StubSQLXML.java rename to test/jdk/javax/sql/util/StubSQLXML.java index 44d1351b357..5e4d1647853 100644 --- a/test/jdk/javax/sql/testng/util/StubSQLXML.java +++ b/test/jdk/javax/sql/util/StubSQLXML.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/javax/sql/testng/util/StubStruct.java b/test/jdk/javax/sql/util/StubStruct.java similarity index 95% rename from test/jdk/javax/sql/testng/util/StubStruct.java rename to test/jdk/javax/sql/util/StubStruct.java index 1dee8028a2c..a5a2004a09d 100644 --- a/test/jdk/javax/sql/testng/util/StubStruct.java +++ b/test/jdk/javax/sql/util/StubStruct.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/javax/sql/testng/util/StubSyncProvider.java b/test/jdk/javax/sql/util/StubSyncProvider.java similarity index 97% rename from test/jdk/javax/sql/testng/util/StubSyncProvider.java rename to test/jdk/javax/sql/util/StubSyncProvider.java index 8947455c701..a6a44e0f509 100644 --- a/test/jdk/javax/sql/testng/util/StubSyncProvider.java +++ b/test/jdk/javax/sql/util/StubSyncProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/javax/sql/testng/util/StubSyncResolver.java b/test/jdk/javax/sql/util/StubSyncResolver.java similarity index 99% rename from test/jdk/javax/sql/testng/util/StubSyncResolver.java rename to test/jdk/javax/sql/util/StubSyncResolver.java index 02477c7f9be..f24c3ec4b13 100644 --- a/test/jdk/javax/sql/testng/util/StubSyncResolver.java +++ b/test/jdk/javax/sql/util/StubSyncResolver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/javax/sql/testng/util/StubWebRowSetImpl.java b/test/jdk/javax/sql/util/StubWebRowSetImpl.java similarity index 99% rename from test/jdk/javax/sql/testng/util/StubWebRowSetImpl.java rename to test/jdk/javax/sql/util/StubWebRowSetImpl.java index 918d5bd0482..48c237e73ae 100644 --- a/test/jdk/javax/sql/testng/util/StubWebRowSetImpl.java +++ b/test/jdk/javax/sql/util/StubWebRowSetImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/javax/sql/testng/util/SuperHero.java b/test/jdk/javax/sql/util/SuperHero.java similarity index 97% rename from test/jdk/javax/sql/testng/util/SuperHero.java rename to test/jdk/javax/sql/util/SuperHero.java index c8afb3831de..2d6e68a7c9e 100644 --- a/test/jdk/javax/sql/testng/util/SuperHero.java +++ b/test/jdk/javax/sql/util/SuperHero.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/javax/sql/testng/util/TestRowSetListener.java b/test/jdk/javax/sql/util/TestRowSetListener.java similarity index 96% rename from test/jdk/javax/sql/testng/util/TestRowSetListener.java rename to test/jdk/javax/sql/util/TestRowSetListener.java index 069ade29ca2..4f71f12da2e 100644 --- a/test/jdk/javax/sql/testng/util/TestRowSetListener.java +++ b/test/jdk/javax/sql/util/TestRowSetListener.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/javax/sql/testng/util/TestSQLDataImpl.java b/test/jdk/javax/sql/util/TestSQLDataImpl.java similarity index 98% rename from test/jdk/javax/sql/testng/util/TestSQLDataImpl.java rename to test/jdk/javax/sql/util/TestSQLDataImpl.java index 0694add3ef9..f02eeb6fece 100644 --- a/test/jdk/javax/sql/testng/util/TestSQLDataImpl.java +++ b/test/jdk/javax/sql/util/TestSQLDataImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/javax/sql/testng/xml/COFFEE_ROWS.xml b/test/jdk/javax/sql/xml/COFFEE_ROWS.xml similarity index 100% rename from test/jdk/javax/sql/testng/xml/COFFEE_ROWS.xml rename to test/jdk/javax/sql/xml/COFFEE_ROWS.xml diff --git a/test/jdk/javax/sql/testng/xml/DELETED_COFFEE_ROWS.xml b/test/jdk/javax/sql/xml/DELETED_COFFEE_ROWS.xml similarity index 100% rename from test/jdk/javax/sql/testng/xml/DELETED_COFFEE_ROWS.xml rename to test/jdk/javax/sql/xml/DELETED_COFFEE_ROWS.xml diff --git a/test/jdk/javax/sql/testng/xml/INSERTED_COFFEE_ROWS.xml b/test/jdk/javax/sql/xml/INSERTED_COFFEE_ROWS.xml similarity index 100% rename from test/jdk/javax/sql/testng/xml/INSERTED_COFFEE_ROWS.xml rename to test/jdk/javax/sql/xml/INSERTED_COFFEE_ROWS.xml diff --git a/test/jdk/javax/sql/testng/xml/MODFIED_DELETED_COFFEE_ROWS.xml b/test/jdk/javax/sql/xml/MODFIED_DELETED_COFFEE_ROWS.xml similarity index 100% rename from test/jdk/javax/sql/testng/xml/MODFIED_DELETED_COFFEE_ROWS.xml rename to test/jdk/javax/sql/xml/MODFIED_DELETED_COFFEE_ROWS.xml diff --git a/test/jdk/javax/sql/testng/xml/UPDATED_COFFEE_ROWS.xml b/test/jdk/javax/sql/xml/UPDATED_COFFEE_ROWS.xml similarity index 100% rename from test/jdk/javax/sql/testng/xml/UPDATED_COFFEE_ROWS.xml rename to test/jdk/javax/sql/xml/UPDATED_COFFEE_ROWS.xml diff --git a/test/jdk/javax/sql/testng/xml/UPDATED_INSERTED_COFFEE_ROWS.xml b/test/jdk/javax/sql/xml/UPDATED_INSERTED_COFFEE_ROWS.xml similarity index 100% rename from test/jdk/javax/sql/testng/xml/UPDATED_INSERTED_COFFEE_ROWS.xml rename to test/jdk/javax/sql/xml/UPDATED_INSERTED_COFFEE_ROWS.xml diff --git a/test/jdk/javax/swing/JFileChooser/4966171/bug4966171.java b/test/jdk/javax/swing/JFileChooser/4966171/bug4966171.java index f3b3ba684e6..27f26d570be 100644 --- a/test/jdk/javax/swing/JFileChooser/4966171/bug4966171.java +++ b/test/jdk/javax/swing/JFileChooser/4966171/bug4966171.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,8 +50,8 @@ public final class bug4966171 { } private static void test() { - // Will run the test no more than 10 seconds per L&F - long endtime = System.nanoTime() + TimeUnit.SECONDS.toNanos(10); + // Will run the test no more than 5 seconds per L&F + long endtime = System.nanoTime() + TimeUnit.SECONDS.toNanos(5); while (System.nanoTime() < endtime) { try { var byteOut = new ByteArrayOutputStream(); diff --git a/test/jdk/javax/swing/JMenuItem/LargeMenuTextArrowIconPosition.java b/test/jdk/javax/swing/JMenuItem/LargeMenuTextArrowIconPosition.java new file mode 100644 index 00000000000..72512560cff --- /dev/null +++ b/test/jdk/javax/swing/JMenuItem/LargeMenuTextArrowIconPosition.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8374506 + * @summary Verify if arrow icon positioning is correct in + * parent JMenu in Windows L&F + * @requires (os.family == "windows") + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual LargeMenuTextArrowIconPosition + */ + +import java.awt.BorderLayout; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.UIManager; + +public class LargeMenuTextArrowIconPosition { + + private static final String INSTRUCTIONS = """ + A frame will be shown with a label. + Right click on the label. + + Check the arrow icon at the end of + "Really long Menu-Text" text. + If it overlaps with the menu text, + press Fail else press Pass."""; + + public static void main(String[] args) throws Throwable { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + + PassFailJFrame.builder() + .instructions(INSTRUCTIONS) + .columns(40) + .testUI(LargeMenuTextArrowIconPosition::createTestUI) + .build() + .awaitAndCheck(); + } + + private static JFrame createTestUI() { + + JFrame frame = new JFrame("LargeMenuTextArrowIcon"); + frame.setSize(300, 150); + frame.setLayout(new BorderLayout()); + + JPopupMenu popupMenu = new JPopupMenu(); + popupMenu.add(new JCheckBoxMenuItem("CheckBox On", true)); + popupMenu.add(new JCheckBoxMenuItem("CheckBox Icon On", + UIManager.getIcon("FileView.floppyDriveIcon"), true)); + popupMenu.add(new JCheckBoxMenuItem("CheckBox Icon Off", + UIManager.getIcon("FileView.floppyDriveIcon"), false)); + + JMenu menu = new JMenu("Really long Menu-Text"); + menu.add(new JMenuItem("Sub-MenuItem")); + menu.add(new JCheckBoxMenuItem("Sub-CheckBox On", true)); + + popupMenu.add(menu); + + JLabel lbl = new JLabel("Right click to invoke popupMenu"); + lbl.setComponentPopupMenu(popupMenu); + frame.add(lbl, BorderLayout.CENTER); + + return frame; + } + +} diff --git a/test/jdk/javax/swing/JPopupMenu/6495920/bug6495920.java b/test/jdk/javax/swing/JPopupMenu/6495920/bug6495920.java index 6a8c132c4e4..cc37cb97b18 100644 --- a/test/jdk/javax/swing/JPopupMenu/6495920/bug6495920.java +++ b/test/jdk/javax/swing/JPopupMenu/6495920/bug6495920.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,12 +29,9 @@ interaction with GNOME is not crippled * @author Sergey Malenkov * @library ../.. - * @modules java.desktop/sun.awt * @modules java.desktop/javax.swing.plaf.basic:open */ -import sun.awt.AppContext; - import java.awt.Point; import java.awt.Robot; import java.awt.event.InputEvent; @@ -92,12 +89,12 @@ public class bug6495920 implements Thread.UncaughtExceptionHandler { } public void thirdValidate() throws Exception { - Field key = BasicPopupMenuUI.class.getDeclaredField("MOUSE_GRABBER_KEY"); + Field key = BasicPopupMenuUI.class.getDeclaredField("mouseGrabber"); key.setAccessible(true); - Object grabber = AppContext.getAppContext().get(key.get(null)); + Object grabber = key.get(null); if (grabber == null) { - throw new Exception("cannot find a mouse grabber in app's context"); + throw new Exception("cannot find a mouse grabber"); } Field field = grabber.getClass().getDeclaredField("grabbedWindow"); diff --git a/test/jdk/javax/swing/JPopupMenu/TestPopupInvoker.java b/test/jdk/javax/swing/JPopupMenu/TestPopupInvoker.java index c8ddfe67999..a3dc658df0e 100644 --- a/test/jdk/javax/swing/JPopupMenu/TestPopupInvoker.java +++ b/test/jdk/javax/swing/JPopupMenu/TestPopupInvoker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,13 +23,14 @@ /* * @test - * @bug 4938801 + * @bug 4938801 8376169 * @key headful * @summary Verifies popup is removed when the component is removed * @run main TestPopupInvoker */ import java.awt.BorderLayout; +import java.awt.Component; import java.awt.Container; import java.awt.Robot; import java.util.concurrent.CountDownLatch; @@ -48,6 +49,7 @@ public class TestPopupInvoker { static JFrame frame; static JLabel label; static Container pane; + static volatile Component invoker; private static final CountDownLatch popupShown = new CountDownLatch(1); private static final CountDownLatch popupHidden = new CountDownLatch(1); @@ -73,6 +75,7 @@ public class TestPopupInvoker { @Override public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { popupHidden.countDown(); + popupMenu.setInvoker(null); } @Override @@ -106,6 +109,11 @@ public class TestPopupInvoker { if (!popupHidden.await(1, SECONDS)) { throw new RuntimeException("Popup is visible after component is removed"); } + + SwingUtilities.invokeAndWait(() -> invoker = popupMenu.getInvoker()); + if (invoker != null) { + throw new RuntimeException("Invoker is not null"); + } } finally { SwingUtilities.invokeAndWait(() -> { if (frame != null) { diff --git a/test/jdk/javax/swing/JTable/TestJTableColWidth.java b/test/jdk/javax/swing/JTable/TestJTableColWidth.java new file mode 100644 index 00000000000..542c4d0ffa1 --- /dev/null +++ b/test/jdk/javax/swing/JTable/TestJTableColWidth.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8192888 + * @key headful + * @summary Verifies JTable doesn't ignore setPreferredWidth during + * initial layout when AUTO_RESIZE_LAST_COLUMN is enabled + * @run main TestJTableColWidth + */ + +import javax.swing.JFrame; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableColumnModel; +import javax.swing.SwingUtilities; + +public class TestJTableColWidth { + static JFrame frame; + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(() -> { + try { + frame = new JFrame("JTable colwidth"); + + String[] cols = {"ID", "Name", "Description", "Status"}; + Object[][] data = {{1, "Mimi", "Testing Java 25 Regression", "Pending"}}; + + DefaultTableModel model = new DefaultTableModel(data, cols); + final JTable tab = new JTable(model); + + tab.getTableHeader().setReorderingAllowed(false); + tab.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN); + + TableColumnModel columnModel = tab.getColumnModel(); + // Defined widths + int[] widths = {30, 200, 100, 50}; + + for (int i = 0; i < widths.length; i++) { + columnModel.getColumn(i).setPreferredWidth(widths[i]); + } + + frame.add(new JScrollPane(tab)); + frame.setSize(600, 200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + + System.out.println("Actual column widths on screen:"); + for (int i = 0; i < columnModel.getColumnCount(); i++) { + System.out.println("Column " + i + ": " + + columnModel.getColumn(i).getWidth() + "px"); + } + if (columnModel.getColumn(0).getWidth() + == columnModel.getColumn(1).getWidth()) { + throw new RuntimeException("JTable ignores setPreferredWidth during" + + " initial layout when AUTO_RESIZE_LAST_COLUMN is enabled"); + } + } finally { + if (frame != null) { + frame.dispose(); + } + } + }); + } +} diff --git a/test/jdk/javax/swing/Security/6938813/bug6938813.java b/test/jdk/javax/swing/Security/6938813/bug6938813.java deleted file mode 100644 index 8f5e3fc3505..00000000000 --- a/test/jdk/javax/swing/Security/6938813/bug6938813.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @key headful - * @bug 6938813 - * @summary Swing mutable statics - * @author Pavel Porvatov - * @modules java.desktop/javax.swing.text.html.parser:open - * @modules java.desktop/sun.awt - */ - -import sun.awt.AppContext; -import sun.awt.SunToolkit; - -import javax.swing.text.html.HTMLEditorKit; -import javax.swing.text.html.StyleSheet; -import javax.swing.text.html.parser.DTD; -import javax.swing.text.html.parser.ParserDelegator; -import java.lang.reflect.Field; - -public class bug6938813 { - public static final String DTD_KEY = "dtd_key"; - - private static volatile StyleSheet styleSheet; - - public static void main(String[] args) throws Exception { - // Run validation and init values for this AppContext - validate(); - - Thread thread = new ThreadInAnotherAppContext(); - - thread.start(); - thread.join(); - } - - private static void validate() throws Exception { - AppContext appContext = AppContext.getAppContext(); - - assertTrue(DTD.getDTD(DTD_KEY).getName().equals(DTD_KEY), "DTD.getDTD() mixed AppContexts"); - - // Spoil hash value - DTD invalidDtd = DTD.getDTD("invalid DTD"); - - DTD.putDTDHash(DTD_KEY, invalidDtd); - - assertTrue(DTD.getDTD(DTD_KEY) == invalidDtd, "Something wrong with DTD.getDTD()"); - - Object dtdKey = getParserDelegator_DTD_KEY(); - - assertTrue(appContext.get(dtdKey) == null, "ParserDelegator mixed AppContexts"); - - // Init default DTD - new ParserDelegator(); - - Object dtdValue = appContext.get(dtdKey); - - assertTrue(dtdValue != null, "ParserDelegator.defaultDTD isn't initialized"); - - // Try reinit default DTD - new ParserDelegator(); - - assertTrue(dtdValue == appContext.get(dtdKey), "ParserDelegator.defaultDTD created a duplicate"); - - HTMLEditorKit htmlEditorKit = new HTMLEditorKit(); - - if (styleSheet == null) { - // First AppContext - styleSheet = htmlEditorKit.getStyleSheet(); - - assertTrue(styleSheet != null, "htmlEditorKit.getStyleSheet() returns null"); - assertTrue(htmlEditorKit.getStyleSheet() == styleSheet, "Something wrong with htmlEditorKit.getStyleSheet()"); - } else { - assertTrue(htmlEditorKit.getStyleSheet() != styleSheet, "HtmlEditorKit.getStyleSheet() mixed AppContexts"); - } - } - - private static void assertTrue(boolean b, String msg) { - if (!b) { - throw new RuntimeException("Test failed: " + msg); - } - } - - private static Object getParserDelegator_DTD_KEY() throws Exception { - Field field = ParserDelegator.class.getDeclaredField("DTD_KEY"); - - field.setAccessible(true); - - return field.get(null); - } - - private static class ThreadInAnotherAppContext extends Thread { - public ThreadInAnotherAppContext() { - super(new ThreadGroup("6938813"), "ThreadInAnotherAppContext"); - } - - public void run() { - SunToolkit.createNewAppContext(); - - try { - validate(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - } -} diff --git a/test/jdk/javax/swing/UIManager/Test6657026.java b/test/jdk/javax/swing/UIManager/Test6657026.java deleted file mode 100644 index 5ce1ea73de4..00000000000 --- a/test/jdk/javax/swing/UIManager/Test6657026.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 6657026 - * @summary Tests shared UIManager in different application contexts - * @author Sergey Malenkov - * @modules java.desktop/sun.awt - */ - -import sun.awt.SunToolkit; - -import javax.swing.UIManager; -import javax.swing.UIManager.LookAndFeelInfo; - -public class Test6657026 implements Runnable { - - public static void main(String[] args) throws Exception { - if (UIManager.getInstalledLookAndFeels().length == 0) { - throw new Error("unexpected amount of look&feels"); - } - UIManager.setInstalledLookAndFeels(new LookAndFeelInfo[0]); - if (UIManager.getInstalledLookAndFeels().length != 0) { - throw new Error("unexpected amount of look&feels"); - } - - ThreadGroup group = new ThreadGroup("$$$"); - Thread thread = new Thread(group, new Test6657026()); - thread.start(); - thread.join(); - } - - public void run() { - SunToolkit.createNewAppContext(); - if (UIManager.getInstalledLookAndFeels().length == 0) { - throw new Error("shared look&feels"); - } - } -} diff --git a/test/jdk/javax/swing/plaf/metal/MetalUtils/bug6190373.java b/test/jdk/javax/swing/plaf/metal/MetalUtils/bug6190373.java deleted file mode 100644 index 07211c7a569..00000000000 --- a/test/jdk/javax/swing/plaf/metal/MetalUtils/bug6190373.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.awt.Graphics; -import java.awt.image.BufferedImage; -import java.util.concurrent.CyclicBarrier; - -import javax.swing.JButton; -import javax.swing.SwingUtilities; -import javax.swing.UIManager; -import javax.swing.UnsupportedLookAndFeelException; - -import sun.awt.AppContext; -import sun.awt.SunToolkit; - -import static javax.swing.UIManager.getInstalledLookAndFeels; - -/** - * @test - * @bug 6190373 - * @summary Tests 6190373 - * @author Scott Violet - * @modules java.desktop/sun.awt - */ -public final class bug6190373 { - - private static AppContext app1; - private static AppContext app2; - private static final int LOOP_COUNT = 10000; - private static final CyclicBarrier barrier = new CyclicBarrier(2); - - public static void main(final String[] args) throws Exception { - final Thread t1 = new Thread(new ThreadGroup("firstGroup"), () -> { - app1 = SunToolkit.createNewAppContext(); - test(true); - }); - final Thread t2 = new Thread(new ThreadGroup("secondGroup"), () -> { - app2 = SunToolkit.createNewAppContext(); - test(false); - }); - - t1.start(); - t2.start(); - t1.join(); - t2.join(); - app1.dispose(); - app2.dispose(); - } - - private static void test(final boolean lock) { - for (final UIManager.LookAndFeelInfo laf : getInstalledLookAndFeels()) { - try { - SwingUtilities.invokeAndWait(() -> setLookAndFeel(laf)); - barrier.await(); - SwingUtilities.invokeAndWait(() -> slam(lock)); - barrier.await(); - } catch (final Exception e) { - throw new RuntimeException(e); - } - } - } - - private static void slam(final boolean lock) { - JButton button = new JButton("HI"); - button.setSize(100, 100); - BufferedImage image = new BufferedImage(100, 100, - BufferedImage.TYPE_INT_RGB); - for (int i = 0; i < LOOP_COUNT; i++) { - Graphics g = image.getGraphics(); - if (lock) { - synchronized (button.getTreeLock()) { - button.paint(g); - } - } else { - button.paint(g); - } - g.dispose(); - } - } - - private static void setLookAndFeel(final UIManager.LookAndFeelInfo laf) { - try { - UIManager.setLookAndFeel(laf.getClassName()); - System.out.println("LookAndFeel: " + laf.getClassName()); - } catch (final UnsupportedLookAndFeelException ignored){ - System.out.println("Unsupported LookAndFeel: " + laf.getClassName()); - } catch (ClassNotFoundException | InstantiationException | - IllegalAccessException e) { - throw new RuntimeException(e); - } - } -} diff --git a/test/jdk/javax/swing/plaf/synth/7143614/bug7143614.java b/test/jdk/javax/swing/plaf/synth/7143614/bug7143614.java deleted file mode 100644 index f1e1cbb94aa..00000000000 --- a/test/jdk/javax/swing/plaf/synth/7143614/bug7143614.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 7143614 - * @summary Issues with Synth Look&Feel - * @author Pavel Porvatov - * @modules java.desktop/javax.swing.plaf.synth:open - * @modules java.desktop/sun.awt - */ - -import sun.awt.SunToolkit; - -import javax.swing.plaf.ComponentUI; -import javax.swing.plaf.basic.BasicButtonUI; -import javax.swing.plaf.synth.SynthConstants; -import javax.swing.plaf.synth.SynthLookAndFeel; -import java.lang.reflect.Method; - -public class bug7143614 { - private static Method setSelectedUIMethod; - - private static ComponentUI componentUI = new BasicButtonUI(); - - public static void main(String[] args) throws Exception { - setSelectedUIMethod = SynthLookAndFeel.class.getDeclaredMethod("setSelectedUI", ComponentUI.class, - boolean.class, boolean.class, boolean.class, boolean.class); - setSelectedUIMethod.setAccessible(true); - - setSelectedUIMethod.invoke(null, componentUI, true, true, true, true); - - validate(); - - Thread thread = new ThreadInAnotherAppContext(); - - thread.start(); - thread.join(); - - validate(); - - System.out.println("Test bug7143614 passed."); - } - - private static void validate() throws Exception { - Method getSelectedUIMethod = SynthLookAndFeel.class.getDeclaredMethod("getSelectedUI"); - - getSelectedUIMethod.setAccessible(true); - - Method getSelectedUIStateMethod = SynthLookAndFeel.class.getDeclaredMethod("getSelectedUIState"); - - getSelectedUIStateMethod.setAccessible(true); - - if (getSelectedUIMethod.invoke(null) != componentUI) { - throw new RuntimeException("getSelectedUI returns invalid value"); - } - if (((Integer) getSelectedUIStateMethod.invoke(null)).intValue() != - (SynthConstants.SELECTED | SynthConstants.FOCUSED)) { - throw new RuntimeException("getSelectedUIState returns invalid value"); - } - - } - - private static class ThreadInAnotherAppContext extends Thread { - public ThreadInAnotherAppContext() { - super(new ThreadGroup("7143614"), "ThreadInAnotherAppContext"); - } - - public void run() { - SunToolkit.createNewAppContext(); - - try { - setSelectedUIMethod.invoke(null, null, false, false, false, false); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - } -} diff --git a/test/jdk/javax/swing/plaf/synth/Test6660049.java b/test/jdk/javax/swing/plaf/synth/Test6660049.java deleted file mode 100644 index a7486eb86c8..00000000000 --- a/test/jdk/javax/swing/plaf/synth/Test6660049.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @key headful - * @bug 6660049 6849518 - * @summary Tests the Region initialization - * @author Sergey Malenkov - * @modules java.desktop/sun.awt - */ - -import sun.awt.SunToolkit; - -import javax.swing.JButton; -import javax.swing.JComponent; -import javax.swing.SwingUtilities; -import javax.swing.plaf.synth.Region; -import javax.swing.plaf.synth.SynthLookAndFeel; - -public class Test6660049 implements Runnable { - public static void main(String[] args) { - SwingUtilities.invokeLater(new Test6660049( - javax.swing.JButton.class, - javax.swing.JCheckBox.class, - javax.swing.JCheckBoxMenuItem.class, - javax.swing.JColorChooser.class, - javax.swing.JComboBox.class, - javax.swing.JDesktopPane.class, - javax.swing.JEditorPane.class, - javax.swing.JFileChooser.class, - javax.swing.JFormattedTextField.class, - javax.swing.JInternalFrame.class, - javax.swing.JLabel.class, - javax.swing.JList.class, - javax.swing.JMenu.class, - javax.swing.JMenuBar.class, - javax.swing.JMenuItem.class, - javax.swing.JOptionPane.class, - javax.swing.JPanel.class, - javax.swing.JPasswordField.class, - javax.swing.JPopupMenu.class, - javax.swing.JProgressBar.class, - javax.swing.JRadioButton.class, - javax.swing.JRadioButtonMenuItem.class, - javax.swing.JRootPane.class, - javax.swing.JScrollBar.class, - javax.swing.JScrollPane.class, - javax.swing.JSeparator.class, - javax.swing.JSlider.class, - javax.swing.JSpinner.class, - javax.swing.JSplitPane.class, - javax.swing.JTabbedPane.class, - javax.swing.JTable.class, - javax.swing.JTextArea.class, - javax.swing.JTextField.class, - javax.swing.JTextPane.class, - javax.swing.JToggleButton.class, - javax.swing.JToolBar.class, - javax.swing.JToolTip.class, - javax.swing.JTree.class, - javax.swing.JViewport.class, - javax.swing.table.JTableHeader.class)); - } - - private final Class[] types; - private final Region region; - - private Test6660049(Class... types) { - this.types = types; - run(); - - this.region = new Region("Button", "ButtonUI", true) { - @Override - public String getName() { - throw new Error("6660049: exploit is available"); - } - }; - } - - public void run() { - if (this.region != null) { - SunToolkit.createNewAppContext(); - } - for (Class type : this.types) { - Region region = getRegion(type); - if (region == null) { - throw new Error("6849518: region is not initialized"); - } - } - getRegion(JButton.class).getName(); - } - - private static Region getRegion(Class type) { - try { - return SynthLookAndFeel.getRegion(type.newInstance()); - } - catch (IllegalAccessException exception) { - throw new Error("unexpected exception", exception); - } - catch (InstantiationException exception) { - throw new Error("unexpected exception", exception); - } - } -} diff --git a/test/jdk/javax/swing/text/LayoutQueue/Test6588003.java b/test/jdk/javax/swing/text/LayoutQueue/Test6588003.java deleted file mode 100644 index 561ac594a47..00000000000 --- a/test/jdk/javax/swing/text/LayoutQueue/Test6588003.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* @test - @bug 6588003 - @summary LayoutQueue should not share its DefaultQueue across AppContexts - @author Peter Zhelezniakov - @modules java.desktop/sun.awt - @run main Test6588003 -*/ - -import javax.swing.text.LayoutQueue; -import sun.awt.SunToolkit; - -public class Test6588003 implements Runnable { - private static final LayoutQueue DEFAULT = new LayoutQueue(); - - public static void main(String[] args) throws InterruptedException { - LayoutQueue.setDefaultQueue(DEFAULT); - - ThreadGroup group = new ThreadGroup("Test6588003"); - Thread thread = new Thread(group, new Test6588003()); - thread.start(); - thread.join(); - - if (LayoutQueue.getDefaultQueue() != DEFAULT) { - throw new RuntimeException("Sharing detected"); - } - } - - public void run() { - SunToolkit.createNewAppContext(); - - if (LayoutQueue.getDefaultQueue() == DEFAULT) { - throw new RuntimeException("Sharing detected"); - } - - LayoutQueue.setDefaultQueue(new LayoutQueue()); - } -} diff --git a/test/jdk/javax/swing/text/html/parser/Test8017492.java b/test/jdk/javax/swing/text/html/parser/Test8017492.java deleted file mode 100644 index dbc1e125cf7..00000000000 --- a/test/jdk/javax/swing/text/html/parser/Test8017492.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.util.Vector; -import javax.swing.text.html.HTML; -import javax.swing.text.html.HTMLDocument; -import javax.swing.text.html.HTMLEditorKit; -import javax.swing.text.html.parser.DTD; -import javax.swing.text.html.parser.Element; -import sun.awt.SunToolkit; - -/* - * @test - * @bug 8017492 - * @modules java.desktop/sun.awt - * @run main/othervm Test8017492 - * @summary Tests for OutOfMemoryError/NegativeArraySizeException - * @author Sergey Malenkov - */ - -public class Test8017492 { - public static void main(String[] args) throws Exception { - Runnable task = new Runnable() { - @Override - public void run() { - try { - SunToolkit.createNewAppContext(); - DTD dtd = DTD.getDTD("dtd"); - dtd.elements = new Vector() { - @Override - public synchronized int size() { - return Integer.MAX_VALUE; - } - }; - dtd.getElement("element"); - } - catch (Exception exception) { - throw new Error("unexpected", exception); - } - } - }; - // run task with different AppContext - Thread thread = new Thread(new ThreadGroup("$$$"), task); - thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { - @Override - public void uncaughtException(Thread thread, Throwable throwable) { - throwable.printStackTrace(); - throw new RuntimeException(throwable); - } - }); - thread.start(); - thread.join(); - // add error handling - SunToolkit.createNewAppContext(); - HTMLDocument document = new HTMLDocument() { - @Override - public HTMLEditorKit.ParserCallback getReader(int pos) { - return getReader(pos, 0, 0, null); - } - - @Override - public HTMLEditorKit.ParserCallback getReader(int pos, int popDepth, int pushDepth, HTML.Tag insertTag) { - return new HTMLDocument.HTMLReader(pos, popDepth, pushDepth, insertTag) { - @Override - public void handleError(String error, int pos) { - throw new Error(error); - } - }; - } - }; - // run parser - new HTMLEditorKit().insertHTML(document, 0, "text", 0, 0, null); - } -} diff --git a/test/jdk/jdk/internal/loader/URLClassPath/JarManifestClassPathOrder.java b/test/jdk/jdk/internal/loader/URLClassPath/JarManifestClassPathOrder.java new file mode 100644 index 00000000000..c1cda1d448a --- /dev/null +++ b/test/jdk/jdk/internal/loader/URLClassPath/JarManifestClassPathOrder.java @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; +import java.util.jar.Attributes; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; +import java.util.stream.Collectors; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/* + * @test + * @summary Verify that URLClassPath discovers JAR Class-Path URLs in the expected order + * @run junit JarManifestClassPathOrder + */ +public class JarManifestClassPathOrder { + + // Name of the JAR resource use for lookups + private static final String ENTRY_NAME = "JarClassPathOrdering.txt"; + + /** + * Verify that URLClassPath discovers JAR files in the expected order when + * only root JARs are on the 'original' class path and the other JARs are + * found via multiple levels of Class-Path Manifest attributes. + * + * @throws IOException if an unexpected error occurs + */ + @Test + public void shouldLoadJARsInExpectedOrder() throws IOException { + + // Set up a 'Class-Path' JAR tree of depth 3 + JarTree specs = new JarTree(); + specs.addJars(3); + + // List of "root" JAR file URLs to use for URLClassLoader + List searchPath = new ArrayList<>(); + + // Order of JAR files we expect URLClassPath to find after a DFS search + List expectedJarNames = new ArrayList<>(); + + for (JarSpec spec : specs.dfs) { + Path jar = createJar(spec); + expectedJarNames.add(jar.getFileName().toString()); + // Only root JARs in the search path, others are discovered transitively via "Class-Path" + if (spec.isRoot()) { + searchPath.add(jar.toUri().toURL()); + } + } + + // Load ENTRY_NAME to identify all JARs found by URLClassPath + try (URLClassLoader loader = new URLClassLoader(searchPath.toArray(new URL[0]))) { + Enumeration resources = loader.getResources(ENTRY_NAME); + // Collect all JAR file names in the order discovered by URLClassPath + List actualJarNames = Collections.list(resources) + .stream() + .map(this::extractJarName) + .collect(Collectors.toList()); + // JARs should be found in DFS order + assertEquals(expectedJarNames, actualJarNames, "JAR files not found in expected order"); + } + } + + // Extract file name of JAR file from a JAR URL + private String extractJarName(URL url) { + String jarPath = url.getPath().substring(0, url.getPath().indexOf("!/")); + String jarName = jarPath.substring(jarPath.lastIndexOf('/') + 1); + return jarName; + } + + // Create a JAR file according to the spec, possibly including a Class-Path attribute + private Path createJar(JarSpec spec) throws IOException { + Path file = Path.of(spec.name +".jar"); + Manifest man = new Manifest(); + Attributes attrs = man.getMainAttributes(); + attrs.put(Attributes.Name.MANIFEST_VERSION, "1.0"); + + // Set Class-Path attribute + if (!spec.children.isEmpty()) { + String path = String.join(" ", spec.children + .stream() + .map(js -> js.name +".jar") + .collect(Collectors.toList())); + attrs.put(Attributes.Name.CLASS_PATH, path); + } + + try (JarOutputStream out = new JarOutputStream(Files.newOutputStream(file), man)) { + // All JARs include the same entry + out.putNextEntry(new JarEntry(ENTRY_NAME)); + } + + return file; + } + + + // Helper class to represent a tree of JARs related by "Class-Path" + static class JarTree { + static final List NAMES = List.of("a", "b", "c"); + List dfs = new ArrayList<>(); + + private void addJar(String prefix, String name, JarSpec parent, int depth, int maxDepth) { + if (depth > maxDepth) { + return; + } + JarSpec spec = new JarSpec(prefix + name, parent); + dfs.add(spec); + + if (parent != null) { + parent.children.add(spec); + } + + for (String childName : NAMES) { + addJar(prefix + name, childName, spec, depth + 1, maxDepth); + } + } + + /* Make a tree of JARs related by the 'Class-Path' Manifest attribute: + * a.jar + * aa.jar + * aaa.jar + * aab.jar + * [...] + * ccc.jar + */ + public void addJars(int maxDepth) { + for (String name : NAMES) { + addJar("", name, null, 1, maxDepth); + } + } + } + + // Helper class to represent a JAR file to be found by URLClassPath + static class JarSpec { + final String name; + final JarSpec parent; + final List children = new ArrayList<>(); + + JarSpec(String name, JarSpec parent) { + this.name = name; + this.parent = parent; + } + boolean isRoot() { + return parent == null; + } + } +} diff --git a/test/jdk/jdk/internal/platform/docker/TestDockerMemoryMetricsSubgroup.java b/test/jdk/jdk/internal/platform/docker/TestDockerMemoryMetricsSubgroup.java index 7d5dbca6f7c..4b487934169 100644 --- a/test/jdk/jdk/internal/platform/docker/TestDockerMemoryMetricsSubgroup.java +++ b/test/jdk/jdk/internal/platform/docker/TestDockerMemoryMetricsSubgroup.java @@ -91,7 +91,8 @@ public class TestDockerMemoryMetricsSubgroup { .addDockerOpts("--volume", Utils.TEST_JDK + ":/jdk") .addDockerOpts("--privileged") .addDockerOpts("--cgroupns=" + (privateNamespace ? "private" : "host")) - .addDockerOpts("--memory", outerGroupMemorySize); + .addDockerOpts("--memory", outerGroupMemorySize) + .addDockerOpts("-e", "LANG=C.UTF-8"); opts.addClassOptions("mkdir -p /sys/fs/cgroup/memory/test ; " + "echo " + innerSize + " > /sys/fs/cgroup/memory/test/memory.limit_in_bytes ; " + "echo $$ > /sys/fs/cgroup/memory/test/cgroup.procs ; " + @@ -112,6 +113,7 @@ public class TestDockerMemoryMetricsSubgroup { .addDockerOpts("--volume", Utils.TEST_JDK + ":/jdk") .addDockerOpts("--privileged") .addDockerOpts("--cgroupns=" + (privateNamespace ? "private" : "host")) + .addDockerOpts("-e", "LANG=C.UTF-8") .addDockerOpts("--memory", outerGroupMemorySize); opts.addClassOptions("mkdir -p /sys/fs/cgroup/memory/test ; " + "echo $$ > /sys/fs/cgroup/memory/test/cgroup.procs ; " + diff --git a/test/jdk/jdk/internal/vm/ThreadSnapshot/ThreadNotAlive.java b/test/jdk/jdk/internal/vm/ThreadSnapshot/ThreadNotAlive.java new file mode 100644 index 00000000000..6b9905e2fa4 --- /dev/null +++ b/test/jdk/jdk/internal/vm/ThreadSnapshot/ThreadNotAlive.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @summary Test jdk.internal.vm.ThreadSnapshot.of(Thread) when thread is not alive + * @modules java.base/jdk.internal.vm + * @compile/module=java.base jdk/internal/vm/Helper.java + * @run junit ThreadNotAlive + */ + +import jdk.internal.vm.Helper; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +class ThreadNotAlive { + + @Test + void unstartedPlatformThread() { + Thread t = Thread.ofPlatform().unstarted(() -> { }); + assertFalse(Helper.isAlive(t)); + } + + @Test + void terminatedPlatformThread() throws InterruptedException { + Thread t = Thread.ofPlatform().start(() -> { }); + t.join(); + assertFalse(Helper.isAlive(t)); + } + + @Test + void unstartedVirtualhread() { + Thread t = Thread.ofVirtual().unstarted(() -> { }); + assertFalse(Helper.isAlive(t)); + } + + @Test + void terminatedVirtualThread() throws InterruptedException { + Thread t = Thread.ofVirtual().start(() -> { }); + t.join(); + assertFalse(Helper.isAlive(t)); + } + +} diff --git a/test/jdk/javax/sql/rowset/serial/SerialBlob/SetBinaryStream.java b/test/jdk/jdk/internal/vm/ThreadSnapshot/java.base/jdk/internal/vm/Helper.java similarity index 63% rename from test/jdk/javax/sql/rowset/serial/SerialBlob/SetBinaryStream.java rename to test/jdk/jdk/internal/vm/ThreadSnapshot/java.base/jdk/internal/vm/Helper.java index a2d7ea2f8cb..99be9d2241a 100644 --- a/test/jdk/javax/sql/rowset/serial/SerialBlob/SetBinaryStream.java +++ b/test/jdk/jdk/internal/vm/ThreadSnapshot/java.base/jdk/internal/vm/Helper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,23 +20,19 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -import javax.sql.rowset.serial.SerialBlob; -import javax.sql.rowset.serial.SerialException; + +package jdk.internal.vm; /** - * @test - * @bug 7077451 - * @summary tests if the correct exception is thrown when calling method setBinaryStream() on SerialBlob + * Defines methods that use package-private methods on ThreadSnapshot. */ -public class SetBinaryStream { +public class Helper { - public static void main(String[] args) throws Exception { - SerialBlob blob = new SerialBlob(new byte[0]); - try { - blob.setBinaryStream(0); - } catch (SerialException e) { - System.out.println("Test PASSED"); - } + /** + * Uses ThreadSnapshot.of(Thread) to take a snapshot of the given thread, returning + * {@code true} if the thread is alive. + */ + public static boolean isAlive(Thread thread) { + return ThreadSnapshot.of(thread) != null; } - } diff --git a/test/jdk/sun/awt/image/ImageRepresentation/LUTCompareTest.java b/test/jdk/sun/awt/image/ImageRepresentation/LUTCompareTest.java index aca2ff1071c..498fe227651 100644 --- a/test/jdk/sun/awt/image/ImageRepresentation/LUTCompareTest.java +++ b/test/jdk/sun/awt/image/ImageRepresentation/LUTCompareTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,12 +23,13 @@ /* * @test - * @bug 6570475 + * @bug 6570475 8375338 * @summary Test verifies that palette comparison procedure of * ImageRepresentation class does not produce extra transparent * pixels. * - * @run main LUTCompareTest + * @run main/othervm LUTCompareTest + * @run main/othervm -Xcheck:jni LUTCompareTest */ diff --git a/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/GetServerCertificates.java b/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/GetServerCertificates.java new file mode 100644 index 00000000000..5de0d7aeb1a --- /dev/null +++ b/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/GetServerCertificates.java @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + * @test + * @bug 8376031 + * @modules jdk.httpserver + * @library /test/lib + * @summary Ensure HttpsURLConnection::getServerCertificates does not + * throw after calling getResponseCode() if the response doesn't have + * a body. + * @run main/othervm ${test.main.class} + * @run main/othervm -Djava.net.preferIPv6Addresses=true ${test.main.class} + */ + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; + +import com.sun.net.httpserver.HttpsConfigurator; +import com.sun.net.httpserver.HttpsServer; +import jdk.test.lib.net.SimpleSSLContext; +import jdk.test.lib.net.URIBuilder; + +import static com.sun.net.httpserver.HttpExchange.RSPBODY_EMPTY; + + +public class GetServerCertificates { + + static final String URI_PATH = "/GetServerCertificates/"; + static final String BODY = "Go raibh maith agat"; + enum TESTS { + HEAD("head", 200, "HEAD"), + NOBODY("nobody", 200, "GET", "POST"), + S204("204", 204, "GET", "POST"), + S304("304", 304, "GET", "POST"), + S200("200", 200, "GET", "POST"); + final String test; + final int code; + final List methods; + private TESTS(String test, int code, String... methods) { + this.test = test; + this.code = code; + this.methods = List.of(methods); + } + boolean isFor(String path) { + return path != null && path.endsWith("/" + test); + } + + String test() { return test; } + int code() { return code; } + List methods() { return methods; } + static Optional fromPath(String path) { + return Stream.of(values()) + .filter(test -> test.isFor(path)) + .findFirst(); + } + } + + void test(String[] args) throws Exception { + SSLContext.setDefault(SimpleSSLContext.findSSLContext()); + HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + return true; + } + }); + HttpServer server = startHttpServer(); + try { + InetSocketAddress address = server.getAddress(); + URI uri = URIBuilder.newBuilder() + .scheme("https") + .host(address.getAddress()) + .port(address.getPort()) + .path(URI_PATH) + .build(); + for (var test : TESTS.values()) { + for (String method : test.methods()) { + doClient(method, uri, test); + } + } + + } finally { + server.stop(1000); + } + } + + void doClient(String method, URI baseUri, TESTS test) throws Exception { + assert baseUri.getRawQuery() == null; + assert baseUri.getRawFragment() == null; + assert test.methods().contains(method); + + String uriStr = baseUri.toString(); + if (!uriStr.endsWith("/")) uriStr = uriStr + "/"; + + URI uri = new URI(uriStr + test.test()); + assert uri.toString().endsWith("/" + test.test()); + int code = test.code(); + System.out.println("doClient(%s, %s, %s)" + .formatted(method, test.test(), test.code)); + + // first request - should create a TCP connection + HttpsURLConnection uc = (HttpsURLConnection) + uri.toURL().openConnection(Proxy.NO_PROXY); + if (!"GET".equals(method)) { + uc.setRequestMethod(method); + } + try { + uc.getServerCertificates(); + throw new AssertionError("Expected IllegalStateException not thrown"); + } catch (IllegalStateException ise) { + System.out.println("Got expected ISE: " + ise); + } + int resp = uc.getResponseCode(); + check(resp == code, "Unexpected response code. Expected %s, got %s" + .formatted(code, resp)); + + check(uc.getServerCertificates()); + if (test == TESTS.S200) { + byte[] bytes = uc.getInputStream().readAllBytes(); + String body = new String(bytes, StandardCharsets.UTF_8); + System.out.println("body: " + body); + check(BODY.equals(body), "Unexpected response body. Expected \"%s\", got \"%s\"" + .formatted(BODY, body)); + } + + // second request - should go on the same TCP connection. + // We don't have a reliable way to test that, and it could + // go on a new TCP connection if the previous connection + // was already closed. It is not an issue either way. + uc = (HttpsURLConnection) + uri.toURL().openConnection(Proxy.NO_PROXY); + if (!"GET".equals(method)) { + uc.setRequestMethod(method); + } + try { + uc.getServerCertificates(); + throw new AssertionError("Expected IllegalStateException not thrown"); + } catch (IllegalStateException ise) { + System.out.println("Got expected ISE: " + ise); + } + resp = uc.getResponseCode(); + check(resp == code, "Unexpected response code. Expected %s, got %s" + .formatted(code, resp)); + + check(uc.getServerCertificates()); + if (test == TESTS.S200) { + byte[] bytes = uc.getInputStream().readAllBytes(); + String body = new String(bytes, StandardCharsets.UTF_8); + System.out.println("body: " + body); + check(BODY.equals(body), "Unexpected response body. Expected \"%s\", got \"%s\"" + .formatted(BODY, body)); + } + + uc.disconnect(); + try { + uc.getServerCertificates(); + throw new AssertionError("Expected IllegalStateException not thrown"); + } catch (IllegalStateException ise) { + System.out.println("Got expected ISE: " + ise); + } + + // third request - forces the connection to close + // after use so that we don't find any connection in the pool + // for the next test case, assuming there was only + // one connection in the first place. + // Again there's no easy way to verify that the pool + // is empty (and it's not really necessary to bother) + uc = (HttpsURLConnection) + uri.toURL().openConnection(Proxy.NO_PROXY); + if (!"GET".equals(method)) { + uc.setRequestMethod(method); + } + uc.setRequestProperty("Connection", "close"); + try { + uc.getServerCertificates(); + throw new AssertionError("Expected IllegalStateException not thrown"); + } catch (IllegalStateException ise) { + System.out.println("Got expected ISE: " + ise); + } + resp = uc.getResponseCode(); + check(resp == code, "Unexpected response code. Expected %s, got %s" + .formatted(code, resp)); + check(uc.getServerCertificates()); + uc.disconnect(); + try { + uc.getServerCertificates(); + throw new AssertionError("Expected IllegalStateException not thrown"); + } catch (IllegalStateException ise) { + System.out.println("Got expected ISE: " + ise); + } + } + + // HTTP Server + HttpServer startHttpServer() throws IOException { + InetAddress localhost = InetAddress.getLoopbackAddress(); + HttpsServer httpServer = HttpsServer + .create(new InetSocketAddress(localhost, 0), 0); + var configurator = new HttpsConfigurator(SimpleSSLContext.findSSLContext()); + httpServer.setHttpsConfigurator(configurator); + httpServer.createContext(URI_PATH, new SimpleHandler()); + httpServer.start(); + return httpServer; + } + + static class SimpleHandler implements HttpHandler { + @Override + public void handle(HttpExchange t) throws IOException { + try { + String path = t.getRequestURI().getRawPath(); + var test = TESTS.fromPath(path); + if (!path.startsWith(URI_PATH) || !test.isPresent()) { + t.getRequestBody().close(); + t.getResponseHeaders().add("Connection", "close"); + t.sendResponseHeaders(421, RSPBODY_EMPTY); + t.close(); + return; + } + try (var is = t.getRequestBody()) { + is.readAllBytes(); + } + switch (test.get()) { + case S204, S304, NOBODY -> + t.sendResponseHeaders(test.get().code(), RSPBODY_EMPTY); + case S200 -> { + byte[] bytes = BODY.getBytes(StandardCharsets.UTF_8); + t.sendResponseHeaders(test.get().code(), bytes.length); + try (var os = t.getResponseBody()) { + os.write(bytes); + } + } + case HEAD -> { + assert t.getRequestMethod().equals("HEAD"); + byte[] bytes = BODY.getBytes(StandardCharsets.UTF_8); + t.sendResponseHeaders(test.get().code(), bytes.length); + } + } + t.close(); + } catch (Throwable error) { + error.printStackTrace(); + throw error; + } + } + } + + volatile int passed = 0, failed = 0; + boolean debug = false; + void pass() {passed++;} + void fail() {failed++;} + void fail(String msg) {System.err.println(msg); fail();} + void unexpected(Throwable t) {failed++; t.printStackTrace();} + void debug(String message) { if (debug) System.out.println(message); } + void check(boolean cond, String failMessage) {if (cond) pass(); else fail(failMessage);} + void check(java.security.cert.Certificate[] certs) { + // Use List.of to check that certs is not null and does not + // contain null. NullPointerException will be thrown here + // if that happens, which will make the test fail. + check(!List.of(certs).isEmpty(), "no certificates returned"); + } + public static void main(String[] args) throws Throwable { + Class k = new Object(){}.getClass().getEnclosingClass(); + try {k.getMethod("instanceMain",String[].class) + .invoke( k.newInstance(), (Object) args);} + catch (Throwable e) {throw e.getCause();}} + public void instanceMain(String[] args) throws Throwable { + try {test(args);} catch (Throwable t) {unexpected(t);} + System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); + if (failed > 0) throw new AssertionError("Some tests failed");} +} diff --git a/test/jdk/sun/security/pkcs11/Cipher/TestPKCS5PaddingError.java b/test/jdk/sun/security/pkcs11/Cipher/TestPKCS5PaddingError.java index a8f50dddb53..ebd2c1c3436 100644 --- a/test/jdk/sun/security/pkcs11/Cipher/TestPKCS5PaddingError.java +++ b/test/jdk/sun/security/pkcs11/Cipher/TestPKCS5PaddingError.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,7 @@ import java.security.AlgorithmParameters; import java.security.NoSuchAlgorithmException; import java.security.Provider; +import java.security.Security; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; @@ -63,40 +64,55 @@ public class TestPKCS5PaddingError extends PKCS11Test { }; private static StringBuffer debugBuf = new StringBuffer(); + private static final String sunJCEProvider = + System.getProperty("test.provider.name", "SunJCE"); @Override public void main(Provider p) throws Exception { + + // Checking for SunJCE first + System.out.println("Checking " + sunJCEProvider + " provider"); + doTest(Security.getProvider(sunJCEProvider)); + + System.out.printf("Checking %s provider%n", p.getName()); + doTest(p); + } + + private void doTest(final Provider p) throws Exception { try { byte[] plainText = new byte[200]; - for (int i = 0; i < TEST_LIST.length; i++) { - CI currTest = TEST_LIST[i]; + for (CI currTest : TEST_LIST) { System.out.println("===" + currTest.transformation + "==="); try { KeyGenerator kg = KeyGenerator.getInstance(currTest.keyAlgo, p); SecretKey key = kg.generateKey(); Cipher c1 = Cipher.getInstance(currTest.transformation, - System.getProperty("test.provider.name", "SunJCE")); + sunJCEProvider); c1.init(Cipher.ENCRYPT_MODE, key); byte[] cipherText = c1.doFinal(plainText); AlgorithmParameters params = c1.getParameters(); Cipher c2 = Cipher.getInstance(currTest.transformation, p); c2.init(Cipher.DECRYPT_MODE, key, params); + c2.doFinal(cipherText); // 1st test: wrong output length - // NOTE: Skip NSS since it reports CKR_DEVICE_ERROR when - // the data passed to its EncryptUpdate/DecryptUpdate is - // not multiple of blocks + // NOTE: Skip NSS since it reports CKR_DEVICE_ERROR when the + // data passed to its EncryptUpdate and + // CKR_ENCRYPTED_DATA_LEN_RANGE when passed through + // DecryptUpdate are not multiple of blocks if (!p.getName().equals("SunPKCS11-NSS")) { try { System.out.println("Testing with wrong cipherText length"); c2.doFinal(cipherText, 0, cipherText.length - 2); + throw new RuntimeException( + "Expected IBSE NOT thrown"); } catch (IllegalBlockSizeException ibe) { // expected } catch (Exception ex) { System.out.println("Error: Unexpected Ex " + ex); - ex.printStackTrace(); + throw ex; } } // 2nd test: wrong padding value @@ -104,11 +120,12 @@ public class TestPKCS5PaddingError extends PKCS11Test { System.out.println("Testing with wrong padding bytes"); cipherText[cipherText.length - 1]++; c2.doFinal(cipherText); + System.out.println("WARNING: Expected BPE NOT thrown"); } catch (BadPaddingException bpe) { // expected } catch (Exception ex) { System.out.println("Error: Unexpected Ex " + ex); - ex.printStackTrace(); + throw ex; } System.out.println("DONE"); } catch (NoSuchAlgorithmException nsae) { @@ -119,13 +136,12 @@ public class TestPKCS5PaddingError extends PKCS11Test { } catch (Exception ex) { // print out debug info when exception is encountered if (debugBuf != null) { - System.out.println(debugBuf.toString()); + System.out.println(debugBuf); debugBuf = new StringBuffer(); } throw ex; } } - public static void main(String[] args) throws Exception { main(new TestPKCS5PaddingError(), args); } diff --git a/test/jdk/sun/security/provider/acvp/Launcher.java b/test/jdk/sun/security/provider/acvp/Launcher.java index 680d1026275..2ee0ff96bd1 100644 --- a/test/jdk/sun/security/provider/acvp/Launcher.java +++ b/test/jdk/sun/security/provider/acvp/Launcher.java @@ -41,6 +41,8 @@ import java.util.zip.ZipFile; * ML_DSA_Impls.version might be modified * @library /test/lib * @modules java.base/sun.security.provider + * java.base/sun.security.util + * java.base/com.sun.crypto.provider * @run main/othervm/timeout=480 Launcher */ @@ -50,6 +52,8 @@ import java.util.zip.ZipFile; * @summary Test verifying the intrinsic implementation. * @library /test/lib * @modules java.base/sun.security.provider + * java.base/sun.security.util + * java.base/com.sun.crypto.provider * @run main/othervm/timeout=480 -Xcomp Launcher */ diff --git a/test/jdk/sun/security/provider/acvp/ML_DSA_Test.java b/test/jdk/sun/security/provider/acvp/ML_DSA_Test.java index 281bb415305..ac56642b8d7 100644 --- a/test/jdk/sun/security/provider/acvp/ML_DSA_Test.java +++ b/test/jdk/sun/security/provider/acvp/ML_DSA_Test.java @@ -24,6 +24,7 @@ import jdk.test.lib.Asserts; import jdk.test.lib.json.JSONValue; import jdk.test.lib.security.FixedSecureRandom; import sun.security.provider.ML_DSA_Impls; +import sun.security.util.DerOutputStream; import java.security.*; import java.security.spec.EncodedKeySpec; @@ -68,12 +69,13 @@ public class ML_DSA_Test { System.out.println(">> " + pname); for (var c : t.get("tests").asArray()) { System.out.print(c.get("tcId").asString() + " "); - g.initialize(np, new FixedSecureRandom(toByteArray(c.get("seed").asString()))); + var seed = toByteArray(c.get("seed").asString()); + g.initialize(np, new FixedSecureRandom(seed)); var kp = g.generateKeyPair(); var pk = f.getKeySpec(kp.getPublic(), EncodedKeySpec.class).getEncoded(); - var sk = f.getKeySpec(kp.getPrivate(), EncodedKeySpec.class).getEncoded(); Asserts.assertEqualsByteArray(toByteArray(c.get("pk").asString()), pk); - Asserts.assertEqualsByteArray(toByteArray(c.get("sk").asString()), sk); + Asserts.assertEqualsByteArray(toByteArray(c.get("sk").asString()), + ML_DSA_Impls.seedToExpanded(pname, seed)); } System.out.println(); } @@ -106,7 +108,7 @@ public class ML_DSA_Test { var sk = new PrivateKey() { public String getAlgorithm() { return pname; } public String getFormat() { return "RAW"; } - public byte[] getEncoded() { return toByteArray(c.get("sk").asString()); } + public byte[] getEncoded() { return oct(toByteArray(c.get("sk").asString())); } }; var sr = new FixedSecureRandom( det ? new byte[32] : toByteArray(c.get("rnd").asString())); @@ -119,6 +121,10 @@ public class ML_DSA_Test { } } + static byte[] oct(byte[] in) { + return new DerOutputStream().putOctetString(in).toByteArray(); + } + static void sigVerTest(JSONValue kat, Provider p) throws Exception { var s = p == null ? Signature.getInstance("ML-DSA") diff --git a/test/jdk/sun/security/provider/acvp/ML_KEM_Test.java b/test/jdk/sun/security/provider/acvp/ML_KEM_Test.java index c46c6a99e6d..35c1ce611da 100644 --- a/test/jdk/sun/security/provider/acvp/ML_KEM_Test.java +++ b/test/jdk/sun/security/provider/acvp/ML_KEM_Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,9 +20,11 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ +import com.sun.crypto.provider.ML_KEM_Impls; import jdk.test.lib.Asserts; import jdk.test.lib.json.JSONValue; import jdk.test.lib.security.FixedSecureRandom; +import sun.security.util.DerOutputStream; import javax.crypto.KEM; import java.security.*; @@ -65,13 +67,14 @@ public class ML_KEM_Test { System.out.println(">> " + pname); for (var c : t.get("tests").asArray()) { System.out.print(c.get("tcId").asString() + " "); - g.initialize(np, new FixedSecureRandom( - toByteArray(c.get("d").asString()), toByteArray(c.get("z").asString()))); + var seed = toByteArray(c.get("d").asString() + c.get("z").asString()); + g.initialize(np, new FixedSecureRandom(seed)); var kp = g.generateKeyPair(); var pk = f.getKeySpec(kp.getPublic(), EncodedKeySpec.class).getEncoded(); - var sk = f.getKeySpec(kp.getPrivate(), EncodedKeySpec.class).getEncoded(); Asserts.assertEqualsByteArray(toByteArray(c.get("ek").asString()), pk); - Asserts.assertEqualsByteArray(toByteArray(c.get("dk").asString()), sk); + Asserts.assertEqualsByteArray( + toByteArray(c.get("dk").asString()), + ML_KEM_Impls.seedToExpanded(pname, seed)); } System.out.println(); } @@ -106,7 +109,7 @@ public class ML_KEM_Test { var dk = new PrivateKey() { public String getAlgorithm() { return pname; } public String getFormat() { return "RAW"; } - public byte[] getEncoded() { return toByteArray(t.get("dk").asString()); } + public byte[] getEncoded() { return oct(toByteArray(t.get("dk").asString())); } }; for (var c : t.get("tests").asArray()) { System.out.print(c.get("tcId").asString() + " "); @@ -118,4 +121,8 @@ public class ML_KEM_Test { } } } + + static byte[] oct(byte[] in) { + return new DerOutputStream().putOctetString(in).toByteArray(); + } } diff --git a/test/jdk/sun/security/provider/NamedEdDSA.java b/test/jdk/sun/security/provider/named/NamedEdDSA.java similarity index 84% rename from test/jdk/sun/security/provider/NamedEdDSA.java rename to test/jdk/sun/security/provider/named/NamedEdDSA.java index 4d0e3e9228a..30df8b22b31 100644 --- a/test/jdk/sun/security/provider/NamedEdDSA.java +++ b/test/jdk/sun/security/provider/named/NamedEdDSA.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,11 +23,12 @@ /* * @test - * @bug 8340327 + * @bug 8340327 8347938 * @modules java.base/sun.security.ec.ed * java.base/sun.security.ec.point * java.base/sun.security.jca * java.base/sun.security.provider + * java.base/sun.security.util * @library /test/lib */ @@ -40,7 +41,10 @@ import sun.security.jca.JCAUtil; import sun.security.provider.NamedKeyFactory; import sun.security.provider.NamedKeyPairGenerator; import sun.security.provider.NamedSignature; +import sun.security.util.DerOutputStream; +import sun.security.util.DerValue; +import java.io.IOException; import java.security.*; import java.security.spec.EdDSAParameterSpec; import java.security.spec.NamedParameterSpec; @@ -66,11 +70,11 @@ public class NamedEdDSA { public static class EdDSASignature extends NamedSignature { public EdDSASignature() { - super("EdDSA", "Ed25519", "Ed448"); + super("EdDSA", new EdDSAKeyFactory()); } protected EdDSASignature(String pname) { - super("EdDSA", pname); + super("EdDSA", new EdDSAKeyFactory(pname)); } public static class Ed25519 extends EdDSASignature { @@ -86,22 +90,32 @@ public class NamedEdDSA { } @Override - public byte[] implSign(String name, byte[] sk, Object sk2, byte[] msg, SecureRandom sr) throws SignatureException { - return getOps(name).sign(plain, sk, msg); + public byte[] implSign(String pname, byte[] sk, Object sk2, byte[] msg, SecureRandom sr) { + return getOps(pname).sign(plain, sk, msg); } @Override - public boolean implVerify(String name, byte[] pk, Object pk2, byte[] msg, byte[] sig) throws SignatureException { - return getOps(name).verify(plain, (AffinePoint) pk2, pk, msg, sig); + public boolean implVerify(String pname, byte[] pk, Object pk2, byte[] msg, byte[] sig) throws SignatureException { + return getOps(pname).verify(plain, (AffinePoint) pk2, pk, msg, sig); } @Override - public Object implCheckPublicKey(String name, byte[] pk) throws InvalidKeyException { - return getOps(name).decodeAffinePoint(InvalidKeyException::new, pk); + public Object implCheckPublicKey(String pname, byte[] pk) throws InvalidKeyException { + return getOps(pname).decodeAffinePoint(InvalidKeyException::new, pk); } } public static class EdDSAKeyFactory extends NamedKeyFactory { + @Override + protected byte[] implExpand(String pname, byte[] input) + throws InvalidKeyException { + try { + return new DerValue(input).getOctetString(); + } catch (IOException e) { + throw new InvalidKeyException(e); + } + } + public EdDSAKeyFactory() { super("EdDSA", "Ed25519", "Ed448"); } @@ -157,7 +171,10 @@ public class NamedEdDSA { // set the high-order bit of the encoded point byte msb = (byte) (point.isXOdd() ? 0x80 : 0); encodedPoint[encodedPoint.length - 1] |= msb; - return new byte[][] { encodedPoint, sk }; + return new byte[][] { + encodedPoint, + new DerOutputStream().putOctetString(sk).toByteArray(), + sk}; } private static void swap(byte[] arr, int i, int j) { diff --git a/test/jdk/sun/security/provider/NamedKeyFactoryTest.java b/test/jdk/sun/security/provider/named/NamedKeyFactoryTest.java similarity index 85% rename from test/jdk/sun/security/provider/NamedKeyFactoryTest.java rename to test/jdk/sun/security/provider/named/NamedKeyFactoryTest.java index 1ca179bc046..e58809fcb69 100644 --- a/test/jdk/sun/security/provider/NamedKeyFactoryTest.java +++ b/test/jdk/sun/security/provider/named/NamedKeyFactoryTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8340327 + * @bug 8340327 8347938 * @modules java.base/sun.security.x509 * java.base/sun.security.pkcs * java.base/sun.security.provider @@ -41,10 +41,13 @@ import sun.security.x509.NamedX509Key; import java.security.*; import java.security.spec.*; +import java.util.Arrays; public class NamedKeyFactoryTest { private static final SeededSecureRandom RAND = SeededSecureRandom.one(); + private static final byte[] RAW_SK = RAND.nBytes(16); + private static final byte[] RAW_PK = RAND.nBytes(16); public static void main(String[] args) throws Exception { Security.addProvider(new ProviderImpl()); @@ -78,8 +81,8 @@ public class NamedKeyFactoryTest { g.initialize(new NamedParameterSpec("ShA-256")); checkKeyPair(g.generateKeyPair(), "SHA", "SHA-256"); - var pk = new NamedX509Key("sHa", "ShA-256", RAND.nBytes(2)); - var sk = new NamedPKCS8Key("sHa", "SHa-256", RAND.nBytes(2)); + var pk = new NamedX509Key("sHa", "ShA-256", RAW_PK); + var sk = NamedPKCS8Key.internalCreate("sHa", "SHa-256", RAW_SK, null); checkKey(pk, "sHa", "ShA-256"); checkKey(sk, "sHa", "SHa-256"); @@ -134,25 +137,27 @@ public class NamedKeyFactoryTest { Asserts.assertEquals("RAW", srk2.getFormat()); Asserts.assertEqualsByteArray(srk2.getEncoded(), sk.getRawBytes()); + checkKey(kf2.generatePrivate(srk), "SHA", "SHA-256"); Asserts.assertEqualsByteArray(kf2.generatePrivate(srk).getEncoded(), sk.getEncoded()); Utils.runAndCheckException(() -> kf.generatePrivate(srk), InvalidKeySpecException.class); // no pname + checkKey(kf2.generatePrivate(srk), "SHA", "SHA-256"); Asserts.assertEqualsByteArray(kf2.generatePrivate(srk2).getEncoded(), sk.getEncoded()); Utils.runAndCheckException(() -> kf.generatePrivate(srk2), InvalidKeySpecException.class); // no pname var pk1 = new PublicKey() { public String getAlgorithm() { return "SHA"; } public String getFormat() { return "RAW"; } - public byte[] getEncoded() { return RAND.nBytes(2); } + public byte[] getEncoded() { return RAW_PK; } }; var pk2 = new PublicKey() { public String getAlgorithm() { return "sHA-256"; } public String getFormat() { return "RAW"; } - public byte[] getEncoded() { return RAND.nBytes(2); } + public byte[] getEncoded() { return RAW_PK; } }; var pk3 = new PublicKey() { public String getAlgorithm() { return "SHA"; } public String getFormat() { return "RAW"; } - public byte[] getEncoded() { return RAND.nBytes(2); } + public byte[] getEncoded() { return RAW_PK; } public AlgorithmParameterSpec getParams() { return new NamedParameterSpec("sHA-256"); } }; @@ -167,17 +172,17 @@ public class NamedKeyFactoryTest { var sk1 = new PrivateKey() { public String getAlgorithm() { return "SHA"; } public String getFormat() { return "RAW"; } - public byte[] getEncoded() { return RAND.nBytes(2); } + public byte[] getEncoded() { return RAW_SK; } }; var sk2 = new PrivateKey() { public String getAlgorithm() { return "sHA-256"; } public String getFormat() { return "RAW"; } - public byte[] getEncoded() { return RAND.nBytes(2); } + public byte[] getEncoded() { return RAW_SK; } }; var sk3 = new PrivateKey() { public String getAlgorithm() { return "SHA"; } public String getFormat() { return "RAW"; } - public byte[] getEncoded() { return RAND.nBytes(2); } + public byte[] getEncoded() { return RAW_SK; } public AlgorithmParameterSpec getParams() { return new NamedParameterSpec("sHA-256"); } }; @@ -201,6 +206,14 @@ public class NamedKeyFactoryTest { if (k instanceof AsymmetricKey ak && ak.getParams() instanceof NamedParameterSpec nps) { Asserts.assertEquals(pname, nps.getName()); } + if (k instanceof NamedPKCS8Key nsk) { + var raw = nsk.getRawBytes(); + Asserts.assertEqualsByteArray(Arrays.copyOf(RAW_SK, raw.length), raw); + } + if (k instanceof NamedX509Key npk) { + var raw = npk.getRawBytes(); + Asserts.assertEqualsByteArray(Arrays.copyOf(RAW_PK, raw.length), raw); + } } // Provider @@ -220,15 +233,24 @@ public class NamedKeyFactoryTest { public KF() { super("SHA", "SHA-256", "SHA-512"); } - } - public static class KF1 extends NamedKeyFactory { - public KF1() { - super("SHA", "SHA-256"); + + public KF(String name) { + super("SHA", name); + } + + @Override + protected byte[] implExpand(String pname, byte[] input) throws InvalidKeyException { + return null; } } - public static class KF2 extends NamedKeyFactory { + public static class KF1 extends KF { + public KF1() { + super("SHA-256"); + } + } + public static class KF2 extends KF { public KF2() { - super("SHA", "SHA-512"); + super("SHA-512"); } } public static class KPG extends NamedKeyPairGenerator { @@ -243,8 +265,8 @@ public class NamedKeyFactoryTest { @Override public byte[][] implGenerateKeyPair(String name, SecureRandom sr) { var out = new byte[2][]; - out[0] = RAND.nBytes(name.endsWith("256") ? 2 : 4); - out[1] = RAND.nBytes(name.endsWith("256") ? 2 : 4); + out[0] = name.endsWith("256") ? Arrays.copyOf(RAW_PK, 8) : RAW_PK; + out[1] = name.endsWith("256") ? Arrays.copyOf(RAW_SK, 8) : RAW_SK; return out; } } diff --git a/test/jdk/sun/security/provider/named/NamedKeys.java b/test/jdk/sun/security/provider/named/NamedKeys.java new file mode 100644 index 00000000000..e46cd981c70 --- /dev/null +++ b/test/jdk/sun/security/provider/named/NamedKeys.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8347938 + * @modules java.base/sun.security.pkcs + * java.base/sun.security.x509 + * @library /test/lib + * @summary check the Named***Key behavior + */ +import jdk.test.lib.Asserts; +import jdk.test.lib.security.SeededSecureRandom; +import sun.security.pkcs.NamedPKCS8Key; +import sun.security.x509.NamedX509Key; + +import java.util.Arrays; + +public class NamedKeys { + public static void main(String[] args) throws Exception { + + // This test uses fictional key algorithms SHA and SHA-256, + // simply because they look like a family name and parameter + // set name and SHA-256 already have its OID defined. + + var r = SeededSecureRandom.one(); + var raw = r.nBytes(32); + + // Create a key using raw bytes + var sk = NamedPKCS8Key.internalCreate("SHA", "SHA-256", raw, null); + var enc = sk.getEncoded(); + + // The raw bytes array is re-used + Asserts.assertTrue(sk.getRawBytes() == sk.getRawBytes()); + // but the encoding is different + Asserts.assertTrue(sk.getEncoded() != sk.getEncoded()); + + // When source change + Arrays.fill(raw, (byte)0); + // Internal raw bytes also changes + Asserts.assertEqualsByteArray(sk.getRawBytes(), new byte[32]); + // No guarantee on getEncoded() output, could be cached + + // Create a key using encoding + var sk1 = new NamedPKCS8Key("SHA", enc, null); + var sk2 = new NamedPKCS8Key("SHA", enc, null); + var raw1 = sk1.getRawBytes(); + Asserts.assertTrue(raw1 != sk2.getRawBytes()); + Asserts.assertTrue(sk1.getEncoded() != sk2.getEncoded()); + + var encCopy = enc.clone(); // store a copy + Arrays.fill(enc, (byte)0); // clean the source and the key unchanged + Asserts.assertEqualsByteArray(encCopy, sk1.getEncoded()); + + // Same with public key + // Create a key using raw bytes + raw = r.nBytes(32); + var pk = new NamedX509Key("SHA", "SHA-256", raw); + enc = pk.getEncoded().clone(); + + // The raw bytes array is re-used + Asserts.assertTrue(pk.getRawBytes() == pk.getRawBytes()); + // but the encoding is different + Asserts.assertTrue(pk.getEncoded() != pk.getEncoded()); + + // When source change + Arrays.fill(raw, (byte)0); + // Internal raw bytes also changes + Asserts.assertEqualsByteArray(pk.getRawBytes(), new byte[32]); + // No guarantee on getEncoded() output, could be cached + + // Create a key using encoding + var pk1 = new NamedX509Key("SHA", enc); + var pk2 = new NamedX509Key("SHA", enc); + raw1 = pk1.getRawBytes(); + Asserts.assertTrue(raw1 != pk2.getRawBytes()); + Asserts.assertTrue(pk1.getEncoded() != pk2.getEncoded()); + + encCopy = enc.clone(); // store a copy + Arrays.fill(enc, (byte)0); // clean the source and the key unchanged + Asserts.assertEqualsByteArray(encCopy, pk1.getEncoded()); + } +} diff --git a/test/jdk/sun/security/provider/pqc/PrivateKeyEncodings.java b/test/jdk/sun/security/provider/pqc/PrivateKeyEncodings.java new file mode 100644 index 00000000000..25060d0b74e --- /dev/null +++ b/test/jdk/sun/security/provider/pqc/PrivateKeyEncodings.java @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8347938 + * @library /test/lib + * @summary ensure ML-KEM and ML-DSA encodings consistent with + * draft-ietf-lamps-kyber-certificates-11 and RFC 9881 + * @modules java.base/com.sun.crypto.provider + * java.base/sun.security.pkcs + * java.base/sun.security.provider + * @run main/othervm PrivateKeyEncodings + */ +import com.sun.crypto.provider.ML_KEM_Impls; +import jdk.test.lib.Asserts; +import jdk.test.lib.security.RepositoryFileReader; +import jdk.test.lib.security.FixedSecureRandom; +import sun.security.pkcs.NamedPKCS8Key; +import sun.security.provider.ML_DSA_Impls; + +import javax.crypto.KEM; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.security.InvalidKeyException; +import java.security.KeyFactory; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.Signature; +import java.security.cert.CertificateFactory; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.NamedParameterSpec; +import java.security.spec.PKCS8EncodedKeySpec; +import java.util.Base64; +import java.util.HashMap; +import java.util.List; +import java.util.stream.Collectors; + +public class PrivateKeyEncodings { + + public static void main(String[] args) throws Exception { + // Example keys and certificates draft-ietf-lamps-kyber-certificates-11, Appendix B + // (https://datatracker.ietf.org/doc/html/draft-ietf-lamps-kyber-certificates-11#autoid-17) + // and RFC 9881, Appendix C.3 + // (https://datatracker.ietf.org/doc/html/rfc9881#name-example-certificates) + // + // These data can be retrieved from the following GitHub releases: + // https://github.com/lamps-wg/kyber-certificates/releases/tag/draft-ietf-lamps-kyber-certificates-11 + // https://github.com/lamps-wg/dilithium-certificates/releases/tag/draft-ietf-lamps-dilithium-certificates-13 + // + // Although the release tags include "draft", these values are the + // same as those in the final RFC 9881. + try (var kemReader = RepositoryFileReader.of(RepositoryFileReader.KYBER_CERTIFICATES.class, + "kyber-certificates-draft-ietf-lamps-kyber-certificates-11/"); + var dsaReader = RepositoryFileReader.of(RepositoryFileReader.DILITHIUM_CERTIFICATES.class, + "dilithium-certificates-draft-ietf-lamps-dilithium-certificates-13/")) { + good(kemReader, dsaReader); + badkem(kemReader); + baddsa(dsaReader); + } + } + + static void badkem(RepositoryFileReader f) throws Exception { + var kf = KeyFactory.getInstance("ML-KEM"); + + // The first ML-KEM-512-PrivateKey example includes the both CHOICE, + // i.e., both seed and expandedKey are included. The seed and expanded + // values can be checked for inconsistencies. + Asserts.assertThrows(InvalidKeySpecException.class, () -> + kf.generatePrivate(new PKCS8EncodedKeySpec( + readData(f, "example/bad-ML-KEM-512-1.priv")))); + + // The second ML-KEM-512-PrivateKey example includes only expandedKey. + // The expanded private key has a mutated s_0 and a valid public key hash, + // but a pairwise consistency check would find that the public key + // fails to match private. + var k2 = kf.generatePrivate(new PKCS8EncodedKeySpec( + readData(f, "example/bad-ML-KEM-512-2.priv"))); + var pk2 = ML_KEM_Impls.privKeyToPubKey((NamedPKCS8Key) k2); + var enc = KEM.getInstance("ML-KEM").newEncapsulator(pk2).encapsulate(); + var dk = KEM.getInstance("ML-KEM").newDecapsulator(k2).decapsulate(enc.encapsulation()); + Asserts.assertNotEqualsByteArray(enc.key().getEncoded(), dk.getEncoded()); + + // The third ML-KEM-512-PrivateKey example includes only expandedKey. + // The expanded private key has a mutated H(ek); both a public key + // digest check and a pairwise consistency check should fail. + var k3 = kf.generatePrivate(new PKCS8EncodedKeySpec( + readData(f, "example/bad-ML-KEM-512-3.priv"))); + Asserts.assertThrows(InvalidKeyException.class, () -> + KEM.getInstance("ML-KEM").newDecapsulator(k3)); + + // The fourth ML-KEM-512-PrivateKey example includes the both CHOICE, + // i.e., both seed and expandedKey are included. There is mismatch + // of the seed and expanded private key in only the z implicit rejection + // secret; here the private and public vectors match and the pairwise + // consistency check passes, but z is different. + Asserts.assertThrows(InvalidKeySpecException.class, () -> + kf.generatePrivate(new PKCS8EncodedKeySpec( + readData(f, "example/bad-ML-KEM-512-4.priv")))); + } + + static void baddsa(RepositoryFileReader f) throws Exception { + var kf = KeyFactory.getInstance("ML-DSA"); + + // The first ML-DSA-PrivateKey example includes the both CHOICE, i.e., + // both seed and expandedKey are included. The seed and expanded values + // can be checked for inconsistencies. + Asserts.assertThrows(InvalidKeySpecException.class, () -> + kf.generatePrivate(new PKCS8EncodedKeySpec( + readData(f, "examples/bad-ML-DSA-44-1.priv")))); + + // The second ML-DSA-PrivateKey example includes only expandedKey. + // The public key fails to match the tr hash value in the private key. + var k2 = kf.generatePrivate(new PKCS8EncodedKeySpec( + readData(f, "examples/bad-ML-DSA-44-2.priv"))); + Asserts.assertThrows(IllegalArgumentException.class, () -> + ML_DSA_Impls.privKeyToPubKey((NamedPKCS8Key) k2)); + + // The third ML-DSA-PrivateKey example also includes only expandedKey. + // The private s_1 and s_2 vectors imply a t vector whose private low + // bits do not match the t_0 vector portion of the private key + // (its high bits t_1 are the primary content of the public key). + var k3 = kf.generatePrivate(new PKCS8EncodedKeySpec( + readData(f, "examples/bad-ML-DSA-44-3.priv"))); + Asserts.assertThrows(IllegalArgumentException.class, () -> + ML_DSA_Impls.privKeyToPubKey((NamedPKCS8Key) k3)); + } + + static void good(RepositoryFileReader kemReader, RepositoryFileReader dsaReader) + throws Exception { + + var seed = new byte[64]; + for (var i = 0; i < seed.length; i++) { + seed[i] = (byte) i; + } + var cf = CertificateFactory.getInstance("X.509"); + var allPublicKeys = new HashMap(); + + for (var pname: List.of("ML-DSA-44", "ML-DSA-65", "ML-DSA-87", // DSA first, will sign KEM + "ML-KEM-512", "ML-KEM-768", "ML-KEM-1024")) { + + var isKem = pname.startsWith("ML-KEM"); + KeyPairGenerator g = KeyPairGenerator.getInstance(isKem ? "ML-KEM" : "ML-DSA"); + var prop = isKem ? "mlkem" : "mldsa"; + var f = isKem ? kemReader : dsaReader; + var example = isKem ? "example/" : "examples/"; + + g.initialize(new NamedParameterSpec(pname), new FixedSecureRandom(seed)); + var pk = g.generateKeyPair().getPublic(); + allPublicKeys.put(pname, pk); + Asserts.assertEqualsByteArray(readData(f, example + pname + ".pub"), pk.getEncoded()); + + var in = new ByteArrayInputStream(readData(f, example + pname + ".crt")); + var c = cf.generateCertificate(in); + var signer = switch (pname) { + case "ML-KEM-512" -> allPublicKeys.get("ML-DSA-44"); + case "ML-KEM-768" -> allPublicKeys.get("ML-DSA-65"); + case "ML-KEM-1024" -> allPublicKeys.get("ML-DSA-87"); + default -> c.getPublicKey(); + }; + c.verify(signer); + Asserts.assertEquals(c.getPublicKey(), pk); + + for (var type : List.of("seed", "expandedkey", "both")) { + System.err.println(pname + " " + type); + System.setProperty("jdk." + prop + ".pkcs8.encoding", type); + g.initialize(new NamedParameterSpec(pname), new FixedSecureRandom(seed)); + var sk = g.generateKeyPair().getPrivate(); + if (type.equals("expandedkey")) type = "expanded"; + Asserts.assertEqualsByteArray( + readData(f, example + pname + "-" + type + ".priv"), sk.getEncoded()); + checkInterop(pk, sk); + } + } + } + + // Ensures pk and sk interop with each other + static void checkInterop(PublicKey pk, PrivateKey sk) throws Exception { + if (pk.getAlgorithm().startsWith("ML-KEM")) { + var kem = KEM.getInstance("ML-KEM"); + var enc = kem.newEncapsulator(pk).encapsulate(); + var k = kem.newDecapsulator(sk).decapsulate(enc.encapsulation()); + Asserts.assertEqualsByteArray(k.getEncoded(), enc.key().getEncoded()); + } else { + var msg = "hello".getBytes(StandardCharsets.UTF_8); + var s = Signature.getInstance("ML-DSA"); + s.initSign(sk); + s.update(msg); + var sig = s.sign(); + s.initVerify(pk); + s.update(msg); + Asserts.assertTrue(s.verify(sig)); + } + } + + static byte[] readData(RepositoryFileReader f, String entry) throws Exception { + byte[] data = f.read(entry); + var pem = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(data))) + .lines() + .filter(s -> !s.contains("-----")) + .collect(Collectors.joining()); + return Base64.getMimeDecoder().decode(pem); + } +} diff --git a/test/jdk/sun/security/provider/pqc/SeedOrExpanded.java b/test/jdk/sun/security/provider/pqc/SeedOrExpanded.java new file mode 100644 index 00000000000..0a5b462b037 --- /dev/null +++ b/test/jdk/sun/security/provider/pqc/SeedOrExpanded.java @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8347938 + * @library /test/lib + * @modules java.base/com.sun.crypto.provider + * java.base/sun.security.pkcs + * java.base/sun.security.provider + * java.base/sun.security.util + * java.base/sun.security.x509 + * @summary check key reading compatibility + * @run main/othervm SeedOrExpanded + */ + +import com.sun.crypto.provider.ML_KEM_Impls; +import jdk.test.lib.Asserts; +import jdk.test.lib.security.DerUtils; +import jdk.test.lib.security.FixedSecureRandom; +import jdk.test.lib.security.SeededSecureRandom; +import sun.security.pkcs.NamedPKCS8Key; +import sun.security.provider.ML_DSA_Impls; +import sun.security.util.DerValue; + +import javax.crypto.KEM; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.Signature; + +public class SeedOrExpanded { + + static final SeededSecureRandom RAND = SeededSecureRandom.one(); + + public static void main(String[] args) throws Exception { + test("mlkem", "ML-KEM-768"); + test("mldsa", "ML-DSA-65"); + } + + static void test(String type, String alg) throws Exception { + + var seed = RAND.nBytes(alg.contains("ML-KEM") ? 64 : 32); + var g = KeyPairGenerator.getInstance(alg); + + // Generation + + g.initialize(-1, new FixedSecureRandom(seed)); + var kp = g.generateKeyPair(); + var pk = kp.getPublic(); + var kDefault = kp.getPrivate(); + + // Property value is case-insensitive + System.setProperty("jdk." + type + ".pkcs8.encoding", "SEED"); + g.initialize(-1, new FixedSecureRandom(seed)); + var kSeed = g.generateKeyPair().getPrivate(); + System.setProperty("jdk." + type + ".pkcs8.encoding", "expandedkey"); + g.initialize(-1, new FixedSecureRandom(seed)); + var kExpanded = g.generateKeyPair().getPrivate(); + System.setProperty("jdk." + type + ".pkcs8.encoding", "boTH"); + g.initialize(-1, new FixedSecureRandom(seed)); + var kBoth = g.generateKeyPair().getPrivate(); + + // Invalid property value + System.setProperty("jdk." + type + ".pkcs8.encoding", "bogus"); + g.initialize(-1, new FixedSecureRandom(seed)); + Asserts.assertThrows(IllegalArgumentException.class, + () -> g.generateKeyPair().getPrivate()); + + byte[] kExpandedEncoded = kExpanded.getEncoded(); + byte[] kSeedEncoded = kSeed.getEncoded(); + byte[] kBothEncoded = kBoth.getEncoded(); + + // Ensure tags match the CHOICE definition + Asserts.assertEquals((byte) 0x80, DerUtils.innerDerValue(kSeedEncoded, "2c").tag); + Asserts.assertEquals((byte) 0x04, DerUtils.innerDerValue(kExpandedEncoded, "2c").tag); + Asserts.assertEquals((byte) 0x30, DerUtils.innerDerValue(kBothEncoded, "2c").tag); + + byte[] seedData = DerUtils.innerDerValue(kSeedEncoded, "2c") + .withTag(DerValue.tag_OctetString).getOctetString(); + byte[] expandedData = DerUtils.innerDerValue(kExpandedEncoded, "2c").getOctetString(); + + Asserts.assertEqualsByteArray(seed, seedData); + Asserts.assertEqualsByteArray( + seedData, + DerUtils.innerDerValue(kBothEncoded, "2c0").getOctetString()); + Asserts.assertEqualsByteArray( + expandedData, + DerUtils.innerDerValue(kBothEncoded, "2c1").getOctetString()); + + // Ensure seedToExpanded correctly called + if (alg.contains("ML-KEM")) { + Asserts.assertEqualsByteArray(expandedData, + ML_KEM_Impls.seedToExpanded(alg, seedData)); + } else { + Asserts.assertEqualsByteArray(expandedData, + ML_DSA_Impls.seedToExpanded(alg, seedData)); + } + + test(alg, pk, kSeed); + test(alg, pk, kExpanded); + test(alg, pk, kBoth); + + var kf = KeyFactory.getInstance(alg); + + System.setProperty("jdk." + type + ".pkcs8.encoding", "seed"); + Asserts.assertEqualsByteArray( + test(alg, pk, kf.translateKey(kBoth)).getEncoded(), + kSeedEncoded); + Asserts.assertTrue(kf.translateKey(kSeed) == kSeed); + Asserts.assertThrows(InvalidKeyException.class, () -> kf.translateKey(kExpanded)); + + System.setProperty("jdk." + type + ".pkcs8.encoding", "expandedkey"); + Asserts.assertEqualsByteArray( + test(alg, pk, kf.translateKey(kBoth)).getEncoded(), + kExpandedEncoded); + Asserts.assertEqualsByteArray( + test(alg, pk, kf.translateKey(kSeed)).getEncoded(), + kExpandedEncoded); + Asserts.assertTrue(kf.translateKey(kExpanded) == kExpanded); + + System.setProperty("jdk." + type + ".pkcs8.encoding", "both"); + Asserts.assertTrue(kf.translateKey(kBoth) == kBoth); + Asserts.assertEqualsByteArray( + test(alg, pk, kf.translateKey(kSeed)).getEncoded(), + kBothEncoded); + Asserts.assertThrows(InvalidKeyException.class, () -> kf.translateKey(kExpanded)); + + // The following makes sure key is not mistakenly cleaned during + // translations. + var xk = new PrivateKey() { + public String getAlgorithm() { return alg; } + public String getFormat() { return "PKCS#8"; } + public byte[] getEncoded() { return kBothEncoded.clone(); } + }; + test(alg, pk, xk); + var xk2 = (PrivateKey) kf.translateKey(xk); + test(alg, pk, xk2); + test(alg, pk, xk); + } + + static PrivateKey test(String alg, PublicKey pk, Key k) throws Exception { + var sk = (PrivateKey) k; + if (alg.contains("ML-KEM")) { + var kem = KEM.getInstance("ML-KEM"); + var e = kem.newEncapsulator(pk, RAND); + var enc = e.encapsulate(); + var k1 = kem.newDecapsulator(sk).decapsulate(enc.encapsulation()); + Asserts.assertEqualsByteArray(k1.getEncoded(), enc.key().getEncoded()); + if (k instanceof NamedPKCS8Key npk) { + Asserts.assertEqualsByteArray( + ML_KEM_Impls.privKeyToPubKey(npk).getEncoded(), pk.getEncoded()); + } + } else { + var s = Signature.getInstance("ML-DSA"); + var rnd = RAND.nBytes(32); // randomness for signature generation + var msg = RAND.nBytes(20); + s.initSign(sk, new FixedSecureRandom(rnd)); + s.update(msg); + var sig1 = s.sign(); + s.initVerify(pk); + s.update(msg); + Asserts.assertTrue(s.verify(sig1)); + if (k instanceof NamedPKCS8Key npk) { + Asserts.assertEqualsByteArray( + ML_DSA_Impls.privKeyToPubKey(npk).getEncoded(), pk.getEncoded()); + } + } + return sk; + } +} diff --git a/test/jdk/tools/jar/ValidatorTest.java b/test/jdk/tools/jar/ValidatorTest.java index c2dfeae8dec..e3f649a04a2 100644 --- a/test/jdk/tools/jar/ValidatorTest.java +++ b/test/jdk/tools/jar/ValidatorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,12 +23,8 @@ /* * @test - * @bug 8345431 + * @bug 8345431 8375433 * @summary test validator to report malformed jar file - * @library /test/lib - * @modules jdk.jartool - * @build jdk.test.lib.Platform - * jdk.test.lib.util.FileUtils * @run junit/othervm ValidatorTest */ @@ -40,6 +36,7 @@ import org.junit.jupiter.api.TestInstance.Lifecycle; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertLinesMatch; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; @@ -59,13 +56,15 @@ import java.util.stream.Stream; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; -import jdk.test.lib.util.FileUtils; - class ValidatorTest { private static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar") .orElseThrow(() -> new RuntimeException("jar tool not found") ); + private static final ToolProvider JAVAC_TOOL = ToolProvider.findFirst("javac") + .orElseThrow(() -> + new RuntimeException("javac tool not found") + ); private final String nl = System.lineSeparator(); private final ByteArrayOutputStream baos = new ByteArrayOutputStream(); @@ -310,6 +309,44 @@ class ValidatorTest { } } + @Test + public void testInvalidAutomaticModuleName() throws Exception { + System.out.printf("%n%n*****Creating Jar with invalid Automatic-Module-Name in Manifest*****%n%n"); + var file = Path.of("InvalidAutomaticModuleName.jar"); + var manifest = Path.of("MANIFEST.MF"); + Files.writeString(manifest, + """ + Automatic-Module-Name: default + """); + jar("--create --file " + file + " --manifest " + manifest); + var e = assertThrows(IOException.class, () -> jar("--validate --file " + file.toString())); + var err = e.getMessage(); + System.out.println(err); + assertTrue(err.contains("invalid module name of Automatic-Module-Name entry in manifest: default"), "missing warning for: default"); + } + + @Test + public void testWrongAutomaticModuleName() throws Exception { + System.out.printf("%n%n*****Creating Jar with wrong Automatic-Module-Name in Manifest*****%n%n"); + var file = Path.of("WrongAutomaticModuleName.jar"); + var foo = Path.of("module-info.java"); + Files.writeString(foo, + """ + module foo {} + """); + var manifest = Path.of("MANIFEST.MF"); + Files.writeString(manifest, + """ + Automatic-Module-Name: bar + """); + JAVAC_TOOL.run(System.out, System.err, foo.toString()); + jar("--create --file " + file + " --manifest " + manifest + " module-info.class"); + var e = assertThrows(IOException.class, () -> jar("--validate --file " + file.toString())); + var err = e.getMessage(); + System.out.println(err); + assertTrue(err.contains("expected Automatic-Module-Name entry in manifest: bar to match name of compiled module: foo"), "missing warning for: foo/bar"); + } + /** * Validates that base manifest-related entries are at expected LOC positions. *

    diff --git a/test/jdk/tools/jimage/VerifyJimage.java b/test/jdk/tools/jimage/VerifyJimage.java index 08f567cbecb..723ad089fa9 100644 --- a/test/jdk/tools/jimage/VerifyJimage.java +++ b/test/jdk/tools/jimage/VerifyJimage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -145,15 +145,9 @@ public abstract class VerifyJimage implements Runnable { pool.execute(new ModuleResourceComparator(rootDir, modName, jimage)); } } - pool.shutdown(); - if (!pool.awaitTermination(20, TimeUnit.SECONDS)) { - failed.add("Directory verification timed out"); - } + pool.close(); } catch (IOException ex) { throw new UncheckedIOException(ex); - } catch (InterruptedException e) { - failed.add("Directory verification was interrupted"); - Thread.currentThread().interrupt(); } } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/FailedCommandErrorValidator.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/FailedCommandErrorValidator.java new file mode 100644 index 00000000000..ab644c36a5c --- /dev/null +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/FailedCommandErrorValidator.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +package jdk.jpackage.test; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.regex.Pattern; + +/** + * Validates failed command error in jpackage's output. + */ +public final class FailedCommandErrorValidator { + + public FailedCommandErrorValidator(Pattern cmdlinePattern) { + this.cmdlinePattern = Objects.requireNonNull(cmdlinePattern); + } + + public TKit.TextStreamVerifier.Group createGroup() { + var asPredicate = cmdlinePattern.asPredicate(); + + var errorMessage = exitCode().map(v -> { + return JPackageStringBundle.MAIN.cannedFormattedString("error.command-failed-unexpected-exit-code", v, ""); + }).orElseGet(() -> { + return JPackageStringBundle.MAIN.cannedFormattedString("error.command-failed-unexpected-output", ""); + }); + + var errorMessageWithPrefix = JPackageCommand.makeError(errorMessage).getValue(); + + var group = TKit.TextStreamVerifier.group(); + + group.add(TKit.assertTextStream(cmdlinePattern.pattern()).predicate(line -> { + if (line.startsWith(errorMessageWithPrefix)) { + line = line.substring(errorMessageWithPrefix.length()); + return asPredicate.test(line); + } else { + return false; + } + })); + + group.add(TKit.assertTextStream( + JPackageStringBundle.MAIN.cannedFormattedString("message.failed-command-output-header").getValue() + ).predicate(String::equals)); + + outputVerifier().ifPresent(group::add); + + return group; + } + + public void applyTo(JPackageCommand cmd) { + cmd.validateOutput(createGroup().create()); + } + + public FailedCommandErrorValidator validator(TKit.TextStreamVerifier.Group v) { + outputValidator = v; + return this; + } + + public FailedCommandErrorValidator validator(List validators) { + var group = TKit.TextStreamVerifier.group(); + validators.forEach(group::add); + return validator(group); + } + + public FailedCommandErrorValidator validators(TKit.TextStreamVerifier... validators) { + return validator(List.of(validators)); + } + + public FailedCommandErrorValidator output(List v) { + return validator(v.stream().map(TKit::assertTextStream).toList()); + } + + public FailedCommandErrorValidator output(String... output) { + return output(List.of(output)); + } + + public FailedCommandErrorValidator exitCode(int v) { + exitCode = v; + return this; + } + + private Optional exitCode() { + return Optional.ofNullable(exitCode); + } + + private Optional outputVerifier() { + return Optional.ofNullable(outputValidator); + } + + private final Pattern cmdlinePattern; + private TKit.TextStreamVerifier.Group outputValidator; + private Integer exitCode; +} diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java index f81c35cea0b..8c7526be9f9 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java @@ -906,6 +906,11 @@ public class JPackageCommand extends CommandArguments { return this; } + public JPackageCommand validateOutput(TKit.TextStreamVerifier.Group group) { + group.tryCreate().ifPresent(this::validateOutput); + return this; + } + @FunctionalInterface public interface CannedArgument { public String value(JPackageCommand cmd); @@ -947,11 +952,11 @@ public class JPackageCommand extends CommandArguments { public JPackageCommand validateOutput(CannedFormattedString... str) { // Will look up the given errors in the order they are specified. - Stream.of(str).map(this::getValue) + validateOutput(Stream.of(str).map(this::getValue) .map(TKit::assertTextStream) .reduce(TKit.TextStreamVerifier.group(), TKit.TextStreamVerifier.Group::add, - TKit.TextStreamVerifier.Group::add).tryCreate().ifPresent(this::validateOutput); + TKit.TextStreamVerifier.Group::add)); return this; } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java index dc1a7b3512b..1191cd02221 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java @@ -782,6 +782,10 @@ public final class MacHelper { return sign(cmd); } + public Optional optionName() { + return type.mapOptionName(certRequest.type()); + } + public List asCmdlineArgs() { String[] args = new String[2]; applyTo((optionName, optionValue) -> { @@ -791,6 +795,10 @@ public final class MacHelper { return List.of(args); } + public Optional passThrough() { + return optionName().map(Name::passThrough); + } + private void applyTo(BiConsumer sink) { type.mapOptionName(certRequest.type()).ifPresent(optionName -> { sink.accept(optionName.optionName(), optionValue()); @@ -886,6 +894,14 @@ public final class MacHelper { return signKeyOption.certRequest(); } + public Optional optionName() { + return signKeyOption.optionName(); + } + + public Optional passThrough() { + return signKeyOption.passThrough(); + } + public JPackageCommand addTo(JPackageCommand cmd) { Optional.ofNullable(cmd.getArgumentValue("--mac-signing-keychain")).ifPresentOrElse(configuredKeychain -> { if (!configuredKeychain.equals(keychain.name())) { diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java index 1639beadb28..7666d1e5167 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java @@ -65,6 +65,7 @@ import java.util.function.BiPredicate; import java.util.function.Consumer; import java.util.function.Predicate; import java.util.function.Supplier; +import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; import jdk.internal.util.OperatingSystem; @@ -1082,6 +1083,11 @@ public final class TKit { predicate(String::contains); } + TextStreamVerifier(Pattern value) { + this(Objects.requireNonNull(value).pattern()); + predicate(value.asPredicate()); + } + TextStreamVerifier(TextStreamVerifier other) { predicate = other.predicate; label = other.label; @@ -1091,6 +1097,10 @@ public final class TKit { value = other.value; } + public TextStreamVerifier copy() { + return new TextStreamVerifier(this); + } + public TextStreamVerifier label(String v) { label = v; return this; @@ -1101,6 +1111,13 @@ public final class TKit { return this; } + public TextStreamVerifier predicate(Predicate v) { + Objects.requireNonNull(v); + return predicate((str, _) -> { + return v.test(str); + }); + } + public TextStreamVerifier negate() { negate = true; return this; @@ -1116,7 +1133,12 @@ public final class TKit { return this; } - private String findMatch(Iterator lineIt) { + public TextStreamVerifier mutate(Consumer mutator) { + mutator.accept(this); + return this; + } + + private String find(Iterator lineIt) { while (lineIt.hasNext()) { final var line = lineIt.next(); if (predicate.test(line, value)) { @@ -1131,7 +1153,7 @@ public final class TKit { } public void apply(Iterator lineIt) { - final String matchedStr = findMatch(lineIt); + final String matchedStr = find(lineIt); final String labelStr = Optional.ofNullable(label).orElse("output"); if (negate) { String msg = String.format( @@ -1180,6 +1202,11 @@ public final class TKit { return this; } + public Group mutate(Consumer mutator) { + mutator.accept(this); + return this; + } + public boolean isEmpty() { return verifiers.isEmpty(); } @@ -1226,6 +1253,18 @@ public final class TKit { return new TextStreamVerifier(what); } + public static TextStreamVerifier assertTextStream(Pattern what) { + return new TextStreamVerifier(what); + } + + public static Consumer> assertEndOfTextStream() { + return it -> { + var tail = new ArrayList(); + it.forEachRemaining(tail::add); + assertStringListEquals(List.of(), tail, "Check the end of the output"); + }; + } + public record PathSnapshot(List contentHashes) { public PathSnapshot { contentHashes.forEach(Objects::requireNonNull); diff --git a/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/cli/MainTest.java b/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/cli/MainTest.java index 79648260274..46de970a829 100644 --- a/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/cli/MainTest.java +++ b/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/cli/MainTest.java @@ -279,9 +279,7 @@ public class MainTest extends JUnitAdapter { expectedOutput.add(ExceptionFormatter.STACK_TRACE); } expectedOutput.add(expect.getValue()); - if (!verbose) { - expectedOutput.add(ExceptionFormatter.FAILED_COMMAND_OUTPUT); - } + expectedOutput.add(ExceptionFormatter.FAILED_COMMAND_OUTPUT); data.add(new ErrorReporterTestSpec(cause, expect.getKey(), verbose, expectedOutput)); } } diff --git a/test/jdk/tools/jpackage/macosx/MacSignTest.java b/test/jdk/tools/jpackage/macosx/MacSignTest.java index a824fdb0925..0be494ea469 100644 --- a/test/jdk/tools/jpackage/macosx/MacSignTest.java +++ b/test/jdk/tools/jpackage/macosx/MacSignTest.java @@ -22,22 +22,23 @@ */ import static jdk.jpackage.test.MacHelper.SignKeyOption.Type.SIGN_KEY_IDENTITY; +import static jdk.jpackage.test.MacHelper.SignKeyOption.Type.SIGN_KEY_IDENTITY_APP_IMAGE; import static jdk.jpackage.test.MacHelper.SignKeyOption.Type.SIGN_KEY_USER_FULL_NAME; import static jdk.jpackage.test.MacHelper.SignKeyOption.Type.SIGN_KEY_USER_SHORT_NAME; -import static jdk.jpackage.test.MacHelper.SignKeyOption.Type.SIGN_KEY_IDENTITY_APP_IMAGE; import java.io.IOException; import java.nio.file.Files; -import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.function.Function; import java.util.function.Predicate; +import java.util.regex.Pattern; import java.util.stream.Stream; import jdk.jpackage.test.Annotations.Parameter; import jdk.jpackage.test.Annotations.ParameterSupplier; import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.CannedFormattedString; +import jdk.jpackage.test.FailedCommandErrorValidator; import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.JPackageStringBundle; import jdk.jpackage.test.MacHelper; @@ -74,22 +75,32 @@ public class MacSignTest { Files.createDirectory(appContent); Files.createFile(appContent.resolve("file")); - final List expectedStrings = new ArrayList<>(); - expectedStrings.add(JPackageStringBundle.MAIN.cannedFormattedString("message.codesign.failed.reason.app.content")); + final var group = TKit.TextStreamVerifier.group(); - expectedStrings.add(JPackageStringBundle.MAIN.cannedFormattedString("error.tool.failed.with.output", "codesign")); + group.add(TKit.assertTextStream(JPackageStringBundle.MAIN.cannedFormattedString( + "message.codesign.failed.reason.app.content").getValue()).predicate(String::equals)); + + final var xcodeWarning = TKit.assertTextStream(JPackageStringBundle.MAIN.cannedFormattedString( + "message.codesign.failed.reason.xcode.tools").getValue()).predicate(String::equals); - final var xcodeWarning = JPackageStringBundle.MAIN.cannedFormattedString("message.codesign.failed.reason.xcode.tools"); if (!MacHelper.isXcodeDevToolsInstalled()) { - expectedStrings.add(xcodeWarning); + group.add(xcodeWarning); } - MacSign.withKeychain(keychain -> { + var keychain = SigningBase.StandardKeychain.MAIN.keychain(); - var signingKeyOption = new SignKeyOptionWithKeychain( - SIGN_KEY_IDENTITY, - SigningBase.StandardCertificateRequest.CODESIGN, - keychain); + var signingKeyOption = new SignKeyOptionWithKeychain( + SIGN_KEY_IDENTITY, + SigningBase.StandardCertificateRequest.CODESIGN, + keychain); + + new FailedCommandErrorValidator(Pattern.compile(String.format( + "/usr/bin/codesign -s %s -vvvv --timestamp --options runtime --prefix \\S+ --keychain %s --entitlements \\S+ \\S+", + Pattern.quote(String.format("'%s'", signingKeyOption.certRequest().name())), + Pattern.quote(keychain.name()) + ))).exitCode(1).createGroup().mutate(group::add); + + MacSign.withKeychain(_ -> { // --app-content and --type app-image // Expect `message.codesign.failed.reason.app.content` message in the log. @@ -97,51 +108,49 @@ public class MacSignTest { // To make jpackage fail, specify bad additional content. JPackageCommand.helloAppImage() .ignoreDefaultVerbose(true) - .validateOutput(expectedStrings.toArray(CannedFormattedString[]::new)) + .validateOutput(group.create()) .addArguments("--app-content", appContent) .mutate(signingKeyOption::addTo) .mutate(cmd -> { if (MacHelper.isXcodeDevToolsInstalled()) { // Check there is no warning about missing xcode command line developer tools. - cmd.validateOutput(TKit.assertTextStream(xcodeWarning.getValue()).negate()); + cmd.validateOutput(xcodeWarning.copy().negate()); } }).execute(1); - }, MacSign.Keychain.UsageBuilder::addToSearchList, SigningBase.StandardKeychain.MAIN.keychain()); + }, MacSign.Keychain.UsageBuilder::addToSearchList, keychain); } @Test - public static void testCodesignUnspecifiedFailure() throws IOException { - - var appImageCmd = JPackageCommand.helloAppImage().setFakeRuntime(); - - appImageCmd.executeIgnoreExitCode().assertExitCodeIsZero(); + public static void testCodesignUnspecificFailure() throws IOException { // This test expects jpackage to respond in a specific way on a codesign failure. - // The simplest option to trigger codesign failure is to request the signing of an invalid bundle. - // Create app content directory with the name known to fail signing. - final var appContent = appImageCmd.appLayout().contentDirectory().resolve("foo.1"); - Files.createDirectory(appContent); - Files.createFile(appContent.resolve("file")); + // There are a few ways to make jpackage fail signing. One is using an erroneous + // combination of a signing key and a keychain. - final List expectedStrings = new ArrayList<>(); - expectedStrings.add(JPackageStringBundle.MAIN.cannedFormattedString("error.tool.failed.with.output", "codesign")); + var signingKeyOption = new SignKeyOption( + SIGN_KEY_IDENTITY, + SigningBase.StandardCertificateRequest.CODESIGN_ACME_TECH_LTD.certRequest( + SigningBase.StandardKeychain.MAIN.keychain())); MacSign.withKeychain(keychain -> { - var signingKeyOption = new SignKeyOptionWithKeychain( - SIGN_KEY_IDENTITY, - SigningBase.StandardCertificateRequest.CODESIGN, - keychain); + // Build a matcher for jpackage's failed command output. + var errorValidator = new FailedCommandErrorValidator(Pattern.compile(String.format( + "/usr/bin/codesign -s %s -vvvv --timestamp --options runtime --prefix \\S+ --keychain %s", + Pattern.quote(String.format("'%s'", signingKeyOption.certRequest().name())), + Pattern.quote(keychain.name()) + ))).exitCode(1).output(String.format("%s: no identity found", signingKeyOption.certRequest().name())).createGroup(); - new JPackageCommand().setPackageType(PackageType.IMAGE) + JPackageCommand.helloAppImage() + .setFakeRuntime() .ignoreDefaultVerbose(true) - .validateOutput(expectedStrings.toArray(CannedFormattedString[]::new)) - .addArguments("--app-image", appImageCmd.outputBundle()) + .validateOutput(errorValidator.create()) .mutate(signingKeyOption::addTo) + .mutate(MacHelper.useKeychain(keychain)) .execute(1); - }, MacSign.Keychain.UsageBuilder::addToSearchList, SigningBase.StandardKeychain.MAIN.keychain()); + }, MacSign.Keychain.UsageBuilder::addToSearchList, SigningBase.StandardKeychain.DUPLICATE.keychain()); } @Test diff --git a/test/langtools/ProblemList-StaticJdk.txt b/test/langtools/ProblemList-StaticJdk.txt index 70f0438c0c6..700099656e8 100644 --- a/test/langtools/ProblemList-StaticJdk.txt +++ b/test/langtools/ProblemList-StaticJdk.txt @@ -1,6 +1,6 @@ ########################################################################### # -# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. # 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,3 +24,16 @@ ########################################################################### # Currently empty + +############################################################################# + +# Preview project specific failures go here at the end of the file. +# +# These are NOT failures that occur with the '--enable-preview' option +# specified; those go in the appropriate ProblemList-enable-preview.txt file. +# These are failures that occur WITHOUT the '--enable-preview' option +# specified AND occur because of some issue with preview project code, +# in either implementation or test code. + +############################################################################# + diff --git a/test/langtools/ProblemList-enable-preview.txt b/test/langtools/ProblemList-enable-preview.txt new file mode 100644 index 00000000000..1a831a0dde3 --- /dev/null +++ b/test/langtools/ProblemList-enable-preview.txt @@ -0,0 +1,32 @@ +# +# Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. +# 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. +# + +############################################################################# +# +# List of quarantined tests for testing with --enable-preview +# +# These are failures that ONLY occur with the '--enable-preview' option +# specified. There are separate sub-sections for each preview project. +# +############################################################################# + diff --git a/test/langtools/ProblemList.txt b/test/langtools/ProblemList.txt index 9d61a20663d..07ab6937c07 100644 --- a/test/langtools/ProblemList.txt +++ b/test/langtools/ProblemList.txt @@ -1,6 +1,6 @@ ########################################################################### # -# Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. # 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,3 +71,16 @@ tools/javap/output/RepeatingTypeAnnotations.java ########################################################################### # # jdeps + +############################################################################# + +# Preview project specific failures go here at the end of the file. +# +# These are NOT failures that occur with the '--enable-preview' option +# specified; those go in the appropriate ProblemList-enable-preview.txt file. +# These are failures that occur WITHOUT the '--enable-preview' option +# specified AND occur because of some issue with preview project code, +# in either implementation or test code. + +############################################################################# + diff --git a/test/langtools/jdk/javadoc/doclet/checkStylesheetClasses/CheckStylesheetClasses.java b/test/langtools/jdk/javadoc/doclet/checkStylesheetClasses/CheckStylesheetClasses.java index ee1fa538a57..6740bace528 100644 --- a/test/langtools/jdk/javadoc/doclet/checkStylesheetClasses/CheckStylesheetClasses.java +++ b/test/langtools/jdk/javadoc/doclet/checkStylesheetClasses/CheckStylesheetClasses.java @@ -122,7 +122,7 @@ public class CheckStylesheetClasses { "modifiers", "permits", "return-type"); // misc: these are defined in HtmlStyle, and used by the doclet - removeAll(htmlStyleNames, "col-plain", "external-link", "header", "index", + removeAll(htmlStyleNames, "col-plain", "external-link", "header", "package-uses", "packages", "permits-note", "serialized-package-container", "source-container"); diff --git a/test/langtools/jdk/jshell/SnippetHighlightTest.java b/test/langtools/jdk/jshell/SnippetHighlightTest.java index dbf3418af83..33f7f263617 100644 --- a/test/langtools/jdk/jshell/SnippetHighlightTest.java +++ b/test/langtools/jdk/jshell/SnippetHighlightTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8274148 8301580 8359497 + * @bug 8274148 8301580 8359497 8374293 * @summary Check snippet highlighting * @library /tools/lib * @modules jdk.compiler/com.sun.tools.javac.api @@ -122,6 +122,13 @@ public class SnippetHighlightTest extends KullaTesting { """); } + @Test // 8374293: The returned Highlights should not overlap + public void testHighlightsOverlap() { + assertHighlights("public void E test()", "Highlight[start=0, end=6, attributes=[KEYWORD]]", + "Highlight[start=7, end=11, attributes=[KEYWORD]]", + "Highlight[start=14, end=18, attributes=[DECLARATION]]"); + } + private void assertHighlights(String code, String... expected) { List completions = computeHighlights(code); assertEquals(Arrays.asList(expected), completions, "Input: " + code + ", " + completions.toString()); @@ -134,7 +141,6 @@ public class SnippetHighlightTest extends KullaTesting { getAnalysis().highlights(code); return highlights.stream() .map(h -> h.toString()) - .distinct() .collect(Collectors.toList()); } } diff --git a/test/langtools/lib/combo/tools/javac/combo/JavacTemplateTestBase.java b/test/langtools/lib/combo/tools/javac/combo/JavacTemplateTestBase.java index 02c94b589c8..dd3f5639c21 100644 --- a/test/langtools/lib/combo/tools/javac/combo/JavacTemplateTestBase.java +++ b/test/langtools/lib/combo/tools/javac/combo/JavacTemplateTestBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -246,7 +246,8 @@ public abstract class JavacTemplateTestBase { return destDir; } else { - ct.analyze(); + ct.call(); + // Failed result will show up in diags return nullDir; } } diff --git a/test/langtools/tools/javac/6304921/TestLog.java b/test/langtools/tools/javac/6304921/TestLog.java index 8f00a14b9e2..9d0219accf1 100644 --- a/test/langtools/tools/javac/6304921/TestLog.java +++ b/test/langtools/tools/javac/6304921/TestLog.java @@ -42,7 +42,6 @@ import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.parser.Parser; import com.sun.tools.javac.parser.ParserFactory; import com.sun.tools.javac.resources.CompilerProperties.Warnings; -import com.sun.tools.javac.tree.EndPosTable; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.TreeScanner; import com.sun.tools.javac.util.Context; @@ -96,9 +95,8 @@ public class TestLog CharSequence cs = fo.getCharContent(true); Parser parser = pfac.newParser(cs, false, genEndPos, false); JCTree.JCCompilationUnit tree = parser.parseCompilationUnit(); - log.setEndPosTable(fo, tree.endPositions); - TreeScanner ts = new LogTester(log, tree.endPositions); + TreeScanner ts = new LogTester(log); ts.scan(tree); check(log.nerrors, 4, "errors"); @@ -117,9 +115,8 @@ public class TestLog } private static class LogTester extends TreeScanner { - LogTester(Log log, EndPosTable endPosTable) { + LogTester(Log log) { this.log = log; - this.endPosTable = endPosTable; } public void visitIf(JCTree.JCIf tree) { @@ -138,7 +135,6 @@ public class TestLog } private Log log; - private EndPosTable endPosTable; } private static class StringJavaFileObject extends SimpleJavaFileObject { diff --git a/test/langtools/tools/javac/diags/DiagnosticGetEndPosition.java b/test/langtools/tools/javac/diags/DiagnosticGetEndPosition.java index 1835cd46167..160f358f32f 100644 --- a/test/langtools/tools/javac/diags/DiagnosticGetEndPosition.java +++ b/test/langtools/tools/javac/diags/DiagnosticGetEndPosition.java @@ -118,9 +118,16 @@ public class DiagnosticGetEndPosition { compiler.getTask( null, null, - d -> assertEquals("", //ideally would be "0", but the positions are not fully set yet - implCode.substring((int) d.getStartPosition(), - (int) d.getEndPosition())), + d -> { + // Use line and column instead of start and end positions + // to handle platform-dependent newlines, which could be + // different between the text block and the written file. + int line = (int) d.getLineNumber(); + int col = (int) d.getColumnNumber(); + assertEquals(1, d.getEndPosition() - d.getStartPosition()); + String substring = implCode.split("\\R")[line - 1].substring(col - 1, col); + assertEquals("0", substring); + }, List.of("-sourcepath", src.toString(), "-Xlint:divzero"), null, fm.getJavaFileObjects(src.resolve("test").resolve("Test.java")) diff --git a/test/langtools/tools/javac/diags/examples/BindingPattern.java b/test/langtools/tools/javac/diags/examples/BindingPattern.java new file mode 100644 index 00000000000..01913a47fd7 --- /dev/null +++ b/test/langtools/tools/javac/diags/examples/BindingPattern.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.err.not.exhaustive.details +// key: compiler.misc.binding.pattern + +class BindingPattern { + int t(Object o) { + return switch (o) { + case String s -> 0; + }; + } +} diff --git a/test/langtools/tools/javac/diags/examples/EnumConstantPattern.java b/test/langtools/tools/javac/diags/examples/EnumConstantPattern.java new file mode 100644 index 00000000000..b2ab5b9028d --- /dev/null +++ b/test/langtools/tools/javac/diags/examples/EnumConstantPattern.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.err.not.exhaustive.details +// key: compiler.misc.enum.constant.pattern + +class NotExhaustiveDetails { + int t(I i) { + return switch (i) { + case R r -> -1; + case E.A -> -1; + }; + } + sealed interface I {} + enum E implements I {A, B} + record R(E e) implements I {} +} diff --git a/test/langtools/tools/javac/diags/examples/NotExhaustive.java b/test/langtools/tools/javac/diags/examples/NotExhaustive.java index 8d36b013677..f048755ec79 100644 --- a/test/langtools/tools/javac/diags/examples/NotExhaustive.java +++ b/test/langtools/tools/javac/diags/examples/NotExhaustive.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,6 +22,7 @@ */ // key: compiler.err.not.exhaustive +// options: -XDexhaustivityMaxBaseChecks=0 class NotExhaustive { int t(int i) { diff --git a/test/langtools/tools/javac/diags/examples/NotExhaustiveStatement.java b/test/langtools/tools/javac/diags/examples/NotExhaustiveStatement.java index 65a11abb0e6..49e4955cbdb 100644 --- a/test/langtools/tools/javac/diags/examples/NotExhaustiveStatement.java +++ b/test/langtools/tools/javac/diags/examples/NotExhaustiveStatement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,6 +22,7 @@ */ // key: compiler.err.not.exhaustive.statement +// options: -XDexhaustivityMaxBaseChecks=0 class NotExhaustive { void t(Object o) { diff --git a/test/langtools/tools/javac/diags/examples/RecordPattern.java b/test/langtools/tools/javac/diags/examples/RecordPattern.java new file mode 100644 index 00000000000..2bb43bfd800 --- /dev/null +++ b/test/langtools/tools/javac/diags/examples/RecordPattern.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.err.not.exhaustive.statement.details +// key: compiler.misc.record.pattern + +class RecordPattern { + void t(R r) { + switch (r) { + case R(C1 _) -> {} + }; + } + sealed interface I {} + record C1() implements I {} + record C2() implements I {} + record R(I i) {} +} diff --git a/test/langtools/tools/javac/failover/CheckAttributedTree.java b/test/langtools/tools/javac/failover/CheckAttributedTree.java index 9b28d2bebd4..050a302bc6e 100644 --- a/test/langtools/tools/javac/failover/CheckAttributedTree.java +++ b/test/langtools/tools/javac/failover/CheckAttributedTree.java @@ -92,7 +92,6 @@ import com.sun.source.util.TaskEvent.Kind; import com.sun.source.util.TaskListener; import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Type; -import com.sun.tools.javac.tree.EndPosTable; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCBreak; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; @@ -367,8 +366,7 @@ public class CheckAttributedTree { private class NPETester extends TreeScanner { void test(JCCompilationUnit cut, JCTree tree) { sourcefile = cut.sourcefile; - endPosTable = cut.endPositions; - encl = new Info(tree, endPosTable); + encl = new Info(tree); tree.accept(this); } @@ -379,7 +377,7 @@ public class CheckAttributedTree { return; } - Info self = new Info(tree, endPosTable); + Info self = new Info(tree); if (mandatoryType(tree)) { check(tree.type != null, "'null' field 'type' found in tree ", self); @@ -454,7 +452,6 @@ public class CheckAttributedTree { } JavaFileObject sourcefile; - EndPosTable endPosTable; Info encl; } } @@ -498,12 +495,12 @@ public class CheckAttributedTree { end = Integer.MAX_VALUE; } - Info(JCTree tree, EndPosTable endPosTable) { + Info(JCTree tree) { this.tree = tree; tag = tree.getTag(); start = TreeInfo.getStartPos(tree); pos = tree.pos; - end = TreeInfo.getEndPos(tree, endPosTable); + end = TreeInfo.getEndPos(tree); } @Override diff --git a/test/jdk/javax/sql/rowset/serial/SerialClob/SetCharacterStream.java b/test/langtools/tools/javac/lint/AssignShift64Bits.java similarity index 63% rename from test/jdk/javax/sql/rowset/serial/SerialClob/SetCharacterStream.java rename to test/langtools/tools/javac/lint/AssignShift64Bits.java index be861e43723..bb889d09022 100644 --- a/test/jdk/javax/sql/rowset/serial/SerialClob/SetCharacterStream.java +++ b/test/langtools/tools/javac/lint/AssignShift64Bits.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -19,24 +19,18 @@ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. - */ -import javax.sql.rowset.serial.SerialClob; -import javax.sql.rowset.serial.SerialException; - -/** + * * @test - * @bug 7077451 - * @summary tests if the correct exception is thrown when calling method setCharacterStream() on SerialClob + * @bug 8371162 + * @summary Verify no lossy conversion warning for 64 bit shift amount + * @compile -Xlint:lossy-conversions -Werror AssignShift64Bits.java */ -public class SetCharacterStream { - public static void main(String[] args) throws Exception { - SerialClob clob = new SerialClob(new char[0]); - try { - clob.setCharacterStream(0); - } catch (SerialException e) { - System.out.println("Test PASSED"); - } +public class AssignShift64Bits { + void m() { + int a = 1 << 1L; + a <<= 1L; + long b = 1 << 1L; + b <<= 1L; } - } diff --git a/test/langtools/tools/javac/lint/ShiftOutOfRange.out b/test/langtools/tools/javac/lint/ShiftOutOfRange.out index 7aee0b014af..6942e7e6809 100644 --- a/test/langtools/tools/javac/lint/ShiftOutOfRange.out +++ b/test/langtools/tools/javac/lint/ShiftOutOfRange.out @@ -1,17 +1,13 @@ ShiftOutOfRange.java:14:18: compiler.warn.bit.shift.out.of.range: int, -32, 0 ShiftOutOfRange.java:15:18: compiler.warn.bit.shift.out.of.range: int, -32, 0 ShiftOutOfRange.java:16:19: compiler.warn.bit.shift.out.of.range: int, -32, 0 -ShiftOutOfRange.java:17:15: compiler.warn.possible.loss.of.precision: long, int ShiftOutOfRange.java:17:15: compiler.warn.bit.shift.out.of.range: int, -32, 0 ShiftOutOfRange.java:18:15: compiler.warn.bit.shift.out.of.range: int, -32, 0 ShiftOutOfRange.java:19:16: compiler.warn.bit.shift.out.of.range: int, -32, 0 -ShiftOutOfRange.java:25:15: compiler.warn.possible.loss.of.precision: long, int -ShiftOutOfRange.java:32:15: compiler.warn.possible.loss.of.precision: long, int ShiftOutOfRange.java:39:18: compiler.warn.bit.shift.out.of.range: int, 32, 0 ShiftOutOfRange.java:40:18: compiler.warn.bit.shift.out.of.range: int, 32, 0 ShiftOutOfRange.java:41:19: compiler.warn.bit.shift.out.of.range: int, 32, 0 ShiftOutOfRange.java:42:15: compiler.warn.bit.shift.out.of.range: int, 32, 0 -ShiftOutOfRange.java:43:15: compiler.warn.possible.loss.of.precision: long, int ShiftOutOfRange.java:43:15: compiler.warn.bit.shift.out.of.range: int, 32, 0 ShiftOutOfRange.java:44:16: compiler.warn.bit.shift.out.of.range: int, 32, 0 ShiftOutOfRange.java:51:18: compiler.warn.bit.shift.out.of.range: long, -64, 0 @@ -26,4 +22,4 @@ ShiftOutOfRange.java:78:19: compiler.warn.bit.shift.out.of.range: long, 64, 0 ShiftOutOfRange.java:79:15: compiler.warn.bit.shift.out.of.range: long, 64, 0 ShiftOutOfRange.java:80:15: compiler.warn.bit.shift.out.of.range: long, 64, 0 ShiftOutOfRange.java:81:16: compiler.warn.bit.shift.out.of.range: long, 64, 0 -28 warnings +24 warnings diff --git a/test/langtools/tools/javac/parser/DeclarationEndPositions.java b/test/langtools/tools/javac/parser/DeclarationEndPositions.java index 226b77769d1..c61a92e80cd 100644 --- a/test/langtools/tools/javac/parser/DeclarationEndPositions.java +++ b/test/langtools/tools/javac/parser/DeclarationEndPositions.java @@ -78,7 +78,7 @@ public class DeclarationEndPositions { throw new AssertionError(String.format( "wrong %s pos %d for \"%s\" in \"%s\"", "start", start, tree, input)); } - int end = TreeInfo.getEndPos(tree, unit.endPositions); + int end = TreeInfo.getEndPos(tree); if (markers.charAt(end - 1) != '>') { throw new AssertionError(String.format( "wrong %s pos %d for \"%s\" in \"%s\"", "end", end, tree, input)); diff --git a/test/langtools/tools/javac/parser/ReversedSourcePositions.java b/test/langtools/tools/javac/parser/ReversedSourcePositions.java index d092d23d8c1..6596430dca5 100644 --- a/test/langtools/tools/javac/parser/ReversedSourcePositions.java +++ b/test/langtools/tools/javac/parser/ReversedSourcePositions.java @@ -72,7 +72,7 @@ public class ReversedSourcePositions { public Void scan(Tree node, Void aVoid) { if (node instanceof JCTree tree) { int start = tree.getStartPosition(); - int end = tree.getEndPosition(unit.endPositions); + int end = tree.getEndPosition(); if (start >= end) { throw new AssertionError( String.format("[%d, %d] %s %s\n", start, end, tree.getKind(), tree)); diff --git a/test/langtools/tools/javac/parser/extend/TrialParser.java b/test/langtools/tools/javac/parser/extend/TrialParser.java index c9a858fbc47..ca4e3995bc3 100644 --- a/test/langtools/tools/javac/parser/extend/TrialParser.java +++ b/test/langtools/tools/javac/parser/extend/TrialParser.java @@ -66,9 +66,8 @@ class TrialParser extends JavacParser { public TrialParser(ParserFactory fac, com.sun.tools.javac.parser.Lexer S, boolean keepDocComments, - boolean keepLineMap, - boolean keepEndPositions) { - super(fac, S, keepDocComments, keepLineMap, keepEndPositions); + boolean keepLineMap) { + super(fac, S, keepDocComments, keepLineMap); } @Override @@ -102,7 +101,7 @@ class TrialParser extends JavacParser { boolean firstTypeDecl = true; while (token.kind != EOF) { - if (token.pos > 0 && token.pos <= endPosTable.errorEndPos) { + if (token.pos > 0 && token.pos <= errorEndPos) { // error recovery skip(true, false, false, false); if (token.kind == EOF) { @@ -139,7 +138,6 @@ class TrialParser extends JavacParser { storeEnd(toplevel, S.prevToken().endPos); } toplevel.lineMap = S.getLineMap(); - toplevel.endPositions = this.endPosTable; return toplevel; } diff --git a/test/langtools/tools/javac/parser/extend/TrialParserFactory.java b/test/langtools/tools/javac/parser/extend/TrialParserFactory.java index 6ac4c60d279..6f62175c82a 100644 --- a/test/langtools/tools/javac/parser/extend/TrialParserFactory.java +++ b/test/langtools/tools/javac/parser/extend/TrialParserFactory.java @@ -48,13 +48,8 @@ class TrialParserFactory extends ParserFactory { } @Override - public JavacParser newParser(CharSequence input, boolean keepDocComments, boolean keepEndPos, boolean keepLineMap) { + public JavacParser newParser(CharSequence input, boolean keepDocComments, boolean keepLineMap, boolean parseModuleInfo) { com.sun.tools.javac.parser.Lexer lexer = scannerFactory.newScanner(input, keepDocComments); - return new TrialParser(this, lexer, keepDocComments, keepLineMap, keepEndPos); - } - - @Override - public JavacParser newParser(CharSequence input, boolean keepDocComments, boolean keepEndPos, boolean keepLineMap, boolean parseModuleInfo) { - return newParser(input, keepDocComments, keepEndPos, keepLineMap); + return new TrialParser(this, lexer, keepDocComments, keepLineMap); } } diff --git a/test/langtools/tools/javac/patterns/DeconstructionPatternErrors.java b/test/langtools/tools/javac/patterns/DeconstructionPatternErrors.java index 4e1a7d7f669..804c2a3f622 100644 --- a/test/langtools/tools/javac/patterns/DeconstructionPatternErrors.java +++ b/test/langtools/tools/javac/patterns/DeconstructionPatternErrors.java @@ -1,5 +1,6 @@ /** * @test /nodynamiccopyright/ + * @bug 8375571 * @summary Verify error reports for erroneous deconstruction patterns are sensible * @compile/fail/ref=DeconstructionPatternErrors.out -XDrawDiagnostics -XDshould-stop.at=FLOW -XDdev DeconstructionPatternErrors.java */ @@ -39,6 +40,10 @@ public class DeconstructionPatternErrors { boolean b = p instanceof P(int i) p; //introducing a variable for the record pattern } + void typeVarTest(T p) { + if (p instanceof T(int i) && i == 0); //T is a type variable + } + public record P(int i) { } diff --git a/test/langtools/tools/javac/patterns/DeconstructionPatternErrors.out b/test/langtools/tools/javac/patterns/DeconstructionPatternErrors.out index f947142cd66..4d21d6069d8 100644 --- a/test/langtools/tools/javac/patterns/DeconstructionPatternErrors.out +++ b/test/langtools/tools/javac/patterns/DeconstructionPatternErrors.out @@ -1,23 +1,24 @@ -DeconstructionPatternErrors.java:35:37: compiler.err.illegal.start.of.type -DeconstructionPatternErrors.java:37:28: compiler.err.illegal.start.of.type -DeconstructionPatternErrors.java:39:42: compiler.err.expected: ';' -DeconstructionPatternErrors.java:39:43: compiler.err.not.stmt -DeconstructionPatternErrors.java:15:29: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.util.List, java.util.ArrayList) -DeconstructionPatternErrors.java:16:29: compiler.err.instanceof.reifiable.not.safe: java.lang.Object, java.util.ArrayList -DeconstructionPatternErrors.java:17:29: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, int) -DeconstructionPatternErrors.java:18:28: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: int, java.lang.String) -DeconstructionPatternErrors.java:19:29: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, DeconstructionPatternErrors.P) -DeconstructionPatternErrors.java:20:26: compiler.err.incorrect.number.of.nested.patterns: java.lang.Runnable,java.lang.Runnable, java.lang.Runnable +DeconstructionPatternErrors.java:36:37: compiler.err.illegal.start.of.type +DeconstructionPatternErrors.java:38:28: compiler.err.illegal.start.of.type +DeconstructionPatternErrors.java:40:42: compiler.err.expected: ';' +DeconstructionPatternErrors.java:40:43: compiler.err.not.stmt +DeconstructionPatternErrors.java:16:29: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.util.List, java.util.ArrayList) +DeconstructionPatternErrors.java:17:29: compiler.err.instanceof.reifiable.not.safe: java.lang.Object, java.util.ArrayList +DeconstructionPatternErrors.java:18:29: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, int) +DeconstructionPatternErrors.java:19:28: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: int, java.lang.String) +DeconstructionPatternErrors.java:20:29: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, DeconstructionPatternErrors.P) DeconstructionPatternErrors.java:21:26: compiler.err.incorrect.number.of.nested.patterns: java.lang.Runnable,java.lang.Runnable, java.lang.Runnable -DeconstructionPatternErrors.java:22:26: compiler.err.incorrect.number.of.nested.patterns: int, int,compiler.misc.type.none -DeconstructionPatternErrors.java:23:26: compiler.err.incorrect.number.of.nested.patterns: int, int,int -DeconstructionPatternErrors.java:24:36: compiler.err.cant.resolve.location: kindname.class, Unresolvable, , , (compiler.misc.location: kindname.class, DeconstructionPatternErrors, null) -DeconstructionPatternErrors.java:24:26: compiler.err.incorrect.number.of.nested.patterns: int, int,Unresolvable -DeconstructionPatternErrors.java:25:13: compiler.err.instanceof.reifiable.not.safe: java.lang.Object, DeconstructionPatternErrors.GenRecord -DeconstructionPatternErrors.java:26:29: compiler.err.instanceof.reifiable.not.safe: java.lang.Object, DeconstructionPatternErrors.GenRecord -DeconstructionPatternErrors.java:27:44: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Integer) -DeconstructionPatternErrors.java:27:13: compiler.err.instanceof.reifiable.not.safe: java.lang.Object, DeconstructionPatternErrors.GenRecord -DeconstructionPatternErrors.java:28:40: compiler.err.match.binding.exists -DeconstructionPatternErrors.java:29:56: compiler.err.already.defined: kindname.variable, v1, kindname.method, meth() -DeconstructionPatternErrors.java:29:64: compiler.err.already.defined: kindname.variable, v2, kindname.method, meth() -22 errors \ No newline at end of file +DeconstructionPatternErrors.java:22:26: compiler.err.incorrect.number.of.nested.patterns: java.lang.Runnable,java.lang.Runnable, java.lang.Runnable +DeconstructionPatternErrors.java:23:26: compiler.err.incorrect.number.of.nested.patterns: int, int,compiler.misc.type.none +DeconstructionPatternErrors.java:24:26: compiler.err.incorrect.number.of.nested.patterns: int, int,int +DeconstructionPatternErrors.java:25:36: compiler.err.cant.resolve.location: kindname.class, Unresolvable, , , (compiler.misc.location: kindname.class, DeconstructionPatternErrors, null) +DeconstructionPatternErrors.java:25:26: compiler.err.incorrect.number.of.nested.patterns: int, int,Unresolvable +DeconstructionPatternErrors.java:26:13: compiler.err.instanceof.reifiable.not.safe: java.lang.Object, DeconstructionPatternErrors.GenRecord +DeconstructionPatternErrors.java:27:29: compiler.err.instanceof.reifiable.not.safe: java.lang.Object, DeconstructionPatternErrors.GenRecord +DeconstructionPatternErrors.java:28:44: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Integer) +DeconstructionPatternErrors.java:28:13: compiler.err.instanceof.reifiable.not.safe: java.lang.Object, DeconstructionPatternErrors.GenRecord +DeconstructionPatternErrors.java:29:40: compiler.err.match.binding.exists +DeconstructionPatternErrors.java:30:56: compiler.err.already.defined: kindname.variable, v1, kindname.method, meth() +DeconstructionPatternErrors.java:30:64: compiler.err.already.defined: kindname.variable, v2, kindname.method, meth() +DeconstructionPatternErrors.java:44:26: compiler.err.deconstruction.pattern.only.records: T +23 errors diff --git a/test/langtools/tools/javac/patterns/Exhaustiveness.java b/test/langtools/tools/javac/patterns/Exhaustiveness.java index 84e67855b3b..f1809e99e45 100644 --- a/test/langtools/tools/javac/patterns/Exhaustiveness.java +++ b/test/langtools/tools/javac/patterns/Exhaustiveness.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2523,6 +2523,7 @@ public class Exhaustiveness extends TestRunner { "-Xlint:-preview", "--class-path", libClasses.toString(), "-XDshould-stop.at=FLOW", + "-XDexhaustivityMaxBaseChecks=0", stopAtFlow ? "-XDshould-stop.ifNoError=FLOW" : "-XDnoop") .outdir(classes) diff --git a/test/langtools/tools/javac/patterns/ExhaustivenessConvenientErrors.java b/test/langtools/tools/javac/patterns/ExhaustivenessConvenientErrors.java new file mode 100644 index 00000000000..6935fcfa006 --- /dev/null +++ b/test/langtools/tools/javac/patterns/ExhaustivenessConvenientErrors.java @@ -0,0 +1,593 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8367530 + * @summary Check enhanced exhaustiveness errors + * @library /tools/lib + * @modules jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.main + * jdk.compiler/com.sun.tools.javac.util + * @build toolbox.ToolBox toolbox.JavacTask + * @run main ExhaustivenessConvenientErrors +*/ + +import com.sun.tools.javac.api.ClientCodeWrapper.DiagnosticSourceUnwrapper; +import com.sun.tools.javac.util.JCDiagnostic; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import toolbox.JavacTask; +import toolbox.Task; +import toolbox.TestRunner; +import toolbox.ToolBox; + +public class ExhaustivenessConvenientErrors extends TestRunner { + + ToolBox tb; + + public static void main(String... args) throws Exception { + new ExhaustivenessConvenientErrors().runTests(); + } + + ExhaustivenessConvenientErrors() { + super(System.err); + tb = new ToolBox(); + } + + public void runTests() throws Exception { + runTests(m -> new Object[] { Paths.get(m.getName()) }); + } + + @Test + public void testExhaustiveSealedClasses(Path base) throws Exception { + doTest(base, + new String[]{""" + package lib; + public sealed interface S permits A, B {} + """, + """ + package lib; + public final class A implements S {} + """, + """ + package lib; + public final class B implements S {} + """}, + """ + package test; + import lib.*; + public class Test { + private int test(S obj) { + return switch (obj) { + case A a -> 0; + }; + } + } + """, + "lib.B _"); + } + + @Test + public void testExhaustiveSealedClassesTransitive(Path base) throws Exception { + doTest(base, + new String[]{""" + package lib; + public sealed interface S1 permits S2, A {} + """, + """ + package lib; + public sealed interface S2 extends S1 permits S3, B {} + """, + """ + package lib; + public sealed interface S3 extends S2 permits C, D {} + """, + """ + package lib; + public final class A implements S1 {} + """, + """ + package lib; + public final class B implements S2 {} + """, + """ + package lib; + public final class C implements S3 {} + """, + """ + package lib; + public final class D implements S3 {} + """}, + """ + package test; + import lib.*; + public class Test { + private int test(S1 obj) { + return switch (obj) { + case A a -> 0; + case B a -> 0; + case D a -> 0; + }; + } + } + """, + "lib.C _"); + } + + @Test + public void testTrivialRecord(Path base) throws Exception { + doTest(base, + new String[]{""" + package lib; + public sealed interface S permits A, B {} + """, + """ + package lib; + public final class A implements S {} + """, + """ + package lib; + public final class B implements S {} + """, + """ + package lib; + public record R(S s) {} + """}, + """ + package test; + import lib.*; + public class Test { + private int test(R r) { + return switch (r) { + case R(A a) -> 0; + }; + } + } + """, + "lib.R(lib.B _)"); + } + + @Test + public void testNonNestedRecord(Path base) throws Exception { + doTest(base, + new String[]{""" + package lib; + public sealed interface S permits A, B {} + """, + """ + package lib; + public final class A implements S {} + """, + """ + package lib; + public final class B implements S {} + """, + """ + package lib; + public record R(S s1, S s2) {} + """}, + """ + package test; + import lib.*; + public class Test { + private int test(R r) { + return switch (r) { + case R(A a, B b) -> 0; + case R(B b, A a) -> 0; + }; + } + } + """, + "lib.R(lib.A _,lib.A _)", + "lib.R(lib.B _,lib.B _)"); + } + + @Test + public void testComplex1(Path base) throws Exception { + doTest(base, + new String[0], + """ + package test; + import lib.*; + public class Test { + private int test(Root r) { + return switch (r) { + case Root(R1 _, _, _) -> 0; + }; + } + sealed interface Base {} + record R1() implements Base {} + record R2() implements Base {} + record R3(Base b1, Base b2) implements Base {} + record Root(Base b1, Base b2, Base b3) {} + } + """, + "test.Test.Root(test.Test.R2 _,test.Test.Base _,test.Test.Base _)", + "test.Test.Root(test.Test.R3 _,test.Test.Base _,test.Test.Base _)"); + } + + @Test + public void testComplex2(Path base) throws Exception { + doTest(base, + new String[0], + """ + package test; + import lib.*; + public class Test { + private int test(Root r) { + return switch (r) { + case Root(R1 _, _, _) -> 0; + case Root(R2 _, R1 _, _) -> 0; + case Root(R2 _, R2 _, R1 _) -> 0; + case Root(R2 _, R2(R1 _, R1 _), R2(R1 _, R1 _)) -> 0; + case Root(R2 _, R2(R1 _, R1 _), R2(R1 _, R2 _)) -> 0; + case Root(R2 _, R2(R1 _, R1 _), R2(R2 _, R1 _)) -> 0; + case Root(R2 _, R2(R1 _, R1 _), R2(R2 _, R2 _)) -> 0; + case Root(R2 _, R2(R1 _, R2 _), R2(R1 _, R1 _)) -> 0; + case Root(R2 _, R2(R1 _, R2 _), R2(R1 _, R2 _)) -> 0; + case Root(R2 _, R2(R1 _, R2 _), R2(R2 _, R1 _)) -> 0; + case Root(R2 _, R2(R1 _, R2 _), R2(R2 _, R2 _)) -> 0; + case Root(R2 _, R2(R2 _, R1 _), R2(R1 _, R1 _)) -> 0; + case Root(R2 _, R2(R2 _, R1 _), R2(R1 _, R2 _)) -> 0; + case Root(R2 _, R2(R2 _, R1 _), R2(R2 _, R1 _)) -> 0; + case Root(R2 _, R2(R2 _, R1 _), R2(R2 _, R2 _)) -> 0; + case Root(R2 _, R2(R2 _, R2 _), R2(R1 _, R1 _)) -> 0; + case Root(R2 _, R2(R2 _, R2 _), R2(R1 _, R2 _)) -> 0; + case Root(R2 _, R2(R2 _, R2 _), R2(R2 _, R1 _)) -> 0; +// case Root(R2 _, R2(R2 _, R2 _), R2(R2 _, R2 _)) -> 0; + }; + } + sealed interface Base {} + record R1() implements Base {} + record R2(Base b1, Base b2) implements Base {} + record Root(Base b1, Base b2, Base b3) {} + } + """, + "test.Test.Root(test.Test.R2 _,test.Test.R2(test.Test.R2 _,test.Test.R2 _),test.Test.R2(test.Test.R2 _,test.Test.R2 _))"); + } + + @Test + public void testComplex3(Path base) throws Exception { + doTest(base, + new String[0], + """ + package test; + public class Test { + private int test(Triple p) { + return switch (p) { + case Triple(B _, _, _) -> 0; + case Triple(_, A _, _) -> 0; + case Triple(_, _, A _) -> 0; + case Triple(A p, C(Nested _, NestedBaseA _), _) -> 0; + case Triple(A p, C(Nested _, NestedBaseB _), C(Nested _, NestedBaseA _)) -> 0; + case Triple(A p, C(Nested _, NestedBaseB _), C(Nested _, NestedBaseB _)) -> 0; + case Triple(A p, C(Nested _, NestedBaseB _), C(Nested _, NestedBaseC _)) -> 0; + case Triple(A p, C(Nested _, NestedBaseC _), C(Nested _, NestedBaseA _)) -> 0; + case Triple(A p, C(Nested _, NestedBaseC _), C(Nested _, NestedBaseB _)) -> 0; +// case Path(A p, C(Nested _, NestedBaseC _), C(Nested _, NestedBaseC _)) -> 0; + }; + } + record Triple(Base c1, Base c2, Base c3) {} + sealed interface Base permits A, B {} + record A(boolean key) implements Base { + } + sealed interface B extends Base {} + record C(Nested n, NestedBase b) implements B {} + record Nested() {} + sealed interface NestedBase {} + record NestedBaseA() implements NestedBase {} + record NestedBaseB() implements NestedBase {} + record NestedBaseC() implements NestedBase {} + } + """, + "test.Test.Triple(test.Test.A _,test.Test.C(test.Test.Nested _,test.Test.NestedBaseC _),test.Test.C(test.Test.Nested _,test.Test.NestedBaseC _))"); + } + + @Test + public void testComplex4(Path base) throws Exception { + doTest(base, + new String[0], + """ + package test; + import lib.*; + public class Test { + private int test(Root r) { + return switch (r) { + case Root(R1 _, _, _) -> 0; + case Root(R2 _, R1 _, _) -> 0; + case Root(R2 _, R2 _, R1 _) -> 0; + case Root(R2 _, R2(R1 _, R1 _), R2(R1 _, R1 _)) -> 0; + case Root(R2 _, R2(R1 _, R1 _), R2(R1 _, R2 _)) -> 0; + case Root(R2 _, R2(R1 _, R1 _), R2(R2 _, R1 _)) -> 0; + case Root(R2 _, R2(R1 _, R1 _), R2(R2 _, R2 _)) -> 0; + case Root(R2 _, R2(R1 _, R2 _), R2(R1 _, R1 _)) -> 0; + case Root(R2 _, R2(R1 _, R2 _), R2(R1 _, R2 _)) -> 0; +// case Root(R2 _, R2(R1 _, R2 _), R2(R2 _, R1 _)) -> 0; + case Root(R2 _, R2(R1 _, R2 _), R2(R2 _, R2 _)) -> 0; + case Root(R2 _, R2(R2 _, R1 _), R2(R1 _, R1 _)) -> 0; + case Root(R2 _, R2(R2 _, R1 _), R2(R1 _, R2 _)) -> 0; + case Root(R2 _, R2(R2 _, R1 _), R2(R2 _, R1 _)) -> 0; + case Root(R2 _, R2(R2 _, R1 _), R2(R2 _, R2 _)) -> 0; + case Root(R2 _, R2(R2 _, R2 _), R2(R1 _, R1 _)) -> 0; + case Root(R2 _, R2(R2 _, R2 _), R2(R1 _, R2 _)) -> 0; + case Root(R2 _, R2(R2 _, R2 _), R2(R2 _, R1 _)) -> 0; +// case Root(R2 _, R2(R2 _, R2 _), R2(R2 _, R2 _)) -> 0; + }; + } + sealed interface Base {} + record R1() implements Base {} + record R2(Base b1, Base b2) implements Base {} + record Root(Base b1, Base b2, Base b3) {} + } + """, + "test.Test.Root(test.Test.R2 _,test.Test.R2(test.Test.Base _,test.Test.R2 _),test.Test.R2(test.Test.R2 _,test.Test.Base _))"); + //ideally,the result would be as follow,but it is difficult to split Base on two distinct places: +// "test.Test.Root(test.Test.R2 _,test.Test.R2(test.Test.R1 _,test.Test.R2 _),test.Test.R2(test.Test.R2 _,test.Test.R1 _))", +// "test.Test.Root(test.Test.R2 _,test.Test.R2(test.Test.R2 _,test.Test.R2 _),test.Test.R2(test.Test.R2 _,test.Test.R2 _))"); + } + + @Test + public void testComplex5(Path base) throws Exception { + doTest(base, + new String[0], + """ + package test; + public class Test { + private int test(Triple p) { + return switch (p) { + case Triple(B _, _, _) -> 0; + case Triple(_, A _, _) -> 0; + case Triple(_, _, A _) -> 0; +// case Triple(A _, C(Nested _, NestedBaseA _), _) -> 0; + case Triple(A _, C(Nested _, NestedBaseB _), C(Nested _, NestedBaseA _)) -> 0; + case Triple(A _, C(Nested _, NestedBaseB _), C(Nested _, NestedBaseB _)) -> 0; + case Triple(A _, C(Nested _, NestedBaseB _), C(Nested _, NestedBaseC _)) -> 0; + case Triple(A _, C(Nested _, NestedBaseC _), C(Nested _, NestedBaseA _)) -> 0; + case Triple(A _, C(Nested _, NestedBaseC _), C(Nested _, NestedBaseB _)) -> 0; +// case Path(A _, C(Nested _, NestedBaseC _), C(Nested _, NestedBaseC _)) -> 0; + }; + } + record Triple(Base c1, Base c2, Base c3) {} + sealed interface Base permits A, B {} + record A(boolean key) implements Base { + } + sealed interface B extends Base {} + record C(Nested n, NestedBase b) implements B {} + record Nested() {} + sealed interface NestedBase {} + record NestedBaseA() implements NestedBase {} + record NestedBaseB() implements NestedBase {} + record NestedBaseC() implements NestedBase {} + } + """, + "test.Test.Triple(test.Test.A _,test.Test.C(test.Test.Nested _,test.Test.NestedBaseA _),test.Test.C _)", + //the following could be: + //test.Test.Triple(test.Test.A _,test.Test.C(test.Test.Nested _,test.Test.NestedBaseC _),test.Test.C(test.Test.Nested _,test.Test.NestedBaseC _)) + "test.Test.Triple(test.Test.A _,test.Test.C(test.Test.Nested _,test.Test.NestedBaseC _),test.Test.C _)"); + } + + @Test + public void testNoInfiniteRecursion(Path base) throws Exception { + doTest(base, + new String[0], + """ + package test; + public class Test { + private int test(R r) { + return switch (r) { + case R(_, _, R(_, _, _, _), String s) -> 0; + case R(_, _, R(_, _, _, String str), _) -> 0; + }; + } + } + public record R(R r1, R r2, R r3, Object o) {} + """, + "test.R(test.R _,test.R _,test.R(test.R _,test.R _,test.R _,java.lang.Object _),java.lang.Object _)"); + } + + @Test + public void testEnum(Path base) throws Exception { + doTest(base, + new String[0], + """ + package test; + public class Test { + private int test(I i) { + return switch (i) { + case E.A -> 0; + case C _ -> 1; + }; + } + sealed interface I {} + enum E implements I {A, B} + final class C implements I {} + } + public record R(R r1, R r2, R r3, Object o) {} + """, + "test.Test.E.B"); + doTest(base, + new String[0], + """ + package test; + public class Test { + private int test(I i) { + return switch (i) { + case C _ -> 1; + }; + } + sealed interface I {} + enum E implements I {A, B} + final class C implements I {} + } + public record R(R r1, R r2, R r3, Object o) {} + """, + "test.Test.E _"); + } + + @Test + public void testInstantiateComponentTypes(Path base) throws Exception { + doTest(base, + new String[0], + """ + package test; + public class Test { + private int test(Pair> p) { + return switch (p) { + case Pair(A(A(_)) -> 0; + case Pair(A(B(_)) -> 0; + case Pair(B(A(_)) -> 0; + }; + } + record Pair(T c) {} + sealed interface Base permits A, B {} + record A(T c) implements Base {} + record B(T c) implements Base {} + } + """, + "test.Test.Pair(test.Test.B(test.Test.B _))"); + } + + @Test + public void testNeedToExpandIfRecordExists(Path base) throws Exception { + doTest(base, + new String[0], + """ + package test; + class Test { + sealed interface A { } + record B() implements A { } + record C(A a) implements A { } + + void test(A a) { + switch (a) { + case C(B _) -> throw null; + } + } + } """, + "test.Test.B _", + "test.Test.C(test.Test.C _)"); + } + + @Test + public void testComplex6(Path base) throws Exception { + doTest(base, + new String[0], + """ + public class Test { + sealed interface Base {} + record NoOp() implements Base {} + record Const() implements Base {} + record Pair(Base n1, + Base b2) implements Base {} + + int t(Base b) { + return switch (b) { + case NoOp _ -> 0; + case Const _ -> 0; + case Pair(NoOp _, _) -> 0; + case Pair(Const _, _) -> 0; + case Pair(Pair _, NoOp _) -> 0; + case Pair(Pair _, Const _) -> 0; + case Pair(Pair _, Pair(NoOp _, _)) -> 0; + case Pair(Pair _, Pair(Const _, _)) -> 0; + case Pair(Pair _, Pair(Pair(NoOp _, _), _)) -> 0; + case Pair(Pair _, Pair(Pair(Const _, _), _)) -> 0; + case Pair(Pair(NoOp _, _), Pair(Pair(Pair _, _), _)) -> 0; + case Pair(Pair(Const _, _), Pair(Pair(Pair _, _), _)) -> 0; +// case Pair(Pair(Pair _, _), Pair(Pair(Pair _, _), _)) -> 0; + }; + } + } + """, + "Test.Pair(Test.Pair(Test.Pair _,Test.Base _),Test.Pair(Test.Pair(Test.Pair _,Test.Base _),Test.Base _))"); + } + + private void doTest(Path base, String[] libraryCode, String testCode, String... expectedMissingPatterns) throws IOException { + Path current = base.resolve("."); + Path libClasses = current.resolve("libClasses"); + + Files.createDirectories(libClasses); + + if (libraryCode.length != 0) { + Path libSrc = current.resolve("lib-src"); + + for (String code : libraryCode) { + tb.writeJavaFiles(libSrc, code); + } + + new JavacTask(tb) + .outdir(libClasses) + .files(tb.findJavaFiles(libSrc)) + .run(); + } + + Path src = current.resolve("src"); + tb.writeJavaFiles(src, testCode); + + Path classes = current.resolve("libClasses"); + + Files.createDirectories(libClasses); + Set missingPatterns = new HashSet<>(); + + new JavacTask(tb) + .options("-XDrawDiagnostics", + "--class-path", libClasses.toString(), + "-XDshould-stop.at=FLOW", + "-XDshould-stop.ifNoError=FLOW", + "-XDexhaustivityMaxBaseChecks=" + Long.MAX_VALUE) //never give up + .outdir(classes) + .files(tb.findJavaFiles(src)) + .diagnosticListener(d -> { + if ("compiler.err.not.exhaustive.details".equals(d.getCode()) || + "compiler.err.not.exhaustive.statement.details".equals(d.getCode())) { + if (d instanceof DiagnosticSourceUnwrapper uw) { + d = uw.d; + } + if (d instanceof JCDiagnostic.MultilineDiagnostic diag) { + diag.getSubdiagnostics() + .stream() + .map(fragment -> fragment.toString()) + .forEach(missingPatterns::add); + } + } + }) + .run(Task.Expect.FAIL) + .writeAll(); + + Set expectedPatterns = new HashSet<>(List.of(expectedMissingPatterns)); + + if (!expectedPatterns.equals(missingPatterns)) { + throw new AssertionError("Incorrect errors, expected: " + expectedPatterns + + ", actual: " + missingPatterns); + } + } + +} diff --git a/test/langtools/tools/javac/patterns/PrimitiveInstanceOfComboTest.java b/test/langtools/tools/javac/patterns/PrimitiveInstanceOfComboTest.java index 82064bd4baf..1830afeb187 100644 --- a/test/langtools/tools/javac/patterns/PrimitiveInstanceOfComboTest.java +++ b/test/langtools/tools/javac/patterns/PrimitiveInstanceOfComboTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -103,16 +103,19 @@ public class PrimitiveInstanceOfComboTest extends ComboInstance { diff --git a/test/langtools/tools/javac/patterns/PrimitivePatternsSwitchConstants.java b/test/langtools/tools/javac/patterns/PrimitivePatternsSwitchConstants.java index 2890b315e62..249cdeb2464 100644 --- a/test/langtools/tools/javac/patterns/PrimitivePatternsSwitchConstants.java +++ b/test/langtools/tools/javac/patterns/PrimitivePatternsSwitchConstants.java @@ -2,7 +2,7 @@ * @test /nodynamiccopyright/ * @summary Retain exhaustiveness properties of switches with a constant selector * @enablePreview - * @compile/fail/ref=PrimitivePatternsSwitchConstants.out -XDrawDiagnostics -XDshould-stop.at=FLOW PrimitivePatternsSwitchConstants.java + * @compile/fail/ref=PrimitivePatternsSwitchConstants.out -XDrawDiagnostics -XDshould-stop.at=FLOW -XDexhaustivityMaxBaseChecks=0 PrimitivePatternsSwitchConstants.java */ public class PrimitivePatternsSwitchConstants { void testConstExpressions() { diff --git a/test/langtools/tools/javac/patterns/PrimitivePatternsSwitchErrors.java b/test/langtools/tools/javac/patterns/PrimitivePatternsSwitchErrors.java index dacd48f441c..3eab2fc83d0 100644 --- a/test/langtools/tools/javac/patterns/PrimitivePatternsSwitchErrors.java +++ b/test/langtools/tools/javac/patterns/PrimitivePatternsSwitchErrors.java @@ -3,7 +3,7 @@ * @bug 8304487 8325653 8332463 * @summary Compiler Implementation for Primitive types in patterns, instanceof, and switch (Preview) * @enablePreview - * @compile/fail/ref=PrimitivePatternsSwitchErrors.out -XDrawDiagnostics -XDshould-stop.at=FLOW PrimitivePatternsSwitchErrors.java + * @compile/fail/ref=PrimitivePatternsSwitchErrors.out -XDrawDiagnostics -XDshould-stop.at=FLOW -XDexhaustivityMaxBaseChecks=0 PrimitivePatternsSwitchErrors.java */ public class PrimitivePatternsSwitchErrors { record R_int(int x) {} diff --git a/test/langtools/tools/javac/patterns/SwitchErrors.java b/test/langtools/tools/javac/patterns/SwitchErrors.java index 607052be583..ebff13e7fa5 100644 --- a/test/langtools/tools/javac/patterns/SwitchErrors.java +++ b/test/langtools/tools/javac/patterns/SwitchErrors.java @@ -2,7 +2,7 @@ * @test /nodynamiccopyright/ * @bug 8262891 8269146 8269113 8348928 * @summary Verify errors related to pattern switches. - * @compile/fail/ref=SwitchErrors.out -XDrawDiagnostics -XDshould-stop.at=FLOW SwitchErrors.java + * @compile/fail/ref=SwitchErrors.out -XDrawDiagnostics -XDshould-stop.at=FLOW -XDexhaustivityMaxBaseChecks=0 SwitchErrors.java */ public class SwitchErrors { diff --git a/test/langtools/tools/javac/platform/NonExportedPermittedTypes.java b/test/langtools/tools/javac/platform/NonExportedPermittedTypes.java index bdafef7e39a..9a378ce346a 100644 --- a/test/langtools/tools/javac/platform/NonExportedPermittedTypes.java +++ b/test/langtools/tools/javac/platform/NonExportedPermittedTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,9 +26,9 @@ * @bug 8318913 * @summary Verify no error is when compiling a class whose permitted types are not exported * @modules jdk.compiler - * @compile/fail/ref=NonExportedPermittedTypes.out -XDrawDiagnostics NonExportedPermittedTypes.java - * @compile/fail/ref=NonExportedPermittedTypes.out --release 21 -XDrawDiagnostics NonExportedPermittedTypes.java - * @compile/fail/ref=NonExportedPermittedTypes.out --release ${jdk.version} -XDrawDiagnostics NonExportedPermittedTypes.java + * @compile/fail/ref=NonExportedPermittedTypes.out -XDrawDiagnostics -XDexhaustivityMaxBaseChecks=0 NonExportedPermittedTypes.java + * @compile/fail/ref=NonExportedPermittedTypes.out --release 21 -XDrawDiagnostics -XDexhaustivityMaxBaseChecks=0 NonExportedPermittedTypes.java + * @compile/fail/ref=NonExportedPermittedTypes.out --release ${jdk.version} -XDrawDiagnostics -XDexhaustivityMaxBaseChecks=0 NonExportedPermittedTypes.java */ diff --git a/test/langtools/tools/javac/records/RecordCompilationTests.java b/test/langtools/tools/javac/records/RecordCompilationTests.java index 1de0ec48f0d..a8384ba4692 100644 --- a/test/langtools/tools/javac/records/RecordCompilationTests.java +++ b/test/langtools/tools/javac/records/RecordCompilationTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -335,7 +335,7 @@ class RecordCompilationTests extends CompilationTestCase { assertFail("compiler.err.invalid.accessor.method.in.record", "public record R(int x) {\n" + - " static private final j = 0;" + + " static private final int j = 0;" + " static public int x() { return j; };" + "}"); } @@ -539,10 +539,10 @@ class RecordCompilationTests extends CompilationTestCase { "record R() { void test1() { class X { U u; } } }", "interface I { default void test1() { class X { void test2() { System.err.println(localVar); } } } }", - "interface I() { default void test1() { class X { void test2() {System.err.println(param);} } } }", + "interface I { default void test1() { class X { void test2() {System.err.println(param);} } } }", "interface I { default void test1() { class X { void test2() { System.err.println(instanceField); } } } }", "interface I { default void test1() { class X { T t; } } }", - "interface I() { default void test1() { class X {U u;} } }", + "interface I { default void test1() { class X {U u;} } }", "enum E { A; void test1() { class X { void test2() { System.err.println(localVar); } } } }", "enum E { A; void test1() { class X { void test2() {System.err.println(param);} } } }", diff --git a/test/langtools/tools/javac/sealed/SealedCompilationTests.java b/test/langtools/tools/javac/sealed/SealedCompilationTests.java index 17141ee3c67..b7207b777c6 100644 --- a/test/langtools/tools/javac/sealed/SealedCompilationTests.java +++ b/test/langtools/tools/javac/sealed/SealedCompilationTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -855,12 +855,13 @@ class SealedCompilationTests extends CompilationTestCase { @Test void testSealedNonSealedWithOtherModifiers() { + // Sup must be static so Sub may be static String template1 = """ @interface A {} class Outer { - sealed class Sup { } + static sealed class Sup { } # # class Sub extends Sup {} final class Sub2 extends Sub {} } diff --git a/test/langtools/tools/javac/switchexpr/ExpressionSwitchNotExhaustive.java b/test/langtools/tools/javac/switchexpr/ExpressionSwitchNotExhaustive.java index 802e66570ef..05a73c0ba7a 100644 --- a/test/langtools/tools/javac/switchexpr/ExpressionSwitchNotExhaustive.java +++ b/test/langtools/tools/javac/switchexpr/ExpressionSwitchNotExhaustive.java @@ -2,7 +2,7 @@ * @test /nodynamiccopyright/ * @bug 8206986 * @summary Verify behavior of not exhaustive switch expressions. - * @compile/fail/ref=ExpressionSwitchNotExhaustive.out -XDrawDiagnostics ExpressionSwitchNotExhaustive.java + * @compile/fail/ref=ExpressionSwitchNotExhaustive.out -XDrawDiagnostics -XDexhaustivityMaxBaseChecks=0 ExpressionSwitchNotExhaustive.java */ public class ExpressionSwitchNotExhaustive { diff --git a/test/langtools/tools/javac/tree/MissingSemicolonTest.java b/test/langtools/tools/javac/tree/MissingSemicolonTest.java index 2c70c4841be..cedcf1e5f98 100644 --- a/test/langtools/tools/javac/tree/MissingSemicolonTest.java +++ b/test/langtools/tools/javac/tree/MissingSemicolonTest.java @@ -115,7 +115,7 @@ public class MissingSemicolonTest { public Void scan(Tree tree, Void p) { if (tree != null) { int start = ((JCTree) tree).getStartPosition(); - int end = ((JCTree) tree).getEndPosition(unit.endPositions); + int end = ((JCTree) tree).getEndPosition(); spans.add(new int[] {start, end}); } @@ -134,7 +134,7 @@ public class MissingSemicolonTest { public Void scan(Tree tree, Void p) { if (tree != null) { int start = ((JCTree) tree).getStartPosition(); - int end = ((JCTree) tree).getEndPosition(updated.endPositions); + int end = ((JCTree) tree).getEndPosition(); if (tree.getKind() != Kind.ERRONEOUS) { int[] expected = nextSpan.next(); diff --git a/test/langtools/tools/javac/tree/TreePosTest.java b/test/langtools/tools/javac/tree/TreePosTest.java index 9e6dcf61306..ecc0d477cdb 100644 --- a/test/langtools/tools/javac/tree/TreePosTest.java +++ b/test/langtools/tools/javac/tree/TreePosTest.java @@ -69,7 +69,6 @@ import com.sun.source.tree.CompilationUnitTree; import com.sun.tools.javac.api.JavacTaskPool; import com.sun.tools.javac.api.JavacTool; import com.sun.tools.javac.code.Flags; -import com.sun.tools.javac.tree.EndPosTable; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCAnnotatedType; import com.sun.tools.javac.tree.JCTree.JCCase; @@ -347,7 +346,6 @@ public class TreePosTest { private boolean compactSourceFile; void test(JCCompilationUnit tree) { sourcefile = tree.sourcefile; - endPosTable = tree.endPositions; encl = new Info(); List nonImports = tree.defs .stream() @@ -355,7 +353,7 @@ public class TreePosTest { .toList(); compactSourceFile = nonImports.size() == 1 && nonImports.get(0) instanceof JCClassDecl classDecl && - tree.endPositions.getEndPos(classDecl) == NOPOS; + classDecl.endpos == NOPOS; tree.accept(this); } @@ -364,7 +362,7 @@ public class TreePosTest { if (tree == null) return; - Info self = new Info(tree, endPosTable); + Info self = new Info(tree); if (check(encl, self)) { // Modifiers nodes are present throughout the tree even where // there is no corresponding source text. @@ -504,7 +502,6 @@ public class TreePosTest { } JavaFileObject sourcefile; - EndPosTable endPosTable; Info encl; } @@ -521,12 +518,12 @@ public class TreePosTest { end = Integer.MAX_VALUE; } - Info(JCTree tree, EndPosTable endPosTable) { + Info(JCTree tree) { this.tree = tree; tag = tree.getTag(); start = TreeInfo.getStartPos(tree); pos = tree.pos; - end = TreeInfo.getEndPos(tree, endPosTable); + end = TreeInfo.getEndPos(tree); } @Override diff --git a/test/lib-test/ProblemList-StaticJdk.txt b/test/lib-test/ProblemList-StaticJdk.txt index 70f0438c0c6..700099656e8 100644 --- a/test/lib-test/ProblemList-StaticJdk.txt +++ b/test/lib-test/ProblemList-StaticJdk.txt @@ -1,6 +1,6 @@ ########################################################################### # -# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. # 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,3 +24,16 @@ ########################################################################### # Currently empty + +############################################################################# + +# Preview project specific failures go here at the end of the file. +# +# These are NOT failures that occur with the '--enable-preview' option +# specified; those go in the appropriate ProblemList-enable-preview.txt file. +# These are failures that occur WITHOUT the '--enable-preview' option +# specified AND occur because of some issue with preview project code, +# in either implementation or test code. + +############################################################################# + diff --git a/test/lib-test/ProblemList.txt b/test/lib-test/ProblemList.txt index 011466088d3..2a5caedc8d8 100644 --- a/test/lib-test/ProblemList.txt +++ b/test/lib-test/ProblemList.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. # 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,3 +37,16 @@ # More than one label is allowed but must be on the same line. # ############################################################################# + +############################################################################# + +# Preview project specific failures go here at the end of the file. +# +# These are NOT failures that occur with the '--enable-preview' option +# specified; those go in the appropriate ProblemList-enable-preview.txt file. +# These are failures that occur WITHOUT the '--enable-preview' option +# specified AND occur because of some issue with preview project code, +# in either implementation or test code. + +############################################################################# + diff --git a/test/lib/jdk/test/lib/SA/SATestUtils.java b/test/lib/jdk/test/lib/SA/SATestUtils.java index 01233b5bf55..63f522b3d62 100644 --- a/test/lib/jdk/test/lib/SA/SATestUtils.java +++ b/test/lib/jdk/test/lib/SA/SATestUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,8 +26,15 @@ import jdk.test.lib.JDKToolLauncher; import jdk.test.lib.Platform; import jtreg.SkippedException; +import java.lang.foreign.Arena; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.Linker; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.ValueLayout; import java.io.IOException; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; @@ -259,4 +266,109 @@ public class SATestUtils { throw new SkippedException("Cannot run this test on OSX if adding privileges is required."); } } + + /** + * Find library file that provides strlen(3), then returns it as libc. + * This method works on Linux only. + * @return path to libc + */ + @SuppressWarnings("restricted") + public static String getLibCPath() { + var linker = Linker.nativeLinker(); + var ptrStrlen = linker.defaultLookup() + .findOrThrow("strlen"); + var strlen = linker.downcallHandle( + ptrStrlen, + FunctionDescriptor.of(linker.canonicalLayouts().get("size_t"), ValueLayout.ADDRESS) + ); + var dladdr = linker.downcallHandle( + linker.defaultLookup().findOrThrow("dladdr"), + FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.ADDRESS) + ); + + var structDLInfo = MemoryLayout.structLayout( + ValueLayout.ADDRESS.withName("dli_fname"), + ValueLayout.ADDRESS.withName("dli_fbase"), + ValueLayout.ADDRESS.withName("dli_sname"), + ValueLayout.ADDRESS.withName("dli_saddr") + ).withName("Dl_info"); + var hndDliFname = structDLInfo.varHandle(MemoryLayout.PathElement.groupElement("dli_fname")); + + try(var arena = Arena.ofConfined()){ + var info = arena.allocate(structDLInfo); + int result = (int)dladdr.invoke(ptrStrlen, info); + if (result == 0) { + throw new RuntimeException("dladdr() returns zero"); + } + + var ptrDliFname = (MemorySegment)hndDliFname.get(info, 0); + var libcPathLen = (long)strlen.invoke(ptrDliFname); + return ptrDliFname.reinterpret(libcPathLen + 1) // +1 for NUL + .getString(0); + } catch (Throwable t) { + throw new RuntimeException("getLibCPath() failed due to Throwable.", t); + } + } + + /** + * Find debuginfo file for the library. + * This method will work on Linux only. + * "readelf" has to be available. + * @return null if debuginfo is not available. + */ + public static String getDebugInfo(String lib) { + try { + // Attempt to find debuginfo in /usr/lib/debug + Path debuginfoPath = Path.of("/usr/lib/debug", lib + ".debug"); + boolean exists = Files.exists(debuginfoPath); + if (!exists) { + // Attempt to find debuginfo with build ID + var proc = (new ProcessBuilder("readelf", "-n", lib)).start(); + try (var reader = proc.inputReader()) { + var buildID = reader.lines() + .filter(l -> l.contains("Build ID:")) + .findAny() + .map(l -> l.replace("Build ID:", "").trim()) + .get(); + String dir = buildID.substring(0, 2); + String file = buildID.substring(2); + debuginfoPath = Path.of("/usr/lib/debug/.build_id", dir, file + ".debug"); + exists = Files.exists(debuginfoPath); + } + } + return exists ? debuginfoPath.toString() : null; + } catch (IOException e) { + throw new RuntimeException("getDebugInfo() failed due to IOException.", e); + } + } + + private static boolean isSymbolAvailableInternal(String lib, String symbol) throws IOException { + var proc = (new ProcessBuilder("nm", lib)).start(); + try (var reader = proc.inputReader()) { + return reader.lines() + .anyMatch(l -> l.endsWith(" " + symbol)); + } + } + + /** + * This method will work on Linux only. + * Both "readelf" and "nm" have to be available. + * @return true if given symbol is available in given lib. + */ + public static boolean isSymbolAvailable(String lib, String symbol) { + try { + // Attempt to find symbol from lib + boolean result = isSymbolAvailableInternal(lib, symbol); + if (!result) { + // Attempt to find symbol from debuginfo + String debuginfoPath = getDebugInfo(lib); + if (debuginfoPath != null) { + result = isSymbolAvailableInternal(debuginfoPath, symbol); + } + } + return result; + } catch (IOException e) { + throw new RuntimeException("isSymbolAvailable() failed due to IOException.", e); + } + } } diff --git a/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java b/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java index b013561be0b..bd9a706e3a4 100644 --- a/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java +++ b/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -380,6 +380,7 @@ public class DockerTestUtils { } template = template + "COPY /jdk /jdk\n" + "ENV JAVA_HOME=/jdk\n" + + "ENV LANG=C.UTF-8\n" + "CMD [\"/bin/bash\"]\n"; String dockerFileStr = String.format(template, baseImage, baseImageVersion); Files.writeString(dockerfile, dockerFileStr); diff --git a/test/lib/jdk/test/lib/process/Proc.java b/test/lib/jdk/test/lib/process/Proc.java index 2fe802fed6c..a989906b2ab 100644 --- a/test/lib/jdk/test/lib/process/Proc.java +++ b/test/lib/jdk/test/lib/process/Proc.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -256,6 +256,15 @@ public class Proc { } } } + String patchPath = System.getProperty("test.patch.path"); + if (patchPath != null) { + try (var subs = Files.newDirectoryStream(Path.of(patchPath))) { + for (var sub : subs) { + var name = sub.getFileName(); + cmd.add("--patch-module=" + name + "=" + sub); + } + } + } var lcp = fullcp(); if (lcp != null) { diff --git a/test/lib/jdk/test/lib/security/OpensslArtifactFetcher.java b/test/lib/jdk/test/lib/security/OpensslArtifactFetcher.java index 6fa8cb2e408..f66ad542e47 100644 --- a/test/lib/jdk/test/lib/security/OpensslArtifactFetcher.java +++ b/test/lib/jdk/test/lib/security/OpensslArtifactFetcher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ import jtreg.SkippedException; public class OpensslArtifactFetcher { - private static final String OPENSSL_BUNDLE_VERSION = "3.5.1"; + private static final String OPENSSL_BUNDLE_VERSION = "3.5.4"; private static final String OPENSSL_ORG = "jpg.tests.jdk.openssl"; /** diff --git a/test/lib/jdk/test/lib/security/RepositoryFileReader.java b/test/lib/jdk/test/lib/security/RepositoryFileReader.java index 4eefc7d82db..04bc3c88d2a 100644 --- a/test/lib/jdk/test/lib/security/RepositoryFileReader.java +++ b/test/lib/jdk/test/lib/security/RepositoryFileReader.java @@ -148,4 +148,13 @@ public sealed interface RepositoryFileReader extends AutoCloseable { unpack = false) public static class CMS_ML_DSA { } + + @Artifact( + organization = "jpg.tests.jdk.repos.lamps-wg", + name = "kyber-certificates", + revision = "29f3215", + extension = "zip", + unpack = false) + public static class KYBER_CERTIFICATES { + } } diff --git a/test/lib/jdk/test/lib/util/CoreUtils.java b/test/lib/jdk/test/lib/util/CoreUtils.java index f7a486def2b..72c1d89af44 100644 --- a/test/lib/jdk/test/lib/util/CoreUtils.java +++ b/test/lib/jdk/test/lib/util/CoreUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -203,6 +203,7 @@ public class CoreUtils { private static final String CORE_PATTERN_FILE_NAME = "/proc/sys/kernel/core_pattern"; private static final String LOCATION_STRING = "location: "; + private static final String ALT_LOCATION_STRING = "alternatively, falling back to"; private static String parseCoreFileLocationFromOutput(String crashOutputString) { System.out.println("crashOutputString = [" + crashOutputString + "]"); @@ -220,12 +221,25 @@ public class CoreUtils { // Find the core file name in the output. String coreWithPid; - if (stringWithLocation.contains("or ") && !Platform.isWindows()) { - Matcher m = Pattern.compile("or.* ([^ ]+[^\\)])\\)?").matcher(stringWithLocation); + if (Platform.isLinux() && stringWithLocation.contains(ALT_LOCATION_STRING)) { + /* + * If hotspot detects that /proc/sys/kernel/core_pattern starts with a "|", + * it generates a messages something like the following: + * # Core dump will be written. Default location: Determined by the following: + * "/var/bin/core.sh %p" (alternatively, falling back to + * /ws/jdk/build/linux-x64/test-support/jtreg_open_test_hotspot_jtreg_serviceability_sa_ClhsdbFindPC_java/scratch/2/core.10353) + * We try to detect this and glean this alternative path from the message. The + * hope here is that either this is where the core file actually ends up, or that + * the script referenced by the core_pattern is just zipping the core file, in + * which case a call to unzipCores() will have already unzipped the core file + * into this path. + */ + Matcher m = Pattern.compile(ALT_LOCATION_STRING + ".* ([^ ]+[^\\)])\\)?").matcher(stringWithLocation); if (!m.find()) { throw new RuntimeException("Couldn't find path to core inside location string"); } coreWithPid = m.group(1); + System.out.println("getCoreFileLocation found alt coreWithPid = " + coreWithPid); } else { coreWithPid = stringWithLocation.trim(); } diff --git a/test/micro/org/openjdk/bench/java/lang/ThreadGetStackTraceWhenParked.java b/test/micro/org/openjdk/bench/java/lang/ThreadGetStackTraceWhenParked.java new file mode 100644 index 00000000000..cd75d3a9568 --- /dev/null +++ b/test/micro/org/openjdk/bench/java/lang/ThreadGetStackTraceWhenParked.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.java.lang; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.LockSupport; +import org.openjdk.jmh.annotations.*; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@State(Scope.Benchmark) +@Warmup(iterations = 10, time = 1) +@Measurement(iterations = 10, time = 1) +@Fork(value = 3) +public class ThreadGetStackTraceWhenParked { + private volatile boolean done; + private Thread thread; + + @Setup + public void setup() throws InterruptedException { + var started = new CountDownLatch(1); + thread = Thread.ofPlatform().start(() -> { + started.countDown(); + while (!done) { + LockSupport.park(); + } + }); + started.await(); + } + + @TearDown + public void shutdown() throws InterruptedException { + done = true; + LockSupport.unpark(thread); + thread.join(); + } + + @Benchmark + public StackTraceElement[] testGetStackTrace() { + return thread.getStackTrace(); + } +} diff --git a/test/micro/org/openjdk/bench/java/lang/ThreadGetStackTraceWhenSpinning.java b/test/micro/org/openjdk/bench/java/lang/ThreadGetStackTraceWhenSpinning.java new file mode 100644 index 00000000000..26c61d19206 --- /dev/null +++ b/test/micro/org/openjdk/bench/java/lang/ThreadGetStackTraceWhenSpinning.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.java.lang; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.*; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@State(Scope.Benchmark) +@Warmup(iterations = 10, time = 1) +@Measurement(iterations = 10, time = 1) +@Fork(value = 3) +public class ThreadGetStackTraceWhenSpinning { + private volatile boolean done; + private Thread thread; + + @Setup + public void setup() throws InterruptedException { + var started = new CountDownLatch(1); + thread = Thread.ofPlatform().start(() -> { + started.countDown(); + while (!done) { + Thread.onSpinWait(); + } + }); + started.await(); + } + + @TearDown + public void shutdown() throws InterruptedException { + done = true; + thread.join(); + } + + @Benchmark + public StackTraceElement[] testGetStackTrace() { + return thread.getStackTrace(); + } +} diff --git a/test/micro/org/openjdk/bench/java/lang/VirtualThreadGetStackTraceWhenSpinning.java b/test/micro/org/openjdk/bench/java/lang/VirtualThreadGetStackTraceWhenSpinning.java new file mode 100644 index 00000000000..59836815bfd --- /dev/null +++ b/test/micro/org/openjdk/bench/java/lang/VirtualThreadGetStackTraceWhenSpinning.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.java.lang; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.*; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@State(Scope.Benchmark) +@Warmup(iterations = 10, time = 1) +@Measurement(iterations = 10, time = 1) +@Fork(value = 3) +public class VirtualThreadGetStackTraceWhenSpinning { + private volatile boolean done; + private Thread thread; + + @Setup + public void setup() throws InterruptedException { + var started = new CountDownLatch(1); + thread = Thread.startVirtualThread(() -> { + started.countDown(); + while (!done) { + Thread.onSpinWait(); + } + }); + started.await(); + } + + @TearDown + public void shutdown() throws InterruptedException { + done = true; + thread.join(); + } + + @Benchmark + public StackTraceElement[] testGetStackTrace() { + return thread.getStackTrace(); + } +} diff --git a/test/micro/org/openjdk/bench/java/lang/VirtualThreadGetStackTraceWhenUnmounted.java b/test/micro/org/openjdk/bench/java/lang/VirtualThreadGetStackTraceWhenUnmounted.java new file mode 100644 index 00000000000..c972b511bd7 --- /dev/null +++ b/test/micro/org/openjdk/bench/java/lang/VirtualThreadGetStackTraceWhenUnmounted.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.java.lang; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.LockSupport; +import org.openjdk.jmh.annotations.*; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@State(Scope.Benchmark) +@Warmup(iterations = 10, time = 1) +@Measurement(iterations = 10, time = 1) +@Fork(value = 3) +public class VirtualThreadGetStackTraceWhenUnmounted { + private volatile boolean done; + private Thread thread; + + @Setup + public void setup() throws InterruptedException { + var started = new CountDownLatch(1); + thread = Thread.startVirtualThread(() -> { + started.countDown(); + while (!done) { + LockSupport.park(); + } + }); + started.await(); + } + + @TearDown + public void shutdown() throws InterruptedException { + done = true; + LockSupport.unpark(thread); + thread.join(); + } + + @Benchmark + public StackTraceElement[] testGetStackTrace() { + return thread.getStackTrace(); + } +} diff --git a/test/micro/org/openjdk/bench/java/lang/VirtualThreadGetStackTraceWhenYielding.java b/test/micro/org/openjdk/bench/java/lang/VirtualThreadGetStackTraceWhenYielding.java new file mode 100644 index 00000000000..0dbefc697c4 --- /dev/null +++ b/test/micro/org/openjdk/bench/java/lang/VirtualThreadGetStackTraceWhenYielding.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.java.lang; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.*; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@State(Scope.Benchmark) +@Warmup(iterations = 10, time = 1) +@Measurement(iterations = 10, time = 1) +@Fork(value = 3) +public class VirtualThreadGetStackTraceWhenYielding { + private volatile boolean done; + private Thread thread; + + @Setup + public void setup() throws InterruptedException { + var started = new CountDownLatch(1); + thread = Thread.startVirtualThread(() -> { + started.countDown(); + while (!done) { + Thread.yield(); + } + }); + started.await(); + } + + @TearDown + public void shutdown() throws InterruptedException { + done = true; + thread.join(); + } + + @Benchmark + public StackTraceElement[] testGetStackTrace() { + return thread.getStackTrace(); + } +} diff --git a/test/micro/org/openjdk/bench/java/nio/CharsetCanEncode.java b/test/micro/org/openjdk/bench/java/nio/CharsetCanEncode.java new file mode 100644 index 00000000000..ebfbc217a95 --- /dev/null +++ b/test/micro/org/openjdk/bench/java/nio/CharsetCanEncode.java @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.java.nio; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; + +import java.nio.charset.Charset; +import java.nio.charset.CharsetEncoder; +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.AverageTime) +@Warmup(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS) +@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@State(Scope.Thread) +@Fork(3) +public class CharsetCanEncode { + + private static final char ALEF_CHAR = '\u05d0'; + private static final String ALEF_STRING = "\u05d0"; + + // sun.nio.cs.US_ASCII + private CharsetEncoder ascii = Charset.forName("US-ASCII").newEncoder(); + + // sun.nio.cs.ISO_8859_1 + private CharsetEncoder iso88591 = Charset.forName("ISO-8859-1").newEncoder(); + + // sun.nio.cs.SingleByte + private CharsetEncoder iso88592 = Charset.forName("ISO-8859-2").newEncoder(); + + // sun.nio.cs.DoubleByte + private CharsetEncoder shiftjis = Charset.forName("Shift_JIS").newEncoder(); + + // sun.nio.cs.UTF_8 + private CharsetEncoder utf8 = Charset.forName("UTF-8").newEncoder(); + + // sun.nio.cs.UTF_16LE + private CharsetEncoder utf16le = Charset.forName("UTF-16LE").newEncoder(); + + @Benchmark + public boolean asciiCanEncodeCharYes() { + return ascii.canEncode('D'); + } + + @Benchmark + public boolean asciiCanEncodeStringYes() { + return ascii.canEncode("D"); + } + + @Benchmark + public boolean asciiCanEncodeCharNo() { + return ascii.canEncode(ALEF_CHAR); + } + + @Benchmark + public boolean asciiCanEncodeStringNo() { + return ascii.canEncode(ALEF_STRING); + } + + @Benchmark + public boolean iso88591CanEncodeCharYes() { + return iso88591.canEncode('D'); + } + + @Benchmark + public boolean iso88591CanEncodeStringYes() { + return iso88591.canEncode("D"); + } + + @Benchmark + public boolean iso88591CanEncodeCharNo() { + return iso88591.canEncode(ALEF_CHAR); + } + + @Benchmark + public boolean iso88591CanEncodeStringNo() { + return iso88591.canEncode(ALEF_STRING); + } + + @Benchmark + public boolean iso88592CanEncodeCharYes() { + return iso88592.canEncode('D'); + } + + @Benchmark + public boolean iso88592CanEncodeStringYes() { + return iso88592.canEncode("D"); + } + + @Benchmark + public boolean iso88592CanEncodeCharNo() { + return iso88592.canEncode(ALEF_CHAR); + } + + @Benchmark + public boolean iso88592CanEncodeStringNo() { + return iso88592.canEncode(ALEF_STRING); + } + + @Benchmark + public boolean shiftjisCanEncodeCharYes() { + return shiftjis.canEncode('D'); + } + + @Benchmark + public boolean shiftjisCanEncodeStringYes() { + return shiftjis.canEncode("D"); + } + + @Benchmark + public boolean shiftjisCanEncodeCharNo() { + return shiftjis.canEncode(ALEF_CHAR); + } + + @Benchmark + public boolean shiftjisCanEncodeStringNo() { + return shiftjis.canEncode(ALEF_STRING); + } + + @Benchmark + public boolean utf8CanEncodeCharYes() { + return utf8.canEncode('D'); + } + + @Benchmark + public boolean utf8CanEncodeStringYes() { + return utf8.canEncode("D"); + } + + @Benchmark + public boolean utf8CanEncodeCharNo() { + return utf8.canEncode(Character.MIN_SURROGATE); + } + + @Benchmark + public boolean utf8CanEncodeStringNo() { + return utf8.canEncode(String.valueOf(Character.MIN_SURROGATE)); + } + + @Benchmark + public boolean utf16leCanEncodeCharYes() { + return utf16le.canEncode('D'); + } + + @Benchmark + public boolean utf16leCanEncodeStringYes() { + return utf16le.canEncode("D"); + } + + @Benchmark + public boolean utf16leCanEncodeCharNo() { + return utf16le.canEncode(Character.MIN_SURROGATE); + } + + @Benchmark + public boolean utf16leCanEncodeStringNo() { + return utf16le.canEncode(String.valueOf(Character.MIN_SURROGATE)); + } +} diff --git a/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorUMinUMaxReductionBenchmark.java b/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorUMinUMaxReductionBenchmark.java new file mode 100644 index 00000000000..658717184a0 --- /dev/null +++ b/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorUMinUMaxReductionBenchmark.java @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.openjdk.bench.jdk.incubator.vector; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.*; + +import jdk.incubator.vector.*; +import java.util.concurrent.TimeUnit; +import java.util.Random; + +@BenchmarkMode(Mode.Throughput) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@State(Scope.Thread) +@Warmup(iterations = 5, time = 1) +@Measurement(iterations = 5, time = 1) +@Fork(value = 2, jvmArgs = { "--add-modules=jdk.incubator.vector" }) +public class VectorUMinUMaxReductionBenchmark { + @Param({"1024"}) + private int size; + + private static final VectorSpecies B_SPECIES = VectorSpecies.ofLargestShape(byte.class); + private static final VectorSpecies S_SPECIES = VectorSpecies.ofLargestShape(short.class); + private static final VectorSpecies I_SPECIES = VectorSpecies.ofLargestShape(int.class); + private static final VectorSpecies L_SPECIES = VectorSpecies.ofLargestShape(long.class); + + private Random r = new Random(); + private byte[] ba; + private short[] sa; + private int[] ia; + private long[] la; + private boolean[] ma; + + @Setup + public void init() { + ba = new byte[size]; + sa = new short[size]; + ia = new int[size]; + la = new long[size]; + ma = new boolean[size]; + + for (int i = 0; i < size; i++) { + ba[i] = (byte) r.nextInt(); + sa[i] = (short) r.nextInt(); + ia[i] = r.nextInt(); + la[i] = r.nextLong(); + ma[i] = r.nextInt() % 2 == 0; + } + } + + @CompilerControl(CompilerControl.Mode.INLINE) + private byte byteUMinUMaxReductionKernel(VectorOperators.Associative op) { + byte res = 0; + for (int i = 0; i < B_SPECIES.loopBound(size); i += B_SPECIES.length()) { + ByteVector av = ByteVector.fromArray(B_SPECIES, ba, i); + res += av.reduceLanes(op); + } + return res; + } + + @CompilerControl(CompilerControl.Mode.INLINE) + private byte byteUMinUMaxReductionMaskedKernel(VectorOperators.Associative op) { + byte res = 0; + VectorMask m = VectorMask.fromArray(B_SPECIES, ma, 0); + for (int i = 0; i < B_SPECIES.loopBound(size); i += B_SPECIES.length()) { + ByteVector av = ByteVector.fromArray(B_SPECIES, ba, i); + res += av.reduceLanes(op, m); + } + return res; + } + + @CompilerControl(CompilerControl.Mode.INLINE) + private short shortUMinUMaxReductionKernel(VectorOperators.Associative op) { + short res = 0; + for (int i = 0; i < S_SPECIES.loopBound(size); i += S_SPECIES.length()) { + ShortVector av = ShortVector.fromArray(S_SPECIES, sa, i); + res += av.reduceLanes(op); + } + return res; + } + + @CompilerControl(CompilerControl.Mode.INLINE) + private short shortUMinUMaxReductionMaskedKernel(VectorOperators.Associative op) { + short res = 0; + VectorMask m = VectorMask.fromArray(S_SPECIES, ma, 0); + for (int i = 0; i < S_SPECIES.loopBound(size); i += S_SPECIES.length()) { + ShortVector av = ShortVector.fromArray(S_SPECIES, sa, i); + res += av.reduceLanes(op, m); + } + return res; + } + + @CompilerControl(CompilerControl.Mode.INLINE) + private int intUMinUMaxReductionKernel(VectorOperators.Associative op) { + int res = 0; + for (int i = 0; i < I_SPECIES.loopBound(size); i += I_SPECIES.length()) { + IntVector av = IntVector.fromArray(I_SPECIES, ia, i); + res += av.reduceLanes(op); + } + return res; + } + + @CompilerControl(CompilerControl.Mode.INLINE) + private int intUMinUMaxReductionMaskedKernel(VectorOperators.Associative op) { + int res = 0; + VectorMask m = VectorMask.fromArray(I_SPECIES, ma, 0); + for (int i = 0; i < I_SPECIES.loopBound(size); i += I_SPECIES.length()) { + IntVector av = IntVector.fromArray(I_SPECIES, ia, i); + res += av.reduceLanes(op, m); + } + return res; + } + + @CompilerControl(CompilerControl.Mode.INLINE) + private long longUMinUMaxReductionKernel(VectorOperators.Associative op) { + long res = 0L; + for (int i = 0; i < L_SPECIES.loopBound(size); i += L_SPECIES.length()) { + LongVector av = LongVector.fromArray(L_SPECIES, la, i); + res += av.reduceLanes(op); + } + return res; + } + + @CompilerControl(CompilerControl.Mode.INLINE) + private long longUMinUMaxReductionMaskedKernel(VectorOperators.Associative op) { + long res = 0L; + VectorMask m = VectorMask.fromArray(L_SPECIES, ma, 0); + for (int i = 0; i < L_SPECIES.loopBound(size); i += L_SPECIES.length()) { + LongVector av = LongVector.fromArray(L_SPECIES, la, i); + res += av.reduceLanes(op, m); + } + return res; + } + + @Benchmark + public byte byteUMinReduction() { + return byteUMinUMaxReductionKernel(VectorOperators.UMIN); + } + + @Benchmark + public byte byteUMaxReduction() { + return byteUMinUMaxReductionKernel(VectorOperators.UMAX); + } + + @Benchmark + public byte byteUMinReductionMasked() { + return byteUMinUMaxReductionMaskedKernel(VectorOperators.UMIN); + } + + @Benchmark + public byte byteUMaxReductionMasked() { + return byteUMinUMaxReductionMaskedKernel(VectorOperators.UMAX); + } + + @Benchmark + public short shortUMinReduction() { + return shortUMinUMaxReductionKernel(VectorOperators.UMIN); + } + + @Benchmark + public short shortUMaxReduction() { + return shortUMinUMaxReductionKernel(VectorOperators.UMAX); + } + + @Benchmark + public short shortUMinReductionMasked() { + return shortUMinUMaxReductionMaskedKernel(VectorOperators.UMIN); + } + + @Benchmark + public short shortUMaxReductionMasked() { + return shortUMinUMaxReductionMaskedKernel(VectorOperators.UMAX); + } + + @Benchmark + public int intUMinReduction() { + return intUMinUMaxReductionKernel(VectorOperators.UMIN); + } + + @Benchmark + public int intUMaxReduction() { + return intUMinUMaxReductionKernel(VectorOperators.UMAX); + } + + @Benchmark + public int intUMinReductionMasked() { + return intUMinUMaxReductionMaskedKernel(VectorOperators.UMIN); + } + + @Benchmark + public int intUMaxReductionMasked() { + return intUMinUMaxReductionMaskedKernel(VectorOperators.UMAX); + } + + @Benchmark + public long longUMinReduction() { + return longUMinUMaxReductionKernel(VectorOperators.UMIN); + } + + @Benchmark + public long longUMaxReduction() { + return longUMinUMaxReductionKernel(VectorOperators.UMAX); + } + + @Benchmark + public long longUMinReductionMasked() { + return longUMinUMaxReductionMaskedKernel(VectorOperators.UMIN); + } + + @Benchmark + public long longUMaxReductionMasked() { + return longUMinUMaxReductionMaskedKernel(VectorOperators.UMAX); + } +} \ No newline at end of file diff --git a/test/micro/org/openjdk/bench/jdk/internal/jrtfs/ImageReaderBenchmark.java b/test/micro/org/openjdk/bench/jdk/internal/jrtfs/ImageReaderBenchmark.java index 1b89b510fae..b6876e66d98 100644 --- a/test/micro/org/openjdk/bench/jdk/internal/jrtfs/ImageReaderBenchmark.java +++ b/test/micro/org/openjdk/bench/jdk/internal/jrtfs/ImageReaderBenchmark.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -447,7 +447,6 @@ public class ImageReaderBenchmark { "/modules/java.base/jdk/internal/access/JavaLangRefAccess.class", "/modules/java.base/java/lang/ref/ReferenceQueue.class", "/modules/java.base/java/lang/ref/ReferenceQueue$Null.class", - "/modules/java.base/java/lang/ref/ReferenceQueue$Lock.class", "/modules/java.base/jdk/internal/access/JavaLangAccess.class", "/modules/java.base/jdk/internal/util/SystemProps.class", "/modules/java.base/jdk/internal/util/SystemProps$Raw.class", @@ -1073,6 +1072,5 @@ public class ImageReaderBenchmark { "/modules/java.base/java/nio/charset/CoderResult.class", "/modules/java.base/java/util/IdentityHashMap$IdentityHashMapIterator.class", "/modules/java.base/java/util/IdentityHashMap$KeyIterator.class", - "/modules/java.base/java/lang/Shutdown.class", - "/modules/java.base/java/lang/Shutdown$Lock.class"); + "/modules/java.base/java/lang/Shutdown.class"); } diff --git a/test/micro/org/openjdk/bench/vm/compiler/VectorAlgorithms.java b/test/micro/org/openjdk/bench/vm/compiler/VectorAlgorithms.java new file mode 100644 index 00000000000..911494cb022 --- /dev/null +++ b/test/micro/org/openjdk/bench/vm/compiler/VectorAlgorithms.java @@ -0,0 +1,274 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package org.openjdk.bench.vm.compiler; + +import java.util.Arrays; +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.*; + +/** + * The goal of this benchmark is to show the power of auto vectorization + * and the Vector API. + * + * Please only modify this benchark in synchronization with the IR test: + * test/hotspot/jtreg/compiler/vectorization/TestVectorAlgorithms.java + * + * You may want to play with the following VM flags: + * - Disable auto vectorization: + * -XX:+UnlockDiagnosticVMOptions -XX:AutoVectorizationOverrideProfitability=0 + * - Smaller vector size: + * -XX:MaxVectorSize=16 + * - Disable fill loop detection, so we don't use intrinsic but auto vectorization: + * -XX:-OptimizeFill + * - Lilliput can also have an effect, because it can change alignment and have + * an impact on which exact intrinsic is chosen (e.g. fill and copy): + * -XX:+UseCompactObjectHeaders + */ +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@State(Scope.Thread) +@Warmup(iterations = 5, time = 1) +@Measurement(iterations = 3, time = 1) +@Fork(value = 5, jvmArgs = {"--add-modules=jdk.incubator.vector", "-XX:CompileCommand=inline,*VectorAlgorithmsImpl*::*"}) +public class VectorAlgorithms { + @Param({"640000"}) + public int SIZE; + + @Param({"10000"}) + public int NUM_X_OBJECTS; + + @Param({"0"}) + public int SEED; + + VectorAlgorithmsImpl.Data d; + + @Setup + public void init() { + d = new VectorAlgorithmsImpl.Data(SIZE, SEED, NUM_X_OBJECTS); + } + + // ------------------------------------------------------------------------------------------ + // Benchmarks just forward arguments and returns. + // ------------------------------------------------------------------------------------------ + + @Benchmark + public Object fillI_loop() { + return VectorAlgorithmsImpl.fillI_loop(d.rI1); + } + + @Benchmark + public Object fillI_VectorAPI() { + return VectorAlgorithmsImpl.fillI_VectorAPI(d.rI1); + } + + @Benchmark + public Object fillI_Arrays() { + return VectorAlgorithmsImpl.fillI_Arrays(d.rI1); + } + + @Benchmark + public Object iotaI_loop() { + return VectorAlgorithmsImpl.iotaI_loop(d.rI1); + } + + @Benchmark + public Object iotaI_VectorAPI() { + return VectorAlgorithmsImpl.iotaI_VectorAPI(d.rI1); + } + + @Benchmark + public Object copyI_loop() { + return VectorAlgorithmsImpl.copyI_loop(d.aI, d.rI1); + } + + @Benchmark + public Object copyI_VectorAPI() { + return VectorAlgorithmsImpl.copyI_VectorAPI(d.aI, d.rI1); + } + + @Benchmark + public Object copyI_System_arraycopy() { + return VectorAlgorithmsImpl.copyI_System_arraycopy(d.aI, d.rI1); + } + + @Benchmark + public Object mapI_loop() { + return VectorAlgorithmsImpl.mapI_loop(d.aI, d.rI1); + } + + @Benchmark + public Object mapI_VectorAPI() { + return VectorAlgorithmsImpl.mapI_VectorAPI(d.aI, d.rI1); + } + + @Benchmark + public int reduceAddI_loop() { + return VectorAlgorithmsImpl.reduceAddI_loop(d.aI); + } + + @Benchmark + public int reduceAddI_reassociate() { + return VectorAlgorithmsImpl.reduceAddI_reassociate(d.aI); + } + + @Benchmark + public int reduceAddI_VectorAPI_naive() { + return VectorAlgorithmsImpl.reduceAddI_VectorAPI_naive(d.aI); + } + + @Benchmark + public int reduceAddI_VectorAPI_reduction_after_loop() { + return VectorAlgorithmsImpl.reduceAddI_VectorAPI_reduction_after_loop(d.aI); + } + + @Benchmark + public float dotProductF_loop() { + return VectorAlgorithmsImpl.dotProductF_loop(d.aF, d.bF); + } + + @Benchmark + public float dotProductF_VectorAPI_naive() { + return VectorAlgorithmsImpl.dotProductF_VectorAPI_naive(d.aF, d.bF); + } + + @Benchmark + public float dotProductF_VectorAPI_reduction_after_loop() { + return VectorAlgorithmsImpl.dotProductF_VectorAPI_reduction_after_loop(d.aF, d.bF); + } + + @Benchmark + public int hashCodeB_loop() { + return VectorAlgorithmsImpl.hashCodeB_loop(d.aB); + } + + @Benchmark + public int hashCodeB_Arrays() { + return VectorAlgorithmsImpl.hashCodeB_Arrays(d.aB); + } + + @Benchmark + public int hashCodeB_VectorAPI_v1() { + return VectorAlgorithmsImpl.hashCodeB_VectorAPI_v1(d.aB); + } + + @Benchmark + public int hashCodeB_VectorAPI_v2() { + return VectorAlgorithmsImpl.hashCodeB_VectorAPI_v2(d.aB); + } + + @Benchmark + public Object scanAddI_loop() { + return VectorAlgorithmsImpl.scanAddI_loop(d.aI, d.rI1); + } + + @Benchmark + public Object scanAddI_loop_reassociate() { + return VectorAlgorithmsImpl.scanAddI_loop_reassociate(d.aI, d.rI1); + } + + @Benchmark + public Object scanAddI_VectorAPI_permute_add() { + return VectorAlgorithmsImpl.scanAddI_VectorAPI_permute_add(d.aI, d.rI1); + } + + @Benchmark + public int findMinIndexI_loop() { + return VectorAlgorithmsImpl.findMinIndexI_loop(d.aI); + } + + @Benchmark + public int findMinIndexI_VectorAPI() { + return VectorAlgorithmsImpl.findMinIndexI_VectorAPI(d.aI); + } + + @Benchmark + public int findI_loop() { + // Every invocation should have a different value for e, so that + // we don't get branch-prediction that is too good. And also so + // that the position where we exit is more evenly distributed. + d.eI_idx = (d.eI_idx + 1) & 0xffff; + int e = d.eI[d.eI_idx]; + return VectorAlgorithmsImpl.findI_loop(d.aI, e); + } + + @Benchmark + public int findI_VectorAPI() { + d.eI_idx = (d.eI_idx + 1) & 0xffff; + int e = d.eI[d.eI_idx]; + return VectorAlgorithmsImpl.findI_VectorAPI(d.aI, e); + } + + @Benchmark + public Object reverseI_loop() { + return VectorAlgorithmsImpl.reverseI_loop(d.aI, d.rI1); + } + + @Benchmark + public Object reverseI_VectorAPI() { + return VectorAlgorithmsImpl.reverseI_VectorAPI(d.aI, d.rI1); + } + + @Benchmark + public Object filterI_loop() { + // Every invocation should have a different value for e, so that + // we don't get branch-prediction that is too good. And also so + // That the length of the resulting data is more evenly distributed. + d.eI_idx = (d.eI_idx + 1) & 0xffff; + int e = d.eI[d.eI_idx]; + return VectorAlgorithmsImpl.filterI_loop(d.aI, d.rI1, e); + } + + @Benchmark + public Object filterI_VectorAPI() { + d.eI_idx = (d.eI_idx + 1) & 0xffff; + int e = d.eI[d.eI_idx]; + return VectorAlgorithmsImpl.filterI_VectorAPI(d.aI, d.rI1, e); + } + + @Benchmark + public int reduceAddIFieldsX4_loop() { + return VectorAlgorithmsImpl.reduceAddIFieldsX4_loop(d.oopsX4, d.memX4); + } + + @Benchmark + public int reduceAddIFieldsX4_VectorAPI() { + return VectorAlgorithmsImpl.reduceAddIFieldsX4_VectorAPI(d.oopsX4, d.memX4); + } + + @Benchmark + public Object lowerCaseB_loop() { + return VectorAlgorithmsImpl.lowerCaseB_loop(d.strB, d.rB1); + } + + @Benchmark + public Object lowerCaseB_VectorAPI_v1() { + return VectorAlgorithmsImpl.lowerCaseB_VectorAPI_v1(d.strB, d.rB1); + } + + @Benchmark + public Object lowerCaseB_VectorAPI_v2() { + return VectorAlgorithmsImpl.lowerCaseB_VectorAPI_v2(d.strB, d.rB1); + } +} diff --git a/test/micro/org/openjdk/bench/vm/compiler/VectorAlgorithmsImpl.java b/test/micro/org/openjdk/bench/vm/compiler/VectorAlgorithmsImpl.java new file mode 100644 index 00000000000..5ab057329d3 --- /dev/null +++ b/test/micro/org/openjdk/bench/vm/compiler/VectorAlgorithmsImpl.java @@ -0,0 +1,775 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package org.openjdk.bench.vm.compiler; + +import java.util.Arrays; +import java.util.Random; +import jdk.incubator.vector.*; + +/** + * The code below is supposed to be an exact copy of: + * test/hotspot/jtreg/compiler/vectorization/VectorAlgorithmsImpl.java + */ +public class VectorAlgorithmsImpl { + private static final VectorSpecies SPECIES_I = IntVector.SPECIES_PREFERRED; + private static final VectorSpecies SPECIES_I512 = IntVector.SPECIES_512; + private static final VectorSpecies SPECIES_I256 = IntVector.SPECIES_256; + private static final VectorSpecies SPECIES_B = ByteVector.SPECIES_PREFERRED; + private static final VectorSpecies SPECIES_B64 = ByteVector.SPECIES_64; + private static final VectorSpecies SPECIES_F = FloatVector.SPECIES_PREFERRED; + + // This class stores the input and output arrays. + // The constructor sets up all the data. + // + // IMPORTANT: + // If you want to use some array but do NOT modify it: just use it. + // If you want to use it and DO want to modify it: clone it. This + // ensures that each test gets a separate copy, and that when we + // capture the modified arrays they are different for every method + // and run. + // An alternative to cloning is to use different return arrays for + // different implementations of the same group, e.g. rI1, rI2, ... + // + public static class Data { + public int[] aI; + public int[] rI1; + public int[] rI2; + public int[] rI3; + public int[] rI4; + public int[] eI; + // The test has to use the same index into eI for all implementations. But in the + // benchmark, we'd like to use random indices, so we use the index to advance through + // the array. + public int eI_idx = 0; + + public float[] aF; + public float[] bF; + + public byte[] aB; + public byte[] strB; + public byte[] rB1; + public byte[] rB2; + public byte[] rB3; + + public int[] oopsX4; + public int[] memX4; + + public Data(int size, int seed, int numX4Objects) { + Random random = new Random(seed); + + // int: one input array and multiple output arrays so different implementations can + // store their results to different arrays. + aI = new int[size]; + rI1 = new int[size]; + rI2 = new int[size]; + rI3 = new int[size]; + rI4 = new int[size]; + Arrays.setAll(aI, i -> random.nextInt()); + + // Populate with some random values from aI, and some totally random values. + eI = new int[0x10000]; + for (int i = 0; i < eI.length; i++) { + eI[i] = (random.nextInt(10) == 0) ? random.nextInt() : aI[random.nextInt(size)]; + } + + // X4 oop setup. + // oopsX4 holds "addresses" (i.e. indices), that point to the 16-byte objects in memX4. + oopsX4 = new int[size]; + memX4 = new int[numX4Objects * 4]; + for (int i = 0; i < size; i++) { + // assign either a zero=null, or assign a random oop. + oopsX4[i] = (random.nextInt(10) == 0) ? 0 : random.nextInt(numX4Objects) * 4; + } + // Just fill the whole array with random values. + // The relevant field is only at every "4 * i + 3" though. + memX4 = new int[4 * numX4Objects]; + for (int i = 0; i < memX4.length; i++) { + memX4[i] = random.nextInt(); + } + + // float inputs. To avoid rounding issues, only use small integers. + aF = new float[size]; + bF = new float[size]; + for (int i = 0; i < size; i++) { + aF[i] = random.nextInt(32) - 16; + bF[i] = random.nextInt(32) - 16; + } + + // byte: just random data. + aB = new byte[size]; + strB = new byte[size]; + rB1 = new byte[size]; + rB2 = new byte[size]; + rB3 = new byte[size]; + random.nextBytes(aB); + random.nextBytes(strB); // TODO: special data! + } + } + + public static Object fillI_loop(int[] r) { + for (int i = 0; i < r.length; i++) { + r[i] = 42; + } + return r; + } + + public static Object fillI_Arrays(int[] r) { + Arrays.fill(r, 42); + return r; + } + + public static Object fillI_VectorAPI(int[] r) { + var v = IntVector.broadcast(SPECIES_I, 42); + int i = 0; + for (; i < SPECIES_I.loopBound(r.length); i += SPECIES_I.length()) { + v.intoArray(r, i); + } + for (; i < r.length; i++) { + r[i] = 42; + } + return r; + } + + public static Object iotaI_loop(int[] r) { + for (int i = 0; i < r.length; i++) { + r[i] = i; + } + return r; + } + + public static Object iotaI_VectorAPI(int[] r) { + var iota = IntVector.broadcast(SPECIES_I, 0).addIndex(1); + int i = 0; + for (; i < SPECIES_I.loopBound(r.length); i += SPECIES_I.length()) { + iota.intoArray(r, i); + iota = iota.add(SPECIES_I.length()); + } + for (; i < r.length; i++) { + r[i] = i; + } + return r; + } + + public static Object copyI_loop(int[] a, int[] r) { + for (int i = 0; i < a.length; i++) { + r[i] = a[i]; + } + return r; + } + + public static Object copyI_System_arraycopy(int[] a, int[] r) { + System.arraycopy(a, 0, r, 0, a.length); + return r; + } + + public static Object copyI_VectorAPI(int[] a, int[] r) { + int i = 0; + for (; i < SPECIES_I.loopBound(r.length); i += SPECIES_I.length()) { + IntVector v = IntVector.fromArray(SPECIES_I, a, i); + v.intoArray(r, i); + } + for (; i < r.length; i++) { + r[i] = a[i]; + } + return r; + } + + public static Object mapI_loop(int[] a, int[] r) { + for (int i = 0; i < a.length; i++) { + r[i] = a[i] * 42; + } + return r; + } + + public static Object mapI_VectorAPI(int[] a, int[] r) { + int i = 0; + for (; i < SPECIES_I.loopBound(r.length); i += SPECIES_I.length()) { + IntVector v = IntVector.fromArray(SPECIES_I, a, i); + v = v.mul(42); + v.intoArray(r, i); + } + for (; i < r.length; i++) { + r[i] = a[i] * 42; + } + return r; + } + + public static int reduceAddI_loop(int[] a) { + int sum = 0; + for (int i = 0; i < a.length; i++) { + // Relying on simple reduction loop should vectorize since JDK26. + sum += a[i]; + } + return sum; + } + + public static int reduceAddI_reassociate(int[] a) { + int sum = 0; + int i; + for (i = 0; i < a.length - 3; i += 4) { + // Unroll 4x, reassociate inside. + sum += a[i] + a[i + 1] + a[i + 2] + a[i + 3]; + } + for (; i < a.length; i++) { + // Tail + sum += a[i]; + } + return sum; + } + + public static int reduceAddI_VectorAPI_naive(int[] a) { + var sum = 0; + int i; + for (i = 0; i < SPECIES_I.loopBound(a.length); i += SPECIES_I.length()) { + IntVector v = IntVector.fromArray(SPECIES_I, a, i); + // reduceLanes in loop is better than scalar performance, but still + // relatively slow. + sum += v.reduceLanes(VectorOperators.ADD); + } + for (; i < a.length; i++) { + sum += a[i]; + } + return sum; + } + + public static int reduceAddI_VectorAPI_reduction_after_loop(int[] a) { + var acc = IntVector.broadcast(SPECIES_I, 0); + int i; + for (i = 0; i < SPECIES_I.loopBound(a.length); i += SPECIES_I.length()) { + IntVector v = IntVector.fromArray(SPECIES_I, a, i); + // Element-wide addition into a vector of partial sums is much faster. + // Now, we only need to do a reduceLanes after the loop. + // This works because int-addition is associative and commutative. + acc = acc.add(v); + } + int sum = acc.reduceLanes(VectorOperators.ADD); + for (; i < a.length; i++) { + sum += a[i]; + } + return sum; + } + + public static float dotProductF_loop(float[] a, float[] b) { + float sum = 0; + for (int i = 0; i < a.length; i++) { + sum += a[i] * b[i]; + } + return sum; + } + + public static float dotProductF_VectorAPI_naive(float[] a, float[] b) { + float sum = 0; + int i; + for (i = 0; i < SPECIES_F.loopBound(a.length); i += SPECIES_F.length()) { + var va = FloatVector.fromArray(SPECIES_F, a, i); + var vb = FloatVector.fromArray(SPECIES_F, b, i); + sum += va.mul(vb).reduceLanes(VectorOperators.ADD); + } + for (; i < a.length; i++) { + sum += a[i] * b[i]; + } + return sum; + } + + public static float dotProductF_VectorAPI_reduction_after_loop(float[] a, float[] b) { + var sums = FloatVector.broadcast(SPECIES_F, 0.0f); + int i; + for (i = 0; i < SPECIES_F.loopBound(a.length); i += SPECIES_F.length()) { + var va = FloatVector.fromArray(SPECIES_F, a, i); + var vb = FloatVector.fromArray(SPECIES_F, b, i); + sums = sums.add(va.mul(vb)); + } + float sum = sums.reduceLanes(VectorOperators.ADD); + for (; i < a.length; i++) { + sum += a[i] * b[i]; + } + return sum; + } + + public static int hashCodeB_loop(byte[] a) { + int h = 1; + for (int i = 0; i < a.length; i++) { + h = 31 * h + a[i]; + } + return h; + } + + public static int hashCodeB_Arrays(byte[] a) { + return Arrays.hashCode(a); + } + + // Simplified intrinsic code from C2_MacroAssembler::arrays_hashcode in c2_MacroAssembler_x86.cpp + // + // Ideas that may help understand the code: + // h(i) = 31 * h(i-1) + a[i] + // "unroll" by factor of L=8: + // h(i+8) = h(i) * 31^8 + a[i+1] * 31^7 + a[i+2] * 31^6 + ... + a[i+8] * 1 + // ----------- ------------------------------------------------ + // scalar vector: notice the powers of 31 in reverse + // + // We notice that we can load a[i+1 .. i+8], then element-wise multiply with + // the vector of reversed powers-of-31, and then do reduceLanes(ADD). + // But we can do even better: By looking at multiple such 8-unrolled iterations. + // Instead of applying the "next" factor of "31^8" to the reduced scalar, we can + // already apply it element-wise. That allows us to move the reduction out + // of the loop. + // + // Note: the intrinsic additionally unrolls the loop by a factor of 4, + // but we want to keep thins simple for demonstration purposes. + // + private static int[] REVERSE_POWERS_OF_31 = new int[9]; + static { + int p = 1; + for (int i = REVERSE_POWERS_OF_31.length - 1; i >= 0; i--) { + REVERSE_POWERS_OF_31[i] = p; + p *= 31; + } + } + public static int hashCodeB_VectorAPI_v1(byte[] a) { + int result = 1; // initialValue + var vresult = IntVector.zero(SPECIES_I256); + int next = REVERSE_POWERS_OF_31[0]; // 31^L + var vcoef = IntVector.fromArray(SPECIES_I256, REVERSE_POWERS_OF_31, 1); // powers of 2 in reverse + int i; + for (i = 0; i < SPECIES_B64.loopBound(a.length); i += SPECIES_B64.length()) { + // scalar part: result *= 31^L + result *= next; + // vector part: element-wise apply the next factor and add in the new values. + var vb = ByteVector.fromArray(SPECIES_B64, a, i); + var vi = vb.castShape(SPECIES_I256, 0); + vresult = vresult.mul(next).add(vi); + } + // reduce the partial hashes in the elements, using the reverse list of powers of 2. + result += vresult.mul(vcoef).reduceLanes(VectorOperators.ADD); + for (; i < a.length; i++) { + result = 31 * result + a[i]; + } + return result; + } + + // This second approach follows the idea from this blog post by Otmar Ertl: + // https://www.dynatrace.com/news/blog/java-arrays-hashcode-byte-efficiency-techniques/ + // + // I simplified the algorithm a little, so that it is a bit closer + // to the solution "v1" above. + // + // The major issue with "v1" is that we cannot load a full vector of bytes, + // because of the cast to ints. So we can only fill 1/4 of the maximal + // vector size. The trick here is to do an unrolling of factor 4, from: + // h(i) = 31 * h(i-1) + a[i] + // to: + // h(i+4) = h(i) * 31^4 + a[i + 1] * 31^3 + // + a[i + 2] * 31^2 + // + a[i + 3] * 31^1 + // + a[i + 4] * 31^0 + // The goal is now to compute this value for 4 bytes within a 4 byte + // lane of the vector. One concern is that we start with byte values, + // but need to do int-multiplication with powers of 31. If we instead + // did a byte-multiplication, we could get overflows that we would not + // have had in the int-multiplication. + // One trick that helps with chaning the size of the lanes from byte + // to short to int is doing all operations with unsigned integers. That + // way, we can zero-extend instead of sign-bit extend. The first step + // is thus to convert the bytes into unsigned values. Since byte is in + // range [-128..128), doing "a[i+j] + 128" makes it a positive value, + // allowing for unsigned multiplication. + // h(i+4) = h(i) * 31^4 + a[i + 1] * 31^3 + // + a[i + 2] * 31^2 + // + a[i + 3] * 31^1 + // + a[i + 4] * 31^0 + // = h(i) * 31^4 + (a[i + 1] + 128 - 128) * 31^3 + // + (a[i + 2] + 128 - 128) * 31^2 + // + (a[i + 3] + 128 - 128) * 31^1 + // + (a[i + 4] + 128 - 128) * 31^0 + // = h(i) * 31^4 + (a[i + 1] + 128 ) * 31^3 + // + (a[i + 2] + 128 ) * 31^2 + // + (a[i + 3] + 128 ) * 31^1 + // + (a[i + 4] + 128 ) * 31^0 + // + -128 * (31^3 + 31^2 + 31^1 + 1) + // = h(i) * 31^4 + ((a[i + 1] + 128) * 31 + // + (a[i + 2] + 128 ) * 31^2 + // + ((a[i + 3] + 128) * 31 + // + (a[i + 4] + 128 ) + // + -128 * (31^3 + 31^2 + 31^1 + 1) + // + // Getting from the signed a[i] value to unsigned with +128, we can + // just xor with 0x80=128. Any numbers there in range [-128..0) are + // now in range [0..128). And any numbers that were in range [0..128) + // are now in unsigned range [128..255). What a neat trick! + // + // We then apply a byte->short transition where we crunch 2 bytes + // into one short, applying a multiplication with 31 to one of the + // two bytes. This multiplication cannot overflow in a short. + // then we apply a short->int transition where we crunch 2 shorts + // into one int, applying a multiplication with 31^2 to one of the + // two shorts. This multiplication cannot overflow in an int. + // + public static int hashCodeB_VectorAPI_v2(byte[] a) { + return HashCodeB_VectorAPI_V2.compute(a); + } + + private static class HashCodeB_VectorAPI_V2 { + private static final int L = Math.min(ByteVector.SPECIES_PREFERRED.length(), + IntVector.SPECIES_PREFERRED.length() * 4); + private static final VectorShape SHAPE = VectorShape.forBitSize(8 * L); + private static final VectorSpecies SPECIES_B = SHAPE.withLanes(byte.class); + private static final VectorSpecies SPECIES_I = SHAPE.withLanes(int.class); + + private static int[] REVERSE_POWERS_OF_31_STEP_4 = new int[L / 4 + 1]; + static { + int p = 1; + int step = 31 * 31 * 31 * 31; // step by 4 + for (int i = REVERSE_POWERS_OF_31_STEP_4.length - 1; i >= 0; i--) { + REVERSE_POWERS_OF_31_STEP_4[i] = p; + p *= step; + } + } + + public static int compute(byte[] a) { + int result = 1; // initialValue + int next = REVERSE_POWERS_OF_31_STEP_4[0]; // 31^L + var vcoef = IntVector.fromArray(SPECIES_I, REVERSE_POWERS_OF_31_STEP_4, 1); // W + var vresult = IntVector.zero(SPECIES_I); + int i; + for (i = 0; i < SPECIES_B.loopBound(a.length); i += SPECIES_B.length()) { + var vb = ByteVector.fromArray(SPECIES_B, a, i); + // Add 128 to each byte. + var vs = vb.lanewise(VectorOperators.XOR, (byte)0x80) + .reinterpretAsShorts(); + // Each short lane contains 2 bytes, crunch them. + var vi = vs.and((short)0xff) // lower byte + .mul((short)31) + .add(vs.lanewise(VectorOperators.LSHR, 8)) // upper byte + .reinterpretAsInts(); + // Each int contains 2 shorts, crunch them. + var v = vi.and(0xffff) // lower short + .mul(31 * 31) + .add(vi.lanewise(VectorOperators.LSHR, 16)); // upper short + // Add the correction for the 128 additions above. + v = v.add(-128 * (31*31*31 + 31*31 + 31 + 1)); + // Every element of v now contains a crunched int-package of 4 bytes. + result *= next; + vresult = vresult.mul(next).add(v); + } + result += vresult.mul(vcoef).reduceLanes(VectorOperators.ADD); + for (; i < a.length; i++) { + result = 31 * result + a[i]; + } + return result; + } + } + + public static Object scanAddI_loop(int[] a, int[] r) { + int sum = 0; + for (int i = 0; i < a.length; i++) { + sum += a[i]; + r[i] = sum; + } + return r; + } + + public static Object scanAddI_loop_reassociate(int[] a, int[] r) { + int sum = 0; + int i = 0; + for (; i < a.length - 3; i += 4) { + // We cut the latency by a factor of 4, but increase the number of additions. + int old_sum = sum; + int v0 = a[i + 0]; + int v1 = a[i + 1]; + int v2 = a[i + 2]; + int v3 = a[i + 3]; + int v01 = v0 + v1; + int v23 = v2 + v3; + int v0123 = v01 + v23; + sum += v0123; + r[i + 0] = old_sum + v0; + r[i + 1] = old_sum + v01; + r[i + 2] = old_sum + v01 + v2; + r[i + 3] = old_sum + v0123; + } + for (; i < a.length; i++) { + sum += a[i]; + r[i] = sum; + } + return r; + } + + public static Object scanAddI_VectorAPI_permute_add(int[] a, int[] r) { + // Using Naive Parallel Algorithm: Hills and Steele + int sum = 0; + int xx = 0; // masked later anyway + var shf1 = VectorShuffle.fromArray(SPECIES_I512, new int[]{xx, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 0); + var shf2 = VectorShuffle.fromArray(SPECIES_I512, new int[]{xx, xx, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 0); + var shf3 = VectorShuffle.fromArray(SPECIES_I512, new int[]{xx, xx, xx, xx, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 0); + var shf4 = VectorShuffle.fromArray(SPECIES_I512, new int[]{xx, xx, xx, xx, xx, xx, xx, xx, 0, 1, 2, 3, 4, 5, 6, 7}, 0); + var mask1 = VectorMask.fromLong(SPECIES_I512, 0b1111111111111110); + var mask2 = VectorMask.fromLong(SPECIES_I512, 0b1111111111111100); + var mask3 = VectorMask.fromLong(SPECIES_I512, 0b1111111111110000); + var mask4 = VectorMask.fromLong(SPECIES_I512, 0b1111111100000000); + int i = 0; + for (; i < SPECIES_I512.loopBound(a.length); i += SPECIES_I512.length()) { + IntVector v = IntVector.fromArray(SPECIES_I512, a, i); + v = v.add(v.rearrange(shf1), mask1); + v = v.add(v.rearrange(shf2), mask2); + v = v.add(v.rearrange(shf3), mask3); + v = v.add(v.rearrange(shf4), mask4); + v = v.add(sum); + v.intoArray(r, i); + sum = v.lane(SPECIES_I512.length() - 1); + } + for (; i < a.length; i++) { + sum += a[i]; + r[i] = sum; + } + return r; + } + + public static int findMinIndexI_loop(int[] a) { + int min = a[0]; + int index = 0; + for (int i = 1; i < a.length; i++) { + int ai = a[i]; + if (ai < min) { + min = ai; + index = i; + } + } + return index; + } + + public static int findMinIndexI_VectorAPI(int[] a) { + // Main approach: have partial results in mins and idxs. + var mins = IntVector.broadcast(SPECIES_I, a[0]); + var idxs = IntVector.broadcast(SPECIES_I, 0); + var iota = IntVector.broadcast(SPECIES_I, 0).addIndex(1); + int i = 0; + for (; i < SPECIES_I.loopBound(a.length); i += SPECIES_I.length()) { + IntVector v = IntVector.fromArray(SPECIES_I, a, i); + var mask = v.compare(VectorOperators.LT, mins); + mins = mins.blend(v, mask); + idxs = idxs.blend(iota, mask); + iota = iota.add(SPECIES_I.length()); + } + // Reduce the vectors down + int min = mins.reduceLanes(VectorOperators.MIN); + var not_min_mask = mins.compare(VectorOperators.NE, min); + int index = idxs.blend(a.length, not_min_mask).reduceLanes(VectorOperators.MIN); + // Tail loop + for (; i < a.length; i++) { + int ai = a[i]; + if (ai < min) { + min = ai; + index = i; + } + } + return index; + } + + public static int findI_loop(int[] a, int e) { + for (int i = 0; i < a.length; i++) { + int ai = a[i]; + if (ai == e) { + return i; + } + } + return -1; + } + + public static int findI_VectorAPI(int[] a, int e) { + var es = IntVector.broadcast(SPECIES_I, e); + int i = 0; + for (; i < SPECIES_I.loopBound(a.length); i += SPECIES_I.length()) { + IntVector v = IntVector.fromArray(SPECIES_I, a, i); + var mask = v.compare(VectorOperators.EQ, es); + if (mask.anyTrue()) { + return i + mask.firstTrue(); + } + } + for (; i < a.length; i++) { + int ai = a[i]; + if (ai == e) { + return i; + } + } + return -1; + } + + public static Object reverseI_loop(int[] a, int[] r) { + for (int i = 0; i < a.length; i++) { + r[a.length - i - 1] = a[i]; + } + return r; + } + + private static final VectorShuffle REVERSE_SHUFFLE_I = SPECIES_I.iotaShuffle(SPECIES_I.length()-1, -1, true); + + public static Object reverseI_VectorAPI(int[] a, int[] r) { + int i = 0; + for (; i < SPECIES_I.loopBound(a.length); i += SPECIES_I.length()) { + IntVector v = IntVector.fromArray(SPECIES_I, a, i); + v = v.rearrange(REVERSE_SHUFFLE_I); + v.intoArray(r, r.length - SPECIES_I.length() - i); + } + for (; i < a.length; i++) { + r[a.length - i - 1] = a[i]; + } + return r; + } + + public static Object filterI_loop(int[] a, int[] r, int threshold) { + int j = 0; + for (int i = 0; i < a.length; i++) { + int ai = a[i]; + if (ai >= threshold) { + r[j++] = ai; + } + } + // Just force the resulting length onto the same array. + r[r.length - 1] = j; + return r; + } + + public static Object filterI_VectorAPI(int[] a, int[] r, int threshold) { + var thresholds = IntVector.broadcast(SPECIES_I, threshold); + int j = 0; + int i = 0; + for (; i < SPECIES_I.loopBound(a.length); i += SPECIES_I.length()) { + IntVector v = IntVector.fromArray(SPECIES_I, a, i); + var mask = v.compare(VectorOperators.GE, thresholds); + v = v.compress(mask); + int trueCount = mask.trueCount(); + var prefixMask = mask.compress(); + v.intoArray(r, j, prefixMask); + j += trueCount; + } + + for (; i < a.length; i++) { + int ai = a[i]; + if (ai >= threshold) { + r[j++] = ai; + } + } + // Just force the resulting length onto the same array. + r[r.length - 1] = j; + return r; + } + + // X4: ints simulate 4-byte oops. + // oops: if non-zero (= non-null), every entry simulates a 4-byte oop, pointing into mem. + // mem: an int array that simulates the memory. + // + // Task: Find all non-null oops, and dereference them, get the relevant field. + // Objects have 16 bytes, and the relevant field is at bytes 12-16. + // That maps to 4 ints, and the relevant field is the 4th element of 4. + // Sum up all the field values. + public static int reduceAddIFieldsX4_loop(int[] oops, int[] mem) { + int sum = 0; + for (int i = 0; i < oops.length; i++) { + int oop = oops[i]; + if (oop != 0) { + int fieldValue = mem[oop + 3]; // oop+12 + sum += fieldValue; + } + } + return sum; + } + + public static int reduceAddIFieldsX4_VectorAPI(int[] oops, int[] mem) { + var acc = IntVector.broadcast(SPECIES_I, 0); + int i = 0; + for (; i < SPECIES_I.loopBound(oops.length); i += SPECIES_I.length()) { + var oopv = IntVector.fromArray(SPECIES_I, oops, i); + var mask = oopv.compare(VectorOperators.NE, /* null */0); + // We are lucky today: we need to access mem[oop + 3] + var fieldValues = IntVector.fromArray(SPECIES_I, mem, 3, oops, i, mask); + acc = acc.add(fieldValues); + } + int sum = acc.reduceLanes(VectorOperators.ADD); + for (; i < oops.length; i++) { + int oop = oops[i]; + if (oop != 0) { + int fieldValue = mem[oop + 3]; // oop+12 + sum += fieldValue; + } + } + return sum; + } + + // The lowerCase example demonstrates a lane-wise control-flow diamond. + public static Object lowerCaseB_loop(byte[] a, byte[] r) { + for (int i = 0; i < a.length; i++) { + byte c = a[i]; + if (c >= 'A' && c <= 'Z') { + c += ('a' - 'A'); // c += 32 + } + r[i] = c; + } + return r; + } + + // Control-flow diamonds can easily be simulated by "if-conversion", i.e. + // by using masked operations. An alternative would be to use blend. + public static Object lowerCaseB_VectorAPI_v1(byte[] a, byte[] r) { + int i; + for (i = 0; i < SPECIES_B.loopBound(a.length); i += SPECIES_B.length()) { + var vc = ByteVector.fromArray(SPECIES_B, a, i); + var maskA = vc.compare(VectorOperators.GE, (byte)'A'); + var maskZ = vc.compare(VectorOperators.LE, (byte)'Z'); + var mask = maskA.and(maskZ); + vc = vc.add((byte)32, mask); + vc.intoArray(r, i); + } + for (; i < a.length; i++) { + byte c = a[i]; + if (c >= 'A' && c <= 'Z') { + c += ('a' - 'A'); + } + r[i] = c; + } + return r; + } + + public static Object lowerCaseB_VectorAPI_v2(byte[] a, byte[] r) { + int i; + for (i = 0; i < SPECIES_B.loopBound(a.length); i += SPECIES_B.length()) { + var vc = ByteVector.fromArray(SPECIES_B, a, i); + // We can convert the range 65..90 (represents ascii A..Z) into a range 0..25. + // This allows us to only use a single unsigned comparison. + var vt = vc.add((byte)-'A'); + var mask = vt.compare(VectorOperators.ULE, (byte)25); + vc = vc.add((byte)32, mask); + vc.intoArray(r, i); + } + for (; i < a.length; i++) { + byte c = a[i]; + if (c >= 'A' && c <= 'Z') { + c += ('a' - 'A'); + } + r[i] = c; + } + return r; + } +} +